diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/Kconfig | 4 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 16 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 23 | ||||
| -rw-r--r-- | net/ipv6/datagram.c | 2 | ||||
| -rw-r--r-- | net/ipv6/esp6.c | 4 | ||||
| -rw-r--r-- | net/ipv6/fib6_rules.c | 3 | ||||
| -rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
| -rw-r--r-- | net/ipv6/inet6_hashtables.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ip6_fib.c | 92 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 10 | ||||
| -rw-r--r-- | net/ipv6/ipcomp6.c | 302 | ||||
| -rw-r--r-- | net/ipv6/ipv6_sockglue.c | 6 | ||||
| -rw-r--r-- | net/ipv6/mip6.c | 8 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/Kconfig | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_security.c | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 4 | ||||
| -rw-r--r-- | net/ipv6/proc.c | 1 | ||||
| -rw-r--r-- | net/ipv6/reassembly.c | 4 | ||||
| -rw-r--r-- | net/ipv6/route.c | 25 | ||||
| -rw-r--r-- | net/ipv6/syncookies.c | 23 | ||||
| -rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 16 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 43 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 6 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 29 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_policy.c | 4 |
26 files changed, 194 insertions, 443 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 42814a2ec9d7..ec992159b5f8 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
| @@ -96,10 +96,8 @@ config INET6_ESP | |||
| 96 | 96 | ||
| 97 | config INET6_IPCOMP | 97 | config INET6_IPCOMP |
| 98 | tristate "IPv6: IPComp transformation" | 98 | tristate "IPv6: IPComp transformation" |
| 99 | select XFRM | ||
| 100 | select INET6_XFRM_TUNNEL | 99 | select INET6_XFRM_TUNNEL |
| 101 | select CRYPTO | 100 | select XFRM_IPCOMP |
| 102 | select CRYPTO_DEFLATE | ||
| 103 | ---help--- | 101 | ---help--- |
| 104 | Support for IP Payload Compression Protocol (IPComp) (RFC3173), | 102 | Support for IP Payload Compression Protocol (IPComp) (RFC3173), |
| 105 | typically needed for IPsec. | 103 | typically needed for IPsec. |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9f4fcce6379b..e2d3b7580b76 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -153,7 +153,7 @@ static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
| 153 | 153 | ||
| 154 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | 154 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); |
| 155 | 155 | ||
| 156 | struct ipv6_devconf ipv6_devconf __read_mostly = { | 156 | static struct ipv6_devconf ipv6_devconf __read_mostly = { |
| 157 | .forwarding = 0, | 157 | .forwarding = 0, |
| 158 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, | 158 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, |
| 159 | .mtu6 = IPV6_MIN_MTU, | 159 | .mtu6 = IPV6_MIN_MTU, |
| @@ -313,8 +313,10 @@ static void in6_dev_finish_destroy_rcu(struct rcu_head *head) | |||
| 313 | void in6_dev_finish_destroy(struct inet6_dev *idev) | 313 | void in6_dev_finish_destroy(struct inet6_dev *idev) |
| 314 | { | 314 | { |
| 315 | struct net_device *dev = idev->dev; | 315 | struct net_device *dev = idev->dev; |
| 316 | BUG_TRAP(idev->addr_list==NULL); | 316 | |
| 317 | BUG_TRAP(idev->mc_list==NULL); | 317 | WARN_ON(idev->addr_list != NULL); |
| 318 | WARN_ON(idev->mc_list != NULL); | ||
| 319 | |||
| 318 | #ifdef NET_REFCNT_DEBUG | 320 | #ifdef NET_REFCNT_DEBUG |
| 319 | printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); | 321 | printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); |
| 320 | #endif | 322 | #endif |
| @@ -517,8 +519,9 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) | |||
| 517 | 519 | ||
| 518 | void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | 520 | void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) |
| 519 | { | 521 | { |
| 520 | BUG_TRAP(ifp->if_next==NULL); | 522 | WARN_ON(ifp->if_next != NULL); |
| 521 | BUG_TRAP(ifp->lst_next==NULL); | 523 | WARN_ON(ifp->lst_next != NULL); |
| 524 | |||
| 522 | #ifdef NET_REFCNT_DEBUG | 525 | #ifdef NET_REFCNT_DEBUG |
| 523 | printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); | 526 | printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); |
| 524 | #endif | 527 | #endif |
| @@ -1103,13 +1106,12 @@ out: | |||
| 1103 | return ret; | 1106 | return ret; |
| 1104 | } | 1107 | } |
| 1105 | 1108 | ||
| 1106 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | 1109 | int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, |
| 1107 | const struct in6_addr *daddr, unsigned int prefs, | 1110 | const struct in6_addr *daddr, unsigned int prefs, |
| 1108 | struct in6_addr *saddr) | 1111 | struct in6_addr *saddr) |
| 1109 | { | 1112 | { |
| 1110 | struct ipv6_saddr_score scores[2], | 1113 | struct ipv6_saddr_score scores[2], |
| 1111 | *score = &scores[0], *hiscore = &scores[1]; | 1114 | *score = &scores[0], *hiscore = &scores[1]; |
| 1112 | struct net *net = dev_net(dst_dev); | ||
| 1113 | struct ipv6_saddr_dst dst; | 1115 | struct ipv6_saddr_dst dst; |
| 1114 | struct net_device *dev; | 1116 | struct net_device *dev; |
| 1115 | int dst_type; | 1117 | int dst_type; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3d828bc4b1cf..95055f8c3f35 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -83,7 +83,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol) | |||
| 83 | struct inet_sock *inet; | 83 | struct inet_sock *inet; |
| 84 | struct ipv6_pinfo *np; | 84 | struct ipv6_pinfo *np; |
| 85 | struct sock *sk; | 85 | struct sock *sk; |
| 86 | struct list_head *p; | ||
| 87 | struct inet_protosw *answer; | 86 | struct inet_protosw *answer; |
| 88 | struct proto *answer_prot; | 87 | struct proto *answer_prot; |
| 89 | unsigned char answer_flags; | 88 | unsigned char answer_flags; |
| @@ -97,13 +96,12 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol) | |||
| 97 | build_ehash_secret(); | 96 | build_ehash_secret(); |
| 98 | 97 | ||
| 99 | /* Look for the requested type/protocol pair. */ | 98 | /* Look for the requested type/protocol pair. */ |
| 100 | answer = NULL; | ||
| 101 | lookup_protocol: | 99 | lookup_protocol: |
| 102 | err = -ESOCKTNOSUPPORT; | 100 | err = -ESOCKTNOSUPPORT; |
| 103 | rcu_read_lock(); | 101 | rcu_read_lock(); |
| 104 | list_for_each_rcu(p, &inetsw6[sock->type]) { | 102 | list_for_each_entry_rcu(answer, &inetsw6[sock->type], list) { |
| 105 | answer = list_entry(p, struct inet_protosw, list); | ||
| 106 | 103 | ||
| 104 | err = 0; | ||
| 107 | /* Check the non-wild match. */ | 105 | /* Check the non-wild match. */ |
| 108 | if (protocol == answer->protocol) { | 106 | if (protocol == answer->protocol) { |
| 109 | if (protocol != IPPROTO_IP) | 107 | if (protocol != IPPROTO_IP) |
| @@ -118,10 +116,9 @@ lookup_protocol: | |||
| 118 | break; | 116 | break; |
| 119 | } | 117 | } |
| 120 | err = -EPROTONOSUPPORT; | 118 | err = -EPROTONOSUPPORT; |
| 121 | answer = NULL; | ||
| 122 | } | 119 | } |
| 123 | 120 | ||
| 124 | if (!answer) { | 121 | if (err) { |
| 125 | if (try_loading_module < 2) { | 122 | if (try_loading_module < 2) { |
| 126 | rcu_read_unlock(); | 123 | rcu_read_unlock(); |
| 127 | /* | 124 | /* |
| @@ -153,7 +150,7 @@ lookup_protocol: | |||
| 153 | answer_flags = answer->flags; | 150 | answer_flags = answer->flags; |
| 154 | rcu_read_unlock(); | 151 | rcu_read_unlock(); |
| 155 | 152 | ||
| 156 | BUG_TRAP(answer_prot->slab != NULL); | 153 | WARN_ON(answer_prot->slab == NULL); |
| 157 | 154 | ||
| 158 | err = -ENOBUFS; | 155 | err = -ENOBUFS; |
| 159 | sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot); | 156 | sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot); |
| @@ -937,6 +934,11 @@ static int __init inet6_init(void) | |||
| 937 | if (err) | 934 | if (err) |
| 938 | goto out_unregister_sock; | 935 | goto out_unregister_sock; |
| 939 | 936 | ||
| 937 | #ifdef CONFIG_SYSCTL | ||
| 938 | err = ipv6_static_sysctl_register(); | ||
| 939 | if (err) | ||
| 940 | goto static_sysctl_fail; | ||
| 941 | #endif | ||
| 940 | /* | 942 | /* |
| 941 | * ipngwg API draft makes clear that the correct semantics | 943 | * ipngwg API draft makes clear that the correct semantics |
| 942 | * for TCP and UDP is to consider one TCP and UDP instance | 944 | * for TCP and UDP is to consider one TCP and UDP instance |
| @@ -1061,6 +1063,10 @@ ipmr_fail: | |||
| 1061 | icmp_fail: | 1063 | icmp_fail: |
| 1062 | unregister_pernet_subsys(&inet6_net_ops); | 1064 | unregister_pernet_subsys(&inet6_net_ops); |
| 1063 | register_pernet_fail: | 1065 | register_pernet_fail: |
| 1066 | #ifdef CONFIG_SYSCTL | ||
| 1067 | ipv6_static_sysctl_unregister(); | ||
| 1068 | static_sysctl_fail: | ||
| 1069 | #endif | ||
| 1064 | cleanup_ipv6_mibs(); | 1070 | cleanup_ipv6_mibs(); |
| 1065 | out_unregister_sock: | 1071 | out_unregister_sock: |
| 1066 | sock_unregister(PF_INET6); | 1072 | sock_unregister(PF_INET6); |
| @@ -1116,6 +1122,9 @@ static void __exit inet6_exit(void) | |||
| 1116 | rawv6_exit(); | 1122 | rawv6_exit(); |
| 1117 | 1123 | ||
| 1118 | unregister_pernet_subsys(&inet6_net_ops); | 1124 | unregister_pernet_subsys(&inet6_net_ops); |
| 1125 | #ifdef CONFIG_SYSCTL | ||
| 1126 | ipv6_static_sysctl_unregister(); | ||
| 1127 | #endif | ||
| 1119 | cleanup_ipv6_mibs(); | 1128 | cleanup_ipv6_mibs(); |
| 1120 | proto_unregister(&rawv6_prot); | 1129 | proto_unregister(&rawv6_prot); |
| 1121 | proto_unregister(&udplitev6_prot); | 1130 | proto_unregister(&udplitev6_prot); |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f7b535dec860..410046a8cc91 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -732,7 +732,7 @@ int datagram_send_ctl(struct net *net, | |||
| 732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", | 732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", |
| 733 | cmsg->cmsg_type); | 733 | cmsg->cmsg_type); |
| 734 | err = -EINVAL; | 734 | err = -EINVAL; |
| 735 | break; | 735 | goto exit_f; |
| 736 | } | 736 | } |
| 737 | } | 737 | } |
| 738 | 738 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index c6bb4c6d24b3..b181b08fb761 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
| @@ -521,6 +521,10 @@ static int esp6_init_state(struct xfrm_state *x) | |||
| 521 | crypto_aead_ivsize(aead); | 521 | crypto_aead_ivsize(aead); |
| 522 | switch (x->props.mode) { | 522 | switch (x->props.mode) { |
| 523 | case XFRM_MODE_BEET: | 523 | case XFRM_MODE_BEET: |
| 524 | if (x->sel.family != AF_INET6) | ||
| 525 | x->props.header_len += IPV4_BEET_PHMAXLEN + | ||
| 526 | (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); | ||
| 527 | break; | ||
| 524 | case XFRM_MODE_TRANSPORT: | 528 | case XFRM_MODE_TRANSPORT: |
| 525 | break; | 529 | break; |
| 526 | case XFRM_MODE_TUNNEL: | 530 | case XFRM_MODE_TUNNEL: |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 8d05527524e3..f5de3f9dc692 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
| 93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) | 93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) |
| 94 | srcprefs |= IPV6_PREFER_SRC_COA; | 94 | srcprefs |= IPV6_PREFER_SRC_COA; |
| 95 | 95 | ||
| 96 | if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, | 96 | if (ipv6_dev_get_saddr(net, |
| 97 | ip6_dst_idev(&rt->u.dst)->dev, | ||
| 97 | &flp->fl6_dst, srcprefs, | 98 | &flp->fl6_dst, srcprefs, |
| 98 | &saddr)) | 99 | &saddr)) |
| 99 | goto again; | 100 | goto again; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 87801cc1b2f8..16d43f20b32f 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
| @@ -98,7 +98,7 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk, | |||
| 98 | ipv6_addr_equal(&treq->rmt_addr, raddr) && | 98 | ipv6_addr_equal(&treq->rmt_addr, raddr) && |
| 99 | ipv6_addr_equal(&treq->loc_addr, laddr) && | 99 | ipv6_addr_equal(&treq->loc_addr, laddr) && |
| 100 | (!treq->iif || treq->iif == iif)) { | 100 | (!treq->iif || treq->iif == iif)) { |
| 101 | BUG_TRAP(req->sk == NULL); | 101 | WARN_ON(req->sk != NULL); |
| 102 | *prevp = prev; | 102 | *prevp = prev; |
| 103 | return req; | 103 | return req; |
| 104 | } | 104 | } |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 00a8a5f9380c..1646a5658255 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
| @@ -28,7 +28,7 @@ void __inet6_hash(struct sock *sk) | |||
| 28 | struct hlist_head *list; | 28 | struct hlist_head *list; |
| 29 | rwlock_t *lock; | 29 | rwlock_t *lock; |
| 30 | 30 | ||
| 31 | BUG_TRAP(sk_unhashed(sk)); | 31 | WARN_ON(!sk_unhashed(sk)); |
| 32 | 32 | ||
| 33 | if (sk->sk_state == TCP_LISTEN) { | 33 | if (sk->sk_state == TCP_LISTEN) { |
| 34 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | 34 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; |
| @@ -202,7 +202,7 @@ unique: | |||
| 202 | * in hash table socket with a funny identity. */ | 202 | * in hash table socket with a funny identity. */ |
| 203 | inet->num = lport; | 203 | inet->num = lport; |
| 204 | inet->sport = htons(lport); | 204 | inet->sport = htons(lport); |
| 205 | BUG_TRAP(sk_unhashed(sk)); | 205 | WARN_ON(!sk_unhashed(sk)); |
| 206 | __sk_add_node(sk, &head->chain); | 206 | __sk_add_node(sk, &head->chain); |
| 207 | sk->sk_hash = hash; | 207 | sk->sk_hash = hash; |
| 208 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 208 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 4de2b9efcacb..29c7c99e69f7 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -287,7 +287,7 @@ static int fib6_dump_node(struct fib6_walker_t *w) | |||
| 287 | w->leaf = rt; | 287 | w->leaf = rt; |
| 288 | return 1; | 288 | return 1; |
| 289 | } | 289 | } |
| 290 | BUG_TRAP(res!=0); | 290 | WARN_ON(res == 0); |
| 291 | } | 291 | } |
| 292 | w->leaf = NULL; | 292 | w->leaf = NULL; |
| 293 | return 0; | 293 | return 0; |
| @@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 378 | 378 | ||
| 379 | arg.skb = skb; | 379 | arg.skb = skb; |
| 380 | arg.cb = cb; | 380 | arg.cb = cb; |
| 381 | arg.net = net; | ||
| 381 | w->args = &arg; | 382 | w->args = &arg; |
| 382 | 383 | ||
| 383 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { | 384 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { |
| @@ -661,17 +662,17 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
| 661 | 662 | ||
| 662 | static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt) | 663 | static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt) |
| 663 | { | 664 | { |
| 664 | if (net->ipv6.ip6_fib_timer->expires == 0 && | 665 | if (!timer_pending(&net->ipv6.ip6_fib_timer) && |
| 665 | (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) | 666 | (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) |
| 666 | mod_timer(net->ipv6.ip6_fib_timer, jiffies + | 667 | mod_timer(&net->ipv6.ip6_fib_timer, |
| 667 | net->ipv6.sysctl.ip6_rt_gc_interval); | 668 | jiffies + net->ipv6.sysctl.ip6_rt_gc_interval); |
| 668 | } | 669 | } |
| 669 | 670 | ||
| 670 | void fib6_force_start_gc(struct net *net) | 671 | void fib6_force_start_gc(struct net *net) |
| 671 | { | 672 | { |
| 672 | if (net->ipv6.ip6_fib_timer->expires == 0) | 673 | if (!timer_pending(&net->ipv6.ip6_fib_timer)) |
| 673 | mod_timer(net->ipv6.ip6_fib_timer, jiffies + | 674 | mod_timer(&net->ipv6.ip6_fib_timer, |
| 674 | net->ipv6.sysctl.ip6_rt_gc_interval); | 675 | jiffies + net->ipv6.sysctl.ip6_rt_gc_interval); |
| 675 | } | 676 | } |
| 676 | 677 | ||
| 677 | /* | 678 | /* |
| @@ -778,7 +779,7 @@ out: | |||
| 778 | pn->leaf = fib6_find_prefix(info->nl_net, pn); | 779 | pn->leaf = fib6_find_prefix(info->nl_net, pn); |
| 779 | #if RT6_DEBUG >= 2 | 780 | #if RT6_DEBUG >= 2 |
| 780 | if (!pn->leaf) { | 781 | if (!pn->leaf) { |
| 781 | BUG_TRAP(pn->leaf != NULL); | 782 | WARN_ON(pn->leaf == NULL); |
| 782 | pn->leaf = info->nl_net->ipv6.ip6_null_entry; | 783 | pn->leaf = info->nl_net->ipv6.ip6_null_entry; |
| 783 | } | 784 | } |
| 784 | #endif | 785 | #endif |
| @@ -942,7 +943,7 @@ struct fib6_node * fib6_locate(struct fib6_node *root, | |||
| 942 | 943 | ||
| 943 | #ifdef CONFIG_IPV6_SUBTREES | 944 | #ifdef CONFIG_IPV6_SUBTREES |
| 944 | if (src_len) { | 945 | if (src_len) { |
| 945 | BUG_TRAP(saddr!=NULL); | 946 | WARN_ON(saddr == NULL); |
| 946 | if (fn && fn->subtree) | 947 | if (fn && fn->subtree) |
| 947 | fn = fib6_locate_1(fn->subtree, saddr, src_len, | 948 | fn = fib6_locate_1(fn->subtree, saddr, src_len, |
| 948 | offsetof(struct rt6_info, rt6i_src)); | 949 | offsetof(struct rt6_info, rt6i_src)); |
| @@ -996,9 +997,9 @@ static struct fib6_node *fib6_repair_tree(struct net *net, | |||
| 996 | RT6_TRACE("fixing tree: plen=%d iter=%d\n", fn->fn_bit, iter); | 997 | RT6_TRACE("fixing tree: plen=%d iter=%d\n", fn->fn_bit, iter); |
| 997 | iter++; | 998 | iter++; |
| 998 | 999 | ||
| 999 | BUG_TRAP(!(fn->fn_flags&RTN_RTINFO)); | 1000 | WARN_ON(fn->fn_flags & RTN_RTINFO); |
| 1000 | BUG_TRAP(!(fn->fn_flags&RTN_TL_ROOT)); | 1001 | WARN_ON(fn->fn_flags & RTN_TL_ROOT); |
| 1001 | BUG_TRAP(fn->leaf==NULL); | 1002 | WARN_ON(fn->leaf != NULL); |
| 1002 | 1003 | ||
| 1003 | children = 0; | 1004 | children = 0; |
| 1004 | child = NULL; | 1005 | child = NULL; |
| @@ -1014,7 +1015,7 @@ static struct fib6_node *fib6_repair_tree(struct net *net, | |||
| 1014 | fn->leaf = fib6_find_prefix(net, fn); | 1015 | fn->leaf = fib6_find_prefix(net, fn); |
| 1015 | #if RT6_DEBUG >= 2 | 1016 | #if RT6_DEBUG >= 2 |
| 1016 | if (fn->leaf==NULL) { | 1017 | if (fn->leaf==NULL) { |
| 1017 | BUG_TRAP(fn->leaf); | 1018 | WARN_ON(!fn->leaf); |
| 1018 | fn->leaf = net->ipv6.ip6_null_entry; | 1019 | fn->leaf = net->ipv6.ip6_null_entry; |
| 1019 | } | 1020 | } |
| 1020 | #endif | 1021 | #endif |
| @@ -1025,16 +1026,17 @@ static struct fib6_node *fib6_repair_tree(struct net *net, | |||
| 1025 | pn = fn->parent; | 1026 | pn = fn->parent; |
| 1026 | #ifdef CONFIG_IPV6_SUBTREES | 1027 | #ifdef CONFIG_IPV6_SUBTREES |
| 1027 | if (FIB6_SUBTREE(pn) == fn) { | 1028 | if (FIB6_SUBTREE(pn) == fn) { |
| 1028 | BUG_TRAP(fn->fn_flags&RTN_ROOT); | 1029 | WARN_ON(!(fn->fn_flags & RTN_ROOT)); |
| 1029 | FIB6_SUBTREE(pn) = NULL; | 1030 | FIB6_SUBTREE(pn) = NULL; |
| 1030 | nstate = FWS_L; | 1031 | nstate = FWS_L; |
| 1031 | } else { | 1032 | } else { |
| 1032 | BUG_TRAP(!(fn->fn_flags&RTN_ROOT)); | 1033 | WARN_ON(fn->fn_flags & RTN_ROOT); |
| 1033 | #endif | 1034 | #endif |
| 1034 | if (pn->right == fn) pn->right = child; | 1035 | if (pn->right == fn) pn->right = child; |
| 1035 | else if (pn->left == fn) pn->left = child; | 1036 | else if (pn->left == fn) pn->left = child; |
| 1036 | #if RT6_DEBUG >= 2 | 1037 | #if RT6_DEBUG >= 2 |
| 1037 | else BUG_TRAP(0); | 1038 | else |
| 1039 | WARN_ON(1); | ||
| 1038 | #endif | 1040 | #endif |
| 1039 | if (child) | 1041 | if (child) |
| 1040 | child->parent = pn; | 1042 | child->parent = pn; |
| @@ -1154,14 +1156,14 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) | |||
| 1154 | 1156 | ||
| 1155 | #if RT6_DEBUG >= 2 | 1157 | #if RT6_DEBUG >= 2 |
| 1156 | if (rt->u.dst.obsolete>0) { | 1158 | if (rt->u.dst.obsolete>0) { |
| 1157 | BUG_TRAP(fn==NULL); | 1159 | WARN_ON(fn != NULL); |
| 1158 | return -ENOENT; | 1160 | return -ENOENT; |
| 1159 | } | 1161 | } |
| 1160 | #endif | 1162 | #endif |
| 1161 | if (fn == NULL || rt == net->ipv6.ip6_null_entry) | 1163 | if (fn == NULL || rt == net->ipv6.ip6_null_entry) |
| 1162 | return -ENOENT; | 1164 | return -ENOENT; |
| 1163 | 1165 | ||
| 1164 | BUG_TRAP(fn->fn_flags&RTN_RTINFO); | 1166 | WARN_ON(!(fn->fn_flags & RTN_RTINFO)); |
| 1165 | 1167 | ||
| 1166 | if (!(rt->rt6i_flags&RTF_CACHE)) { | 1168 | if (!(rt->rt6i_flags&RTF_CACHE)) { |
| 1167 | struct fib6_node *pn = fn; | 1169 | struct fib6_node *pn = fn; |
| @@ -1266,7 +1268,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
| 1266 | w->node = pn; | 1268 | w->node = pn; |
| 1267 | #ifdef CONFIG_IPV6_SUBTREES | 1269 | #ifdef CONFIG_IPV6_SUBTREES |
| 1268 | if (FIB6_SUBTREE(pn) == fn) { | 1270 | if (FIB6_SUBTREE(pn) == fn) { |
| 1269 | BUG_TRAP(fn->fn_flags&RTN_ROOT); | 1271 | WARN_ON(!(fn->fn_flags & RTN_ROOT)); |
| 1270 | w->state = FWS_L; | 1272 | w->state = FWS_L; |
| 1271 | continue; | 1273 | continue; |
| 1272 | } | 1274 | } |
| @@ -1281,7 +1283,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
| 1281 | continue; | 1283 | continue; |
| 1282 | } | 1284 | } |
| 1283 | #if RT6_DEBUG >= 2 | 1285 | #if RT6_DEBUG >= 2 |
| 1284 | BUG_TRAP(0); | 1286 | WARN_ON(1); |
| 1285 | #endif | 1287 | #endif |
| 1286 | } | 1288 | } |
| 1287 | } | 1289 | } |
| @@ -1323,7 +1325,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) | |||
| 1323 | } | 1325 | } |
| 1324 | return 0; | 1326 | return 0; |
| 1325 | } | 1327 | } |
| 1326 | BUG_TRAP(res==0); | 1328 | WARN_ON(res != 0); |
| 1327 | } | 1329 | } |
| 1328 | w->leaf = rt; | 1330 | w->leaf = rt; |
| 1329 | return 0; | 1331 | return 0; |
| @@ -1447,27 +1449,23 @@ void fib6_run_gc(unsigned long expires, struct net *net) | |||
| 1447 | gc_args.timeout = expires ? (int)expires : | 1449 | gc_args.timeout = expires ? (int)expires : |
| 1448 | net->ipv6.sysctl.ip6_rt_gc_interval; | 1450 | net->ipv6.sysctl.ip6_rt_gc_interval; |
| 1449 | } else { | 1451 | } else { |
| 1450 | local_bh_disable(); | 1452 | if (!spin_trylock_bh(&fib6_gc_lock)) { |
| 1451 | if (!spin_trylock(&fib6_gc_lock)) { | 1453 | mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); |
| 1452 | mod_timer(net->ipv6.ip6_fib_timer, jiffies + HZ); | ||
| 1453 | local_bh_enable(); | ||
| 1454 | return; | 1454 | return; |
| 1455 | } | 1455 | } |
| 1456 | gc_args.timeout = net->ipv6.sysctl.ip6_rt_gc_interval; | 1456 | gc_args.timeout = net->ipv6.sysctl.ip6_rt_gc_interval; |
| 1457 | } | 1457 | } |
| 1458 | gc_args.more = 0; | ||
| 1459 | 1458 | ||
| 1460 | icmp6_dst_gc(&gc_args.more); | 1459 | gc_args.more = icmp6_dst_gc(); |
| 1461 | 1460 | ||
| 1462 | fib6_clean_all(net, fib6_age, 0, NULL); | 1461 | fib6_clean_all(net, fib6_age, 0, NULL); |
| 1463 | 1462 | ||
| 1464 | if (gc_args.more) | 1463 | if (gc_args.more) |
| 1465 | mod_timer(net->ipv6.ip6_fib_timer, jiffies + | 1464 | mod_timer(&net->ipv6.ip6_fib_timer, |
| 1466 | net->ipv6.sysctl.ip6_rt_gc_interval); | 1465 | round_jiffies(jiffies |
| 1467 | else { | 1466 | + net->ipv6.sysctl.ip6_rt_gc_interval)); |
| 1468 | del_timer(net->ipv6.ip6_fib_timer); | 1467 | else |
| 1469 | net->ipv6.ip6_fib_timer->expires = 0; | 1468 | del_timer(&net->ipv6.ip6_fib_timer); |
| 1470 | } | ||
| 1471 | spin_unlock_bh(&fib6_gc_lock); | 1469 | spin_unlock_bh(&fib6_gc_lock); |
| 1472 | } | 1470 | } |
| 1473 | 1471 | ||
| @@ -1478,24 +1476,15 @@ static void fib6_gc_timer_cb(unsigned long arg) | |||
| 1478 | 1476 | ||
| 1479 | static int fib6_net_init(struct net *net) | 1477 | static int fib6_net_init(struct net *net) |
| 1480 | { | 1478 | { |
| 1481 | int ret; | 1479 | setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); |
| 1482 | struct timer_list *timer; | ||
| 1483 | |||
| 1484 | ret = -ENOMEM; | ||
| 1485 | timer = kzalloc(sizeof(*timer), GFP_KERNEL); | ||
| 1486 | if (!timer) | ||
| 1487 | goto out; | ||
| 1488 | |||
| 1489 | setup_timer(timer, fib6_gc_timer_cb, (unsigned long)net); | ||
| 1490 | net->ipv6.ip6_fib_timer = timer; | ||
| 1491 | 1480 | ||
| 1492 | net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); | 1481 | net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); |
| 1493 | if (!net->ipv6.rt6_stats) | 1482 | if (!net->ipv6.rt6_stats) |
| 1494 | goto out_timer; | 1483 | goto out_timer; |
| 1495 | 1484 | ||
| 1496 | net->ipv6.fib_table_hash = | 1485 | net->ipv6.fib_table_hash = kcalloc(FIB_TABLE_HASHSZ, |
| 1497 | kzalloc(sizeof(*net->ipv6.fib_table_hash)*FIB_TABLE_HASHSZ, | 1486 | sizeof(*net->ipv6.fib_table_hash), |
| 1498 | GFP_KERNEL); | 1487 | GFP_KERNEL); |
| 1499 | if (!net->ipv6.fib_table_hash) | 1488 | if (!net->ipv6.fib_table_hash) |
| 1500 | goto out_rt6_stats; | 1489 | goto out_rt6_stats; |
| 1501 | 1490 | ||
| @@ -1521,9 +1510,7 @@ static int fib6_net_init(struct net *net) | |||
| 1521 | #endif | 1510 | #endif |
| 1522 | fib6_tables_init(net); | 1511 | fib6_tables_init(net); |
| 1523 | 1512 | ||
| 1524 | ret = 0; | 1513 | return 0; |
| 1525 | out: | ||
| 1526 | return ret; | ||
| 1527 | 1514 | ||
| 1528 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 1515 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 1529 | out_fib6_main_tbl: | 1516 | out_fib6_main_tbl: |
| @@ -1534,15 +1521,14 @@ out_fib_table_hash: | |||
| 1534 | out_rt6_stats: | 1521 | out_rt6_stats: |
| 1535 | kfree(net->ipv6.rt6_stats); | 1522 | kfree(net->ipv6.rt6_stats); |
| 1536 | out_timer: | 1523 | out_timer: |
| 1537 | kfree(timer); | 1524 | return -ENOMEM; |
| 1538 | goto out; | ||
| 1539 | } | 1525 | } |
| 1540 | 1526 | ||
| 1541 | static void fib6_net_exit(struct net *net) | 1527 | static void fib6_net_exit(struct net *net) |
| 1542 | { | 1528 | { |
| 1543 | rt6_ifdown(net, NULL); | 1529 | rt6_ifdown(net, NULL); |
| 1544 | del_timer_sync(net->ipv6.ip6_fib_timer); | 1530 | del_timer_sync(&net->ipv6.ip6_fib_timer); |
| 1545 | kfree(net->ipv6.ip6_fib_timer); | 1531 | |
| 1546 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 1532 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 1547 | kfree(net->ipv6.fib6_local_tbl); | 1533 | kfree(net->ipv6.fib6_local_tbl); |
| 1548 | #endif | 1534 | #endif |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6407c64ea4a5..0e844c2736a7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -116,7 +116,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
| 116 | __skb_pull(newskb, skb_network_offset(newskb)); | 116 | __skb_pull(newskb, skb_network_offset(newskb)); |
| 117 | newskb->pkt_type = PACKET_LOOPBACK; | 117 | newskb->pkt_type = PACKET_LOOPBACK; |
| 118 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 118 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
| 119 | BUG_TRAP(newskb->dst); | 119 | WARN_ON(!newskb->dst); |
| 120 | 120 | ||
| 121 | netif_rx(newskb); | 121 | netif_rx(newskb); |
| 122 | return 0; | 122 | return 0; |
| @@ -236,6 +236,10 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 236 | skb_reset_network_header(skb); | 236 | skb_reset_network_header(skb); |
| 237 | hdr = ipv6_hdr(skb); | 237 | hdr = ipv6_hdr(skb); |
| 238 | 238 | ||
| 239 | /* Allow local fragmentation. */ | ||
| 240 | if (ipfragok) | ||
| 241 | skb->local_df = 1; | ||
| 242 | |||
| 239 | /* | 243 | /* |
| 240 | * Fill in the IPv6 header | 244 | * Fill in the IPv6 header |
| 241 | */ | 245 | */ |
| @@ -265,7 +269,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 265 | skb->mark = sk->sk_mark; | 269 | skb->mark = sk->sk_mark; |
| 266 | 270 | ||
| 267 | mtu = dst_mtu(dst); | 271 | mtu = dst_mtu(dst); |
| 268 | if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { | 272 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { |
| 269 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 273 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
| 270 | IPSTATS_MIB_OUTREQUESTS); | 274 | IPSTATS_MIB_OUTREQUESTS); |
| 271 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 275 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
| @@ -930,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
| 930 | goto out_err_release; | 934 | goto out_err_release; |
| 931 | 935 | ||
| 932 | if (ipv6_addr_any(&fl->fl6_src)) { | 936 | if (ipv6_addr_any(&fl->fl6_src)) { |
| 933 | err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, | 937 | err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, |
| 934 | &fl->fl6_dst, | 938 | &fl->fl6_dst, |
| 935 | sk ? inet6_sk(sk)->srcprefs : 0, | 939 | sk ? inet6_sk(sk)->srcprefs : 0, |
| 936 | &fl->fl6_src); | 940 | &fl->fl6_src); |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index ee6de425ce6b..4545e4306862 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
| @@ -50,125 +50,6 @@ | |||
| 50 | #include <linux/icmpv6.h> | 50 | #include <linux/icmpv6.h> |
| 51 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
| 52 | 52 | ||
| 53 | struct ipcomp6_tfms { | ||
| 54 | struct list_head list; | ||
| 55 | struct crypto_comp **tfms; | ||
| 56 | int users; | ||
| 57 | }; | ||
| 58 | |||
| 59 | static DEFINE_MUTEX(ipcomp6_resource_mutex); | ||
| 60 | static void **ipcomp6_scratches; | ||
| 61 | static int ipcomp6_scratch_users; | ||
| 62 | static LIST_HEAD(ipcomp6_tfms_list); | ||
| 63 | |||
| 64 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | ||
| 65 | { | ||
| 66 | int nexthdr; | ||
| 67 | int err = -ENOMEM; | ||
| 68 | struct ip_comp_hdr *ipch; | ||
| 69 | int plen, dlen; | ||
| 70 | struct ipcomp_data *ipcd = x->data; | ||
| 71 | u8 *start, *scratch; | ||
| 72 | struct crypto_comp *tfm; | ||
| 73 | int cpu; | ||
| 74 | |||
| 75 | if (skb_linearize_cow(skb)) | ||
| 76 | goto out; | ||
| 77 | |||
| 78 | skb->ip_summed = CHECKSUM_NONE; | ||
| 79 | |||
| 80 | /* Remove ipcomp header and decompress original payload */ | ||
| 81 | ipch = (void *)skb->data; | ||
| 82 | nexthdr = ipch->nexthdr; | ||
| 83 | |||
| 84 | skb->transport_header = skb->network_header + sizeof(*ipch); | ||
| 85 | __skb_pull(skb, sizeof(*ipch)); | ||
| 86 | |||
| 87 | /* decompression */ | ||
| 88 | plen = skb->len; | ||
| 89 | dlen = IPCOMP_SCRATCH_SIZE; | ||
| 90 | start = skb->data; | ||
| 91 | |||
| 92 | cpu = get_cpu(); | ||
| 93 | scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); | ||
| 94 | tfm = *per_cpu_ptr(ipcd->tfms, cpu); | ||
| 95 | |||
| 96 | err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); | ||
| 97 | if (err) | ||
| 98 | goto out_put_cpu; | ||
| 99 | |||
| 100 | if (dlen < (plen + sizeof(*ipch))) { | ||
| 101 | err = -EINVAL; | ||
| 102 | goto out_put_cpu; | ||
| 103 | } | ||
| 104 | |||
| 105 | err = pskb_expand_head(skb, 0, dlen - plen, GFP_ATOMIC); | ||
| 106 | if (err) { | ||
| 107 | goto out_put_cpu; | ||
| 108 | } | ||
| 109 | |||
| 110 | skb->truesize += dlen - plen; | ||
| 111 | __skb_put(skb, dlen - plen); | ||
| 112 | skb_copy_to_linear_data(skb, scratch, dlen); | ||
| 113 | err = nexthdr; | ||
| 114 | |||
| 115 | out_put_cpu: | ||
| 116 | put_cpu(); | ||
| 117 | out: | ||
| 118 | return err; | ||
| 119 | } | ||
| 120 | |||
| 121 | static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) | ||
| 122 | { | ||
| 123 | int err; | ||
| 124 | struct ip_comp_hdr *ipch; | ||
| 125 | struct ipcomp_data *ipcd = x->data; | ||
| 126 | int plen, dlen; | ||
| 127 | u8 *start, *scratch; | ||
| 128 | struct crypto_comp *tfm; | ||
| 129 | int cpu; | ||
| 130 | |||
| 131 | /* check whether datagram len is larger than threshold */ | ||
| 132 | if (skb->len < ipcd->threshold) { | ||
| 133 | goto out_ok; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (skb_linearize_cow(skb)) | ||
| 137 | goto out_ok; | ||
| 138 | |||
| 139 | /* compression */ | ||
| 140 | plen = skb->len; | ||
| 141 | dlen = IPCOMP_SCRATCH_SIZE; | ||
| 142 | start = skb->data; | ||
| 143 | |||
| 144 | cpu = get_cpu(); | ||
| 145 | scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); | ||
| 146 | tfm = *per_cpu_ptr(ipcd->tfms, cpu); | ||
| 147 | |||
| 148 | local_bh_disable(); | ||
| 149 | err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); | ||
| 150 | local_bh_enable(); | ||
| 151 | if (err || (dlen + sizeof(*ipch)) >= plen) { | ||
| 152 | put_cpu(); | ||
| 153 | goto out_ok; | ||
| 154 | } | ||
| 155 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); | ||
| 156 | put_cpu(); | ||
| 157 | pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); | ||
| 158 | |||
| 159 | /* insert ipcomp header and replace datagram */ | ||
| 160 | ipch = ip_comp_hdr(skb); | ||
| 161 | ipch->nexthdr = *skb_mac_header(skb); | ||
| 162 | ipch->flags = 0; | ||
| 163 | ipch->cpi = htons((u16 )ntohl(x->id.spi)); | ||
| 164 | *skb_mac_header(skb) = IPPROTO_COMP; | ||
| 165 | |||
| 166 | out_ok: | ||
| 167 | skb_push(skb, -skb_network_offset(skb)); | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 53 | static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
| 173 | int type, int code, int offset, __be32 info) | 54 | int type, int code, int offset, __be32 info) |
| 174 | { | 55 | { |
| @@ -251,160 +132,9 @@ out: | |||
| 251 | return err; | 132 | return err; |
| 252 | } | 133 | } |
| 253 | 134 | ||
| 254 | static void ipcomp6_free_scratches(void) | ||
| 255 | { | ||
| 256 | int i; | ||
| 257 | void **scratches; | ||
| 258 | |||
| 259 | if (--ipcomp6_scratch_users) | ||
| 260 | return; | ||
| 261 | |||
| 262 | scratches = ipcomp6_scratches; | ||
| 263 | if (!scratches) | ||
| 264 | return; | ||
| 265 | |||
| 266 | for_each_possible_cpu(i) { | ||
| 267 | void *scratch = *per_cpu_ptr(scratches, i); | ||
| 268 | |||
| 269 | vfree(scratch); | ||
| 270 | } | ||
| 271 | |||
| 272 | free_percpu(scratches); | ||
| 273 | } | ||
| 274 | |||
| 275 | static void **ipcomp6_alloc_scratches(void) | ||
| 276 | { | ||
| 277 | int i; | ||
| 278 | void **scratches; | ||
| 279 | |||
| 280 | if (ipcomp6_scratch_users++) | ||
| 281 | return ipcomp6_scratches; | ||
| 282 | |||
| 283 | scratches = alloc_percpu(void *); | ||
| 284 | if (!scratches) | ||
| 285 | return NULL; | ||
| 286 | |||
| 287 | ipcomp6_scratches = scratches; | ||
| 288 | |||
| 289 | for_each_possible_cpu(i) { | ||
| 290 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); | ||
| 291 | if (!scratch) | ||
| 292 | return NULL; | ||
| 293 | *per_cpu_ptr(scratches, i) = scratch; | ||
| 294 | } | ||
| 295 | |||
| 296 | return scratches; | ||
| 297 | } | ||
| 298 | |||
| 299 | static void ipcomp6_free_tfms(struct crypto_comp **tfms) | ||
| 300 | { | ||
| 301 | struct ipcomp6_tfms *pos; | ||
| 302 | int cpu; | ||
| 303 | |||
| 304 | list_for_each_entry(pos, &ipcomp6_tfms_list, list) { | ||
| 305 | if (pos->tfms == tfms) | ||
| 306 | break; | ||
| 307 | } | ||
| 308 | |||
| 309 | BUG_TRAP(pos); | ||
| 310 | |||
| 311 | if (--pos->users) | ||
| 312 | return; | ||
| 313 | |||
| 314 | list_del(&pos->list); | ||
| 315 | kfree(pos); | ||
| 316 | |||
| 317 | if (!tfms) | ||
| 318 | return; | ||
| 319 | |||
| 320 | for_each_possible_cpu(cpu) { | ||
| 321 | struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu); | ||
| 322 | crypto_free_comp(tfm); | ||
| 323 | } | ||
| 324 | free_percpu(tfms); | ||
| 325 | } | ||
| 326 | |||
| 327 | static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name) | ||
| 328 | { | ||
| 329 | struct ipcomp6_tfms *pos; | ||
| 330 | struct crypto_comp **tfms; | ||
| 331 | int cpu; | ||
| 332 | |||
| 333 | /* This can be any valid CPU ID so we don't need locking. */ | ||
| 334 | cpu = raw_smp_processor_id(); | ||
| 335 | |||
| 336 | list_for_each_entry(pos, &ipcomp6_tfms_list, list) { | ||
| 337 | struct crypto_comp *tfm; | ||
| 338 | |||
| 339 | tfms = pos->tfms; | ||
| 340 | tfm = *per_cpu_ptr(tfms, cpu); | ||
| 341 | |||
| 342 | if (!strcmp(crypto_comp_name(tfm), alg_name)) { | ||
| 343 | pos->users++; | ||
| 344 | return tfms; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | pos = kmalloc(sizeof(*pos), GFP_KERNEL); | ||
| 349 | if (!pos) | ||
| 350 | return NULL; | ||
| 351 | |||
| 352 | pos->users = 1; | ||
| 353 | INIT_LIST_HEAD(&pos->list); | ||
| 354 | list_add(&pos->list, &ipcomp6_tfms_list); | ||
| 355 | |||
| 356 | pos->tfms = tfms = alloc_percpu(struct crypto_comp *); | ||
| 357 | if (!tfms) | ||
| 358 | goto error; | ||
| 359 | |||
| 360 | for_each_possible_cpu(cpu) { | ||
| 361 | struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, | ||
| 362 | CRYPTO_ALG_ASYNC); | ||
| 363 | if (IS_ERR(tfm)) | ||
| 364 | goto error; | ||
| 365 | *per_cpu_ptr(tfms, cpu) = tfm; | ||
| 366 | } | ||
| 367 | |||
| 368 | return tfms; | ||
| 369 | |||
| 370 | error: | ||
| 371 | ipcomp6_free_tfms(tfms); | ||
| 372 | return NULL; | ||
| 373 | } | ||
| 374 | |||
| 375 | static void ipcomp6_free_data(struct ipcomp_data *ipcd) | ||
| 376 | { | ||
| 377 | if (ipcd->tfms) | ||
| 378 | ipcomp6_free_tfms(ipcd->tfms); | ||
| 379 | ipcomp6_free_scratches(); | ||
| 380 | } | ||
| 381 | |||
| 382 | static void ipcomp6_destroy(struct xfrm_state *x) | ||
| 383 | { | ||
| 384 | struct ipcomp_data *ipcd = x->data; | ||
| 385 | if (!ipcd) | ||
| 386 | return; | ||
| 387 | xfrm_state_delete_tunnel(x); | ||
| 388 | mutex_lock(&ipcomp6_resource_mutex); | ||
| 389 | ipcomp6_free_data(ipcd); | ||
| 390 | mutex_unlock(&ipcomp6_resource_mutex); | ||
| 391 | kfree(ipcd); | ||
| 392 | |||
| 393 | xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); | ||
| 394 | } | ||
| 395 | |||
| 396 | static int ipcomp6_init_state(struct xfrm_state *x) | 135 | static int ipcomp6_init_state(struct xfrm_state *x) |
| 397 | { | 136 | { |
| 398 | int err; | 137 | int err = -EINVAL; |
| 399 | struct ipcomp_data *ipcd; | ||
| 400 | struct xfrm_algo_desc *calg_desc; | ||
| 401 | |||
| 402 | err = -EINVAL; | ||
| 403 | if (!x->calg) | ||
| 404 | goto out; | ||
| 405 | |||
| 406 | if (x->encap) | ||
| 407 | goto out; | ||
| 408 | 138 | ||
| 409 | x->props.header_len = 0; | 139 | x->props.header_len = 0; |
| 410 | switch (x->props.mode) { | 140 | switch (x->props.mode) { |
| @@ -417,39 +147,21 @@ static int ipcomp6_init_state(struct xfrm_state *x) | |||
| 417 | goto out; | 147 | goto out; |
| 418 | } | 148 | } |
| 419 | 149 | ||
| 420 | err = -ENOMEM; | 150 | err = ipcomp_init_state(x); |
| 421 | ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); | 151 | if (err) |
| 422 | if (!ipcd) | ||
| 423 | goto out; | 152 | goto out; |
| 424 | 153 | ||
| 425 | mutex_lock(&ipcomp6_resource_mutex); | ||
| 426 | if (!ipcomp6_alloc_scratches()) | ||
| 427 | goto error; | ||
| 428 | |||
| 429 | ipcd->tfms = ipcomp6_alloc_tfms(x->calg->alg_name); | ||
| 430 | if (!ipcd->tfms) | ||
| 431 | goto error; | ||
| 432 | mutex_unlock(&ipcomp6_resource_mutex); | ||
| 433 | |||
| 434 | if (x->props.mode == XFRM_MODE_TUNNEL) { | 154 | if (x->props.mode == XFRM_MODE_TUNNEL) { |
| 435 | err = ipcomp6_tunnel_attach(x); | 155 | err = ipcomp6_tunnel_attach(x); |
| 436 | if (err) | 156 | if (err) |
| 437 | goto error_tunnel; | 157 | goto error_tunnel; |
| 438 | } | 158 | } |
| 439 | 159 | ||
| 440 | calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0); | ||
| 441 | BUG_ON(!calg_desc); | ||
| 442 | ipcd->threshold = calg_desc->uinfo.comp.threshold; | ||
| 443 | x->data = ipcd; | ||
| 444 | err = 0; | 160 | err = 0; |
| 445 | out: | 161 | out: |
| 446 | return err; | 162 | return err; |
| 447 | error_tunnel: | 163 | error_tunnel: |
| 448 | mutex_lock(&ipcomp6_resource_mutex); | 164 | ipcomp_destroy(x); |
| 449 | error: | ||
| 450 | ipcomp6_free_data(ipcd); | ||
| 451 | mutex_unlock(&ipcomp6_resource_mutex); | ||
| 452 | kfree(ipcd); | ||
| 453 | 165 | ||
| 454 | goto out; | 166 | goto out; |
| 455 | } | 167 | } |
| @@ -460,9 +172,9 @@ static const struct xfrm_type ipcomp6_type = | |||
| 460 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
| 461 | .proto = IPPROTO_COMP, | 173 | .proto = IPPROTO_COMP, |
| 462 | .init_state = ipcomp6_init_state, | 174 | .init_state = ipcomp6_init_state, |
| 463 | .destructor = ipcomp6_destroy, | 175 | .destructor = ipcomp_destroy, |
| 464 | .input = ipcomp6_input, | 176 | .input = ipcomp_input, |
| 465 | .output = ipcomp6_output, | 177 | .output = ipcomp_output, |
| 466 | .hdr_offset = xfrm6_find_1stfragopt, | 178 | .hdr_offset = xfrm6_find_1stfragopt, |
| 467 | }; | 179 | }; |
| 468 | 180 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ea33b26512c2..4e5eac301f91 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -346,6 +346,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
| 346 | */ | 346 | */ |
| 347 | if (optlen == 0) | 347 | if (optlen == 0) |
| 348 | optval = NULL; | 348 | optval = NULL; |
| 349 | else if (optval == NULL) | ||
| 350 | goto e_inval; | ||
| 349 | else if (optlen < sizeof(struct ipv6_opt_hdr) || | 351 | else if (optlen < sizeof(struct ipv6_opt_hdr) || |
| 350 | optlen & 0x7 || optlen > 8 * 255) | 352 | optlen & 0x7 || optlen > 8 * 255) |
| 351 | goto e_inval; | 353 | goto e_inval; |
| @@ -909,7 +911,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 909 | } else { | 911 | } else { |
| 910 | if (np->rxopt.bits.rxinfo) { | 912 | if (np->rxopt.bits.rxinfo) { |
| 911 | struct in6_pktinfo src_info; | 913 | struct in6_pktinfo src_info; |
| 912 | src_info.ipi6_ifindex = np->mcast_oif; | 914 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; |
| 913 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 915 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); |
| 914 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 916 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); |
| 915 | } | 917 | } |
| @@ -919,7 +921,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 919 | } | 921 | } |
| 920 | if (np->rxopt.bits.rxoinfo) { | 922 | if (np->rxopt.bits.rxoinfo) { |
| 921 | struct in6_pktinfo src_info; | 923 | struct in6_pktinfo src_info; |
| 922 | src_info.ipi6_ifindex = np->mcast_oif; | 924 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; |
| 923 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 925 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); |
| 924 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); | 926 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); |
| 925 | } | 927 | } |
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index ad1cc5bbf977..31295c8f6196 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c | |||
| @@ -164,8 +164,8 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 164 | calc_padlen(sizeof(*dstopt), 6)); | 164 | calc_padlen(sizeof(*dstopt), 6)); |
| 165 | 165 | ||
| 166 | hao->type = IPV6_TLV_HAO; | 166 | hao->type = IPV6_TLV_HAO; |
| 167 | BUILD_BUG_ON(sizeof(*hao) != 18); | ||
| 167 | hao->length = sizeof(*hao) - 2; | 168 | hao->length = sizeof(*hao) - 2; |
| 168 | BUG_TRAP(hao->length == 16); | ||
| 169 | 169 | ||
| 170 | len = ((char *)hao - (char *)dstopt) + sizeof(*hao); | 170 | len = ((char *)hao - (char *)dstopt) + sizeof(*hao); |
| 171 | 171 | ||
| @@ -174,7 +174,7 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 174 | memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); | 174 | memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); |
| 175 | spin_unlock_bh(&x->lock); | 175 | spin_unlock_bh(&x->lock); |
| 176 | 176 | ||
| 177 | BUG_TRAP(len == x->props.header_len); | 177 | WARN_ON(len != x->props.header_len); |
| 178 | dstopt->hdrlen = (x->props.header_len >> 3) - 1; | 178 | dstopt->hdrlen = (x->props.header_len >> 3) - 1; |
| 179 | 179 | ||
| 180 | return 0; | 180 | return 0; |
| @@ -317,7 +317,7 @@ static int mip6_destopt_init_state(struct xfrm_state *x) | |||
| 317 | x->props.header_len = sizeof(struct ipv6_destopt_hdr) + | 317 | x->props.header_len = sizeof(struct ipv6_destopt_hdr) + |
| 318 | calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) + | 318 | calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) + |
| 319 | sizeof(struct ipv6_destopt_hao); | 319 | sizeof(struct ipv6_destopt_hao); |
| 320 | BUG_TRAP(x->props.header_len == 24); | 320 | WARN_ON(x->props.header_len != 24); |
| 321 | 321 | ||
| 322 | return 0; | 322 | return 0; |
| 323 | } | 323 | } |
| @@ -380,7 +380,7 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 380 | rt2->rt_hdr.segments_left = 1; | 380 | rt2->rt_hdr.segments_left = 1; |
| 381 | memset(&rt2->reserved, 0, sizeof(rt2->reserved)); | 381 | memset(&rt2->reserved, 0, sizeof(rt2->reserved)); |
| 382 | 382 | ||
| 383 | BUG_TRAP(rt2->rt_hdr.hdrlen == 2); | 383 | WARN_ON(rt2->rt_hdr.hdrlen != 2); |
| 384 | 384 | ||
| 385 | memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr)); | 385 | memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr)); |
| 386 | spin_lock_bh(&x->lock); | 386 | spin_lock_bh(&x->lock); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index beb48e3f038a..f1c62ba0f56b 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
| 549 | override = 0; | 549 | override = 0; |
| 550 | in6_ifa_put(ifp); | 550 | in6_ifa_put(ifp); |
| 551 | } else { | 551 | } else { |
| 552 | if (ipv6_dev_get_saddr(dev, daddr, | 552 | if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, |
| 553 | inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, | 553 | inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, |
| 554 | &tmpaddr)) | 554 | &tmpaddr)) |
| 555 | return; | 555 | return; |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 689dec899c57..0cfcce7b18d8 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
| @@ -213,7 +213,7 @@ config IP6_NF_SECURITY | |||
| 213 | tristate "Security table" | 213 | tristate "Security table" |
| 214 | depends on IP6_NF_IPTABLES | 214 | depends on IP6_NF_IPTABLES |
| 215 | depends on SECURITY | 215 | depends on SECURITY |
| 216 | default m if NETFILTER_ADVANCED=n | 216 | depends on NETFILTER_ADVANCED |
| 217 | help | 217 | help |
| 218 | This option adds a `security' table to iptables, for use | 218 | This option adds a `security' table to iptables, for use |
| 219 | with Mandatory Access Control (MAC) policy. | 219 | with Mandatory Access Control (MAC) policy. |
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c index a07abee30497..6e7131036bc6 100644 --- a/net/ipv6/netfilter/ip6table_security.c +++ b/net/ipv6/netfilter/ip6table_security.c | |||
| @@ -31,7 +31,7 @@ static struct | |||
| 31 | struct ip6t_replace repl; | 31 | struct ip6t_replace repl; |
| 32 | struct ip6t_standard entries[3]; | 32 | struct ip6t_standard entries[3]; |
| 33 | struct ip6t_error term; | 33 | struct ip6t_error term; |
| 34 | } initial_table __initdata = { | 34 | } initial_table __net_initdata = { |
| 35 | .repl = { | 35 | .repl = { |
| 36 | .name = "security", | 36 | .name = "security", |
| 37 | .valid_hooks = SECURITY_VALID_HOOKS, | 37 | .valid_hooks = SECURITY_VALID_HOOKS, |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index cf20bc4fd60d..52d06dd4b817 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -416,8 +416,8 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) | |||
| 416 | 416 | ||
| 417 | fq_kill(fq); | 417 | fq_kill(fq); |
| 418 | 418 | ||
| 419 | BUG_TRAP(head != NULL); | 419 | WARN_ON(head == NULL); |
| 420 | BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0); | 420 | WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); |
| 421 | 421 | ||
| 422 | /* Unfragmented part is taken from the first segment. */ | 422 | /* Unfragmented part is taken from the first segment. */ |
| 423 | payload_len = ((head->data - skb_network_header(head)) - | 423 | payload_len = ((head->data - skb_network_header(head)) - |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f82f6074cf85..0179b66864f1 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
| @@ -286,7 +286,6 @@ proc_net_fail: | |||
| 286 | 286 | ||
| 287 | void ipv6_misc_proc_exit(void) | 287 | void ipv6_misc_proc_exit(void) |
| 288 | { | 288 | { |
| 289 | proc_net_remove(&init_net, "sockstat6"); | ||
| 290 | proc_net_remove(&init_net, "dev_snmp6"); | 289 | proc_net_remove(&init_net, "dev_snmp6"); |
| 291 | proc_net_remove(&init_net, "snmp6"); | 290 | proc_net_remove(&init_net, "snmp6"); |
| 292 | unregister_pernet_subsys(&ipv6_proc_ops); | 291 | unregister_pernet_subsys(&ipv6_proc_ops); |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 6ab957ec2dd6..89184b576e23 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -473,8 +473,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
| 473 | fq->q.fragments = head; | 473 | fq->q.fragments = head; |
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | BUG_TRAP(head != NULL); | 476 | WARN_ON(head == NULL); |
| 477 | BUG_TRAP(FRAG6_CB(head)->offset == 0); | 477 | WARN_ON(FRAG6_CB(head)->offset != 0); |
| 478 | 478 | ||
| 479 | /* Unfragmented part is taken from the first segment. */ | 479 | /* Unfragmented part is taken from the first segment. */ |
| 480 | payload_len = ((head->data - skb_network_header(head)) - | 480 | payload_len = ((head->data - skb_network_header(head)) - |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 615b328de251..9af6115f0f50 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -978,13 +978,12 @@ out: | |||
| 978 | return &rt->u.dst; | 978 | return &rt->u.dst; |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | int icmp6_dst_gc(int *more) | 981 | int icmp6_dst_gc(void) |
| 982 | { | 982 | { |
| 983 | struct dst_entry *dst, *next, **pprev; | 983 | struct dst_entry *dst, *next, **pprev; |
| 984 | int freed; | 984 | int more = 0; |
| 985 | 985 | ||
| 986 | next = NULL; | 986 | next = NULL; |
| 987 | freed = 0; | ||
| 988 | 987 | ||
| 989 | spin_lock_bh(&icmp6_dst_lock); | 988 | spin_lock_bh(&icmp6_dst_lock); |
| 990 | pprev = &icmp6_dst_gc_list; | 989 | pprev = &icmp6_dst_gc_list; |
| @@ -993,16 +992,15 @@ int icmp6_dst_gc(int *more) | |||
| 993 | if (!atomic_read(&dst->__refcnt)) { | 992 | if (!atomic_read(&dst->__refcnt)) { |
| 994 | *pprev = dst->next; | 993 | *pprev = dst->next; |
| 995 | dst_free(dst); | 994 | dst_free(dst); |
| 996 | freed++; | ||
| 997 | } else { | 995 | } else { |
| 998 | pprev = &dst->next; | 996 | pprev = &dst->next; |
| 999 | (*more)++; | 997 | ++more; |
| 1000 | } | 998 | } |
| 1001 | } | 999 | } |
| 1002 | 1000 | ||
| 1003 | spin_unlock_bh(&icmp6_dst_lock); | 1001 | spin_unlock_bh(&icmp6_dst_lock); |
| 1004 | 1002 | ||
| 1005 | return freed; | 1003 | return more; |
| 1006 | } | 1004 | } |
| 1007 | 1005 | ||
| 1008 | static int ip6_dst_gc(struct dst_ops *ops) | 1006 | static int ip6_dst_gc(struct dst_ops *ops) |
| @@ -1251,7 +1249,7 @@ install_route: | |||
| 1251 | 1249 | ||
| 1252 | if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) | 1250 | if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) |
| 1253 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; | 1251 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; |
| 1254 | if (!dst_metric(&rt->u.dst, RTAX_MTU)) | 1252 | if (!dst_mtu(&rt->u.dst)) |
| 1255 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); | 1253 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); |
| 1256 | if (!dst_metric(&rt->u.dst, RTAX_ADVMSS)) | 1254 | if (!dst_metric(&rt->u.dst, RTAX_ADVMSS)) |
| 1257 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); | 1255 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); |
| @@ -2108,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void) | |||
| 2108 | + nla_total_size(sizeof(struct rta_cacheinfo)); | 2106 | + nla_total_size(sizeof(struct rta_cacheinfo)); |
| 2109 | } | 2107 | } |
| 2110 | 2108 | ||
| 2111 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 2109 | static int rt6_fill_node(struct net *net, |
| 2110 | struct sk_buff *skb, struct rt6_info *rt, | ||
| 2112 | struct in6_addr *dst, struct in6_addr *src, | 2111 | struct in6_addr *dst, struct in6_addr *src, |
| 2113 | int iif, int type, u32 pid, u32 seq, | 2112 | int iif, int type, u32 pid, u32 seq, |
| 2114 | int prefix, int nowait, unsigned int flags) | 2113 | int prefix, int nowait, unsigned int flags) |
| @@ -2189,8 +2188,9 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
| 2189 | #endif | 2188 | #endif |
| 2190 | NLA_PUT_U32(skb, RTA_IIF, iif); | 2189 | NLA_PUT_U32(skb, RTA_IIF, iif); |
| 2191 | } else if (dst) { | 2190 | } else if (dst) { |
| 2191 | struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); | ||
| 2192 | struct in6_addr saddr_buf; | 2192 | struct in6_addr saddr_buf; |
| 2193 | if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, | 2193 | if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, |
| 2194 | dst, 0, &saddr_buf) == 0) | 2194 | dst, 0, &saddr_buf) == 0) |
| 2195 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); | 2195 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); |
| 2196 | } | 2196 | } |
| @@ -2235,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
| 2235 | } else | 2235 | } else |
| 2236 | prefix = 0; | 2236 | prefix = 0; |
| 2237 | 2237 | ||
| 2238 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | 2238 | return rt6_fill_node(arg->net, |
| 2239 | arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | ||
| 2239 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, | 2240 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, |
| 2240 | prefix, 0, NLM_F_MULTI); | 2241 | prefix, 0, NLM_F_MULTI); |
| 2241 | } | 2242 | } |
| @@ -2301,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
| 2301 | rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); | 2302 | rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); |
| 2302 | skb->dst = &rt->u.dst; | 2303 | skb->dst = &rt->u.dst; |
| 2303 | 2304 | ||
| 2304 | err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, | 2305 | err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, |
| 2305 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, | 2306 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, |
| 2306 | nlh->nlmsg_seq, 0, 0, 0); | 2307 | nlh->nlmsg_seq, 0, 0, 0); |
| 2307 | if (err < 0) { | 2308 | if (err < 0) { |
| @@ -2328,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
| 2328 | if (skb == NULL) | 2329 | if (skb == NULL) |
| 2329 | goto errout; | 2330 | goto errout; |
| 2330 | 2331 | ||
| 2331 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, | 2332 | err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, |
| 2332 | event, info->pid, seq, 0, 0, 0); | 2333 | event, info->pid, seq, 0, 0, 0); |
| 2333 | if (err < 0) { | 2334 | if (err < 0) { |
| 2334 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ | 2335 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 6a68eeb7bbf8..ec394cf5a19b 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
| @@ -199,10 +199,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 199 | ireq6 = inet6_rsk(req); | 199 | ireq6 = inet6_rsk(req); |
| 200 | treq = tcp_rsk(req); | 200 | treq = tcp_rsk(req); |
| 201 | 201 | ||
| 202 | if (security_inet_conn_request(sk, skb, req)) { | 202 | if (security_inet_conn_request(sk, skb, req)) |
| 203 | reqsk_free(req); | 203 | goto out_free; |
| 204 | goto out; | ||
| 205 | } | ||
| 206 | 204 | ||
| 207 | req->mss = mss; | 205 | req->mss = mss; |
| 208 | ireq->rmt_port = th->source; | 206 | ireq->rmt_port = th->source; |
| @@ -223,6 +221,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 223 | 221 | ||
| 224 | req->expires = 0UL; | 222 | req->expires = 0UL; |
| 225 | req->retrans = 0; | 223 | req->retrans = 0; |
| 224 | ireq->ecn_ok = 0; | ||
| 226 | ireq->snd_wscale = tcp_opt.snd_wscale; | 225 | ireq->snd_wscale = tcp_opt.snd_wscale; |
| 227 | ireq->rcv_wscale = tcp_opt.rcv_wscale; | 226 | ireq->rcv_wscale = tcp_opt.rcv_wscale; |
| 228 | ireq->sack_ok = tcp_opt.sack_ok; | 227 | ireq->sack_ok = tcp_opt.sack_ok; |
| @@ -254,14 +253,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 254 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 253 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
| 255 | fl.fl_ip_sport = inet_sk(sk)->sport; | 254 | fl.fl_ip_sport = inet_sk(sk)->sport; |
| 256 | security_req_classify_flow(req, &fl); | 255 | security_req_classify_flow(req, &fl); |
| 257 | if (ip6_dst_lookup(sk, &dst, &fl)) { | 256 | if (ip6_dst_lookup(sk, &dst, &fl)) |
| 258 | reqsk_free(req); | 257 | goto out_free; |
| 259 | goto out; | 258 | |
| 260 | } | ||
| 261 | if (final_p) | 259 | if (final_p) |
| 262 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 260 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
| 263 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 261 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
| 264 | goto out; | 262 | goto out_free; |
| 265 | } | 263 | } |
| 266 | 264 | ||
| 267 | req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); | 265 | req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); |
| @@ -272,7 +270,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 272 | ireq->rcv_wscale = rcv_wscale; | 270 | ireq->rcv_wscale = rcv_wscale; |
| 273 | 271 | ||
| 274 | ret = get_cookie_sock(sk, skb, req, dst); | 272 | ret = get_cookie_sock(sk, skb, req, dst); |
| 275 | 273 | out: | |
| 276 | out: return ret; | 274 | return ret; |
| 275 | out_free: | ||
| 276 | reqsk_free(req); | ||
| 277 | return NULL; | ||
| 277 | } | 278 | } |
| 278 | 279 | ||
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 5c99274558bf..e6dfaeac6be3 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
| @@ -150,3 +150,19 @@ void ipv6_sysctl_unregister(void) | |||
| 150 | unregister_net_sysctl_table(ip6_header); | 150 | unregister_net_sysctl_table(ip6_header); |
| 151 | unregister_pernet_subsys(&ipv6_sysctl_net_ops); | 151 | unregister_pernet_subsys(&ipv6_sysctl_net_ops); |
| 152 | } | 152 | } |
| 153 | |||
| 154 | static struct ctl_table_header *ip6_base; | ||
| 155 | |||
| 156 | int ipv6_static_sysctl_register(void) | ||
| 157 | { | ||
| 158 | static struct ctl_table empty[1]; | ||
| 159 | ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); | ||
| 160 | if (ip6_base == NULL) | ||
| 161 | return -ENOMEM; | ||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | void ipv6_static_sysctl_unregister(void) | ||
| 166 | { | ||
| 167 | unregister_net_sysctl_table(ip6_base); | ||
| 168 | } | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ae45f9835014..5b90b369ccb2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -69,7 +69,8 @@ | |||
| 69 | #include <linux/scatterlist.h> | 69 | #include <linux/scatterlist.h> |
| 70 | 70 | ||
| 71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); | 71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); |
| 72 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); | 72 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
| 73 | struct request_sock *req); | ||
| 73 | 74 | ||
| 74 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 75 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
| 75 | 76 | ||
| @@ -421,7 +422,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 421 | /* ICMPs are not backlogged, hence we cannot get | 422 | /* ICMPs are not backlogged, hence we cannot get |
| 422 | * an established socket here. | 423 | * an established socket here. |
| 423 | */ | 424 | */ |
| 424 | BUG_TRAP(req->sk == NULL); | 425 | WARN_ON(req->sk != NULL); |
| 425 | 426 | ||
| 426 | if (seq != tcp_rsk(req)->snt_isn) { | 427 | if (seq != tcp_rsk(req)->snt_isn) { |
| 427 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); | 428 | NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); |
| @@ -748,7 +749,7 @@ static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, | |||
| 748 | ipv6_addr_copy(&bp->saddr, saddr); | 749 | ipv6_addr_copy(&bp->saddr, saddr); |
| 749 | ipv6_addr_copy(&bp->daddr, daddr); | 750 | ipv6_addr_copy(&bp->daddr, daddr); |
| 750 | bp->protocol = cpu_to_be32(IPPROTO_TCP); | 751 | bp->protocol = cpu_to_be32(IPPROTO_TCP); |
| 751 | bp->len = cpu_to_be16(nbytes); | 752 | bp->len = cpu_to_be32(nbytes); |
| 752 | 753 | ||
| 753 | sg_init_one(&sg, bp, sizeof(*bp)); | 754 | sg_init_one(&sg, bp, sizeof(*bp)); |
| 754 | return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); | 755 | return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); |
| @@ -849,28 +850,17 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) | |||
| 849 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); | 850 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); |
| 850 | hash_location = tcp_parse_md5sig_option(th); | 851 | hash_location = tcp_parse_md5sig_option(th); |
| 851 | 852 | ||
| 852 | /* do we have a hash as expected? */ | 853 | /* We've parsed the options - do we have a hash? */ |
| 853 | if (!hash_expected) { | 854 | if (!hash_expected && !hash_location) |
| 854 | if (!hash_location) | 855 | return 0; |
| 855 | return 0; | 856 | |
| 856 | if (net_ratelimit()) { | 857 | if (hash_expected && !hash_location) { |
| 857 | printk(KERN_INFO "MD5 Hash NOT expected but found " | 858 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
| 858 | "(" NIP6_FMT ", %u)->" | ||
| 859 | "(" NIP6_FMT ", %u)\n", | ||
| 860 | NIP6(ip6h->saddr), ntohs(th->source), | ||
| 861 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
| 862 | } | ||
| 863 | return 1; | 859 | return 1; |
| 864 | } | 860 | } |
| 865 | 861 | ||
| 866 | if (!hash_location) { | 862 | if (!hash_expected && hash_location) { |
| 867 | if (net_ratelimit()) { | 863 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
| 868 | printk(KERN_INFO "MD5 Hash expected but NOT found " | ||
| 869 | "(" NIP6_FMT ", %u)->" | ||
| 870 | "(" NIP6_FMT ", %u)\n", | ||
| 871 | NIP6(ip6h->saddr), ntohs(th->source), | ||
| 872 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
| 873 | } | ||
| 874 | return 1; | 864 | return 1; |
| 875 | } | 865 | } |
| 876 | 866 | ||
| @@ -1105,8 +1095,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
| 1105 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 1095 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | |
| 1106 | (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); | 1096 | (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); |
| 1107 | tcp_v6_md5_hash_hdr((__u8 *)topt, key, | 1097 | tcp_v6_md5_hash_hdr((__u8 *)topt, key, |
| 1108 | &ipv6_hdr(skb)->daddr, | 1098 | &ipv6_hdr(skb)->saddr, |
| 1109 | &ipv6_hdr(skb)->saddr, t1); | 1099 | &ipv6_hdr(skb)->daddr, t1); |
| 1110 | } | 1100 | } |
| 1111 | #endif | 1101 | #endif |
| 1112 | 1102 | ||
| @@ -1149,10 +1139,11 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
| 1149 | inet_twsk_put(tw); | 1139 | inet_twsk_put(tw); |
| 1150 | } | 1140 | } |
| 1151 | 1141 | ||
| 1152 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) | 1142 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
| 1143 | struct request_sock *req) | ||
| 1153 | { | 1144 | { |
| 1154 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, | 1145 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, |
| 1155 | tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr)); | 1146 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr)); |
| 1156 | } | 1147 | } |
| 1157 | 1148 | ||
| 1158 | 1149 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d1477b350f76..a6aecf76a71b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -379,7 +379,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
| 379 | uh->source, saddr, dif))) { | 379 | uh->source, saddr, dif))) { |
| 380 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 380 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
| 381 | if (buff) { | 381 | if (buff) { |
| 382 | bh_lock_sock_nested(sk2); | 382 | bh_lock_sock(sk2); |
| 383 | if (!sock_owned_by_user(sk2)) | 383 | if (!sock_owned_by_user(sk2)) |
| 384 | udpv6_queue_rcv_skb(sk2, buff); | 384 | udpv6_queue_rcv_skb(sk2, buff); |
| 385 | else | 385 | else |
| @@ -387,7 +387,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
| 387 | bh_unlock_sock(sk2); | 387 | bh_unlock_sock(sk2); |
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | bh_lock_sock_nested(sk); | 390 | bh_lock_sock(sk); |
| 391 | if (!sock_owned_by_user(sk)) | 391 | if (!sock_owned_by_user(sk)) |
| 392 | udpv6_queue_rcv_skb(sk, skb); | 392 | udpv6_queue_rcv_skb(sk, skb); |
| 393 | else | 393 | else |
| @@ -508,7 +508,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
| 508 | 508 | ||
| 509 | /* deliver */ | 509 | /* deliver */ |
| 510 | 510 | ||
| 511 | bh_lock_sock_nested(sk); | 511 | bh_lock_sock(sk); |
| 512 | if (!sock_owned_by_user(sk)) | 512 | if (!sock_owned_by_user(sk)) |
| 513 | udpv6_queue_rcv_skb(sk, skb); | 513 | udpv6_queue_rcv_skb(sk, skb); |
| 514 | else | 514 | else |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index d6ce400f585f..bbd48b101bae 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
| @@ -40,16 +40,39 @@ static void xfrm6_beet_make_header(struct sk_buff *skb) | |||
| 40 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 40 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
| 41 | { | 41 | { |
| 42 | struct ipv6hdr *top_iph; | 42 | struct ipv6hdr *top_iph; |
| 43 | 43 | struct ip_beet_phdr *ph; | |
| 44 | skb_set_network_header(skb, -x->props.header_len); | 44 | struct iphdr *iphv4; |
| 45 | int optlen, hdr_len; | ||
| 46 | |||
| 47 | iphv4 = ip_hdr(skb); | ||
| 48 | hdr_len = 0; | ||
| 49 | optlen = XFRM_MODE_SKB_CB(skb)->optlen; | ||
| 50 | if (unlikely(optlen)) | ||
| 51 | hdr_len += IPV4_BEET_PHMAXLEN - (optlen & 4); | ||
| 52 | |||
| 53 | skb_set_network_header(skb, -x->props.header_len - hdr_len); | ||
| 54 | if (x->sel.family != AF_INET6) | ||
| 55 | skb->network_header += IPV4_BEET_PHMAXLEN; | ||
| 45 | skb->mac_header = skb->network_header + | 56 | skb->mac_header = skb->network_header + |
| 46 | offsetof(struct ipv6hdr, nexthdr); | 57 | offsetof(struct ipv6hdr, nexthdr); |
| 47 | skb->transport_header = skb->network_header + sizeof(*top_iph); | 58 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
| 48 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl); | 59 | ph = (struct ip_beet_phdr *)__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl-hdr_len); |
| 49 | 60 | ||
| 50 | xfrm6_beet_make_header(skb); | 61 | xfrm6_beet_make_header(skb); |
| 51 | 62 | ||
| 52 | top_iph = ipv6_hdr(skb); | 63 | top_iph = ipv6_hdr(skb); |
| 64 | if (unlikely(optlen)) { | ||
| 65 | |||
| 66 | BUG_ON(optlen < 0); | ||
| 67 | |||
| 68 | ph->padlen = 4 - (optlen & 4); | ||
| 69 | ph->hdrlen = optlen / 8; | ||
| 70 | ph->nexthdr = top_iph->nexthdr; | ||
| 71 | if (ph->padlen) | ||
| 72 | memset(ph + 1, IPOPT_NOP, ph->padlen); | ||
| 73 | |||
| 74 | top_iph->nexthdr = IPPROTO_BEETPH; | ||
| 75 | } | ||
| 53 | 76 | ||
| 54 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); | 77 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); |
| 55 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); | 78 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8f1e0543b3c4..08e4cbbe3f04 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
| 52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) | 52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) |
| 53 | { | 53 | { |
| 54 | struct dst_entry *dst; | 54 | struct dst_entry *dst; |
| 55 | struct net_device *dev; | ||
| 55 | 56 | ||
| 56 | dst = xfrm6_dst_lookup(0, NULL, daddr); | 57 | dst = xfrm6_dst_lookup(0, NULL, daddr); |
| 57 | if (IS_ERR(dst)) | 58 | if (IS_ERR(dst)) |
| 58 | return -EHOSTUNREACH; | 59 | return -EHOSTUNREACH; |
| 59 | 60 | ||
| 60 | ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, | 61 | dev = ip6_dst_idev(dst)->dev; |
| 62 | ipv6_dev_get_saddr(dev_net(dev), dev, | ||
| 61 | (struct in6_addr *)&daddr->a6, 0, | 63 | (struct in6_addr *)&daddr->a6, 0, |
| 62 | (struct in6_addr *)&saddr->a6); | 64 | (struct in6_addr *)&saddr->a6); |
| 63 | dst_release(dst); | 65 | dst_release(dst); |
