diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 17 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 5 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 8 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 3 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 10 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 182 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 37 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 19 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 6 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 5 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 6 | ||||
-rw-r--r-- | net/ipv6/mip6.c | 3 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 98 | ||||
-rw-r--r-- | net/ipv6/netfilter.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 2 | ||||
-rw-r--r-- | net/ipv6/proc.c | 6 | ||||
-rw-r--r-- | net/ipv6/raw.c | 3 | ||||
-rw-r--r-- | net/ipv6/route.c | 2 | ||||
-rw-r--r-- | net/ipv6/sit.c | 35 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 20 | ||||
-rw-r--r-- | net/ipv6/udp.c | 63 | ||||
-rw-r--r-- | net/ipv6/xfrm6_input.c | 9 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 13 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 3 |
28 files changed, 348 insertions, 217 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 07ee758de9e1..e92ad8455c63 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2031,8 +2031,8 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2031 | 2031 | ||
2032 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2032 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) |
2033 | if (dev->type == ARPHRD_SIT) { | 2033 | if (dev->type == ARPHRD_SIT) { |
2034 | const struct net_device_ops *ops = dev->netdev_ops; | ||
2034 | struct ifreq ifr; | 2035 | struct ifreq ifr; |
2035 | mm_segment_t oldfs; | ||
2036 | struct ip_tunnel_parm p; | 2036 | struct ip_tunnel_parm p; |
2037 | 2037 | ||
2038 | err = -EADDRNOTAVAIL; | 2038 | err = -EADDRNOTAVAIL; |
@@ -2048,9 +2048,14 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2048 | p.iph.ttl = 64; | 2048 | p.iph.ttl = 64; |
2049 | ifr.ifr_ifru.ifru_data = (__force void __user *)&p; | 2049 | ifr.ifr_ifru.ifru_data = (__force void __user *)&p; |
2050 | 2050 | ||
2051 | oldfs = get_fs(); set_fs(KERNEL_DS); | 2051 | if (ops->ndo_do_ioctl) { |
2052 | err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL); | 2052 | mm_segment_t oldfs = get_fs(); |
2053 | set_fs(oldfs); | 2053 | |
2054 | set_fs(KERNEL_DS); | ||
2055 | err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL); | ||
2056 | set_fs(oldfs); | ||
2057 | } else | ||
2058 | err = -EOPNOTSUPP; | ||
2054 | 2059 | ||
2055 | if (err == 0) { | 2060 | if (err == 0) { |
2056 | err = -ENOBUFS; | 2061 | err = -ENOBUFS; |
@@ -2483,8 +2488,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2483 | if (!idev && dev->mtu >= IPV6_MIN_MTU) | 2488 | if (!idev && dev->mtu >= IPV6_MIN_MTU) |
2484 | idev = ipv6_add_dev(dev); | 2489 | idev = ipv6_add_dev(dev); |
2485 | 2490 | ||
2486 | if (idev) | 2491 | if (idev) { |
2487 | idev->if_flags |= IF_READY; | 2492 | idev->if_flags |= IF_READY; |
2493 | run_pending = 1; | ||
2494 | } | ||
2488 | } else { | 2495 | } else { |
2489 | if (!addrconf_qdisc_ok(dev)) { | 2496 | if (!addrconf_qdisc_ok(dev)) { |
2490 | /* device is still not ready. */ | 2497 | /* device is still not ready. */ |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 01edac888510..437b750b98fd 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -637,7 +637,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
637 | if (final_p) | 637 | if (final_p) |
638 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 638 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
639 | 639 | ||
640 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 640 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) { |
641 | sk->sk_err_soft = -err; | 641 | sk->sk_err_soft = -err; |
642 | return err; | 642 | return err; |
643 | } | 643 | } |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 7a8a01369e5c..52449f7a1b71 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -407,6 +407,7 @@ out: | |||
407 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 407 | static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
408 | int type, int code, int offset, __be32 info) | 408 | int type, int code, int offset, __be32 info) |
409 | { | 409 | { |
410 | struct net *net = dev_net(skb->dev); | ||
410 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; | 411 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; |
411 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); | 412 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); |
412 | struct xfrm_state *x; | 413 | struct xfrm_state *x; |
@@ -415,7 +416,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
415 | type != ICMPV6_PKT_TOOBIG) | 416 | type != ICMPV6_PKT_TOOBIG) |
416 | return; | 417 | return; |
417 | 418 | ||
418 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); | 419 | x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6); |
419 | if (!x) | 420 | if (!x) |
420 | return; | 421 | return; |
421 | 422 | ||
@@ -509,9 +510,7 @@ static void ah6_destroy(struct xfrm_state *x) | |||
509 | return; | 510 | return; |
510 | 511 | ||
511 | kfree(ahp->work_icv); | 512 | kfree(ahp->work_icv); |
512 | ahp->work_icv = NULL; | ||
513 | crypto_free_hash(ahp->tfm); | 513 | crypto_free_hash(ahp->tfm); |
514 | ahp->tfm = NULL; | ||
515 | kfree(ahp); | 514 | kfree(ahp); |
516 | } | 515 | } |
517 | 516 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 410046a8cc91..e2bdc6d83a43 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -175,7 +175,8 @@ ipv4_connected: | |||
175 | if (final_p) | 175 | if (final_p) |
176 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 176 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
177 | 177 | ||
178 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 178 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
179 | if (err < 0) { | ||
179 | if (err == -EREMOTE) | 180 | if (err == -EREMOTE) |
180 | err = ip6_dst_blackhole(sk, &dst, &fl); | 181 | err = ip6_dst_blackhole(sk, &dst, &fl); |
181 | if (err < 0) | 182 | if (err < 0) |
@@ -661,6 +662,11 @@ int datagram_send_ctl(struct net *net, | |||
661 | switch (rthdr->type) { | 662 | switch (rthdr->type) { |
662 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 663 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
663 | case IPV6_SRCRT_TYPE_2: | 664 | case IPV6_SRCRT_TYPE_2: |
665 | if (rthdr->hdrlen != 2 || | ||
666 | rthdr->segments_left != 1) { | ||
667 | err = -EINVAL; | ||
668 | goto exit_f; | ||
669 | } | ||
664 | break; | 670 | break; |
665 | #endif | 671 | #endif |
666 | default: | 672 | default: |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index c02a6308defe..c2f250150db1 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -356,6 +356,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) | |||
356 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 356 | static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
357 | int type, int code, int offset, __be32 info) | 357 | int type, int code, int offset, __be32 info) |
358 | { | 358 | { |
359 | struct net *net = dev_net(skb->dev); | ||
359 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; | 360 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; |
360 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); | 361 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); |
361 | struct xfrm_state *x; | 362 | struct xfrm_state *x; |
@@ -364,7 +365,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
364 | type != ICMPV6_PKT_TOOBIG) | 365 | type != ICMPV6_PKT_TOOBIG) |
365 | return; | 366 | return; |
366 | 367 | ||
367 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); | 368 | x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); |
368 | if (!x) | 369 | if (!x) |
369 | return; | 370 | return; |
370 | printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", | 371 | printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index be351009fd03..4f433847d95f 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -233,7 +233,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct | |||
233 | icmp6h->icmp6_cksum = 0; | 233 | icmp6h->icmp6_cksum = 0; |
234 | 234 | ||
235 | if (skb_queue_len(&sk->sk_write_queue) == 1) { | 235 | if (skb_queue_len(&sk->sk_write_queue) == 1) { |
236 | skb->csum = csum_partial((char *)icmp6h, | 236 | skb->csum = csum_partial(icmp6h, |
237 | sizeof(struct icmp6hdr), skb->csum); | 237 | sizeof(struct icmp6hdr), skb->csum); |
238 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, | 238 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, |
239 | &fl->fl6_dst, | 239 | &fl->fl6_dst, |
@@ -246,7 +246,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct | |||
246 | tmp_csum = csum_add(tmp_csum, skb->csum); | 246 | tmp_csum = csum_add(tmp_csum, skb->csum); |
247 | } | 247 | } |
248 | 248 | ||
249 | tmp_csum = csum_partial((char *)icmp6h, | 249 | tmp_csum = csum_partial(icmp6h, |
250 | sizeof(struct icmp6hdr), tmp_csum); | 250 | sizeof(struct icmp6hdr), tmp_csum); |
251 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, | 251 | icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, |
252 | &fl->fl6_dst, | 252 | &fl->fl6_dst, |
@@ -427,7 +427,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
427 | /* No need to clone since we're just using its address. */ | 427 | /* No need to clone since we're just using its address. */ |
428 | dst2 = dst; | 428 | dst2 = dst; |
429 | 429 | ||
430 | err = xfrm_lookup(&dst, &fl, sk, 0); | 430 | err = xfrm_lookup(net, &dst, &fl, sk, 0); |
431 | switch (err) { | 431 | switch (err) { |
432 | case 0: | 432 | case 0: |
433 | if (dst != dst2) | 433 | if (dst != dst2) |
@@ -446,7 +446,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
446 | if (ip6_dst_lookup(sk, &dst2, &fl)) | 446 | if (ip6_dst_lookup(sk, &dst2, &fl)) |
447 | goto relookup_failed; | 447 | goto relookup_failed; |
448 | 448 | ||
449 | err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP); | 449 | err = xfrm_lookup(net, &dst2, &fl, sk, XFRM_LOOKUP_ICMP); |
450 | switch (err) { | 450 | switch (err) { |
451 | case 0: | 451 | case 0: |
452 | dst_release(dst); | 452 | dst_release(dst); |
@@ -552,7 +552,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
552 | err = ip6_dst_lookup(sk, &dst, &fl); | 552 | err = ip6_dst_lookup(sk, &dst, &fl); |
553 | if (err) | 553 | if (err) |
554 | goto out; | 554 | goto out; |
555 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 555 | if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) |
556 | goto out; | 556 | goto out; |
557 | 557 | ||
558 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 558 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 16d43f20b32f..3c3732d50c1a 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -219,7 +219,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
219 | if (final_p) | 219 | if (final_p) |
220 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 220 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
221 | 221 | ||
222 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 222 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) { |
223 | sk->sk_route_caps = 0; | 223 | sk->sk_route_caps = 0; |
224 | kfree_skb(skb); | 224 | kfree_skb(skb); |
225 | return err; | 225 | return err; |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 1646a5658255..8fe267feb81e 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -25,26 +25,30 @@ | |||
25 | void __inet6_hash(struct sock *sk) | 25 | void __inet6_hash(struct sock *sk) |
26 | { | 26 | { |
27 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; | 27 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; |
28 | struct hlist_head *list; | ||
29 | rwlock_t *lock; | ||
30 | 28 | ||
31 | WARN_ON(!sk_unhashed(sk)); | 29 | WARN_ON(!sk_unhashed(sk)); |
32 | 30 | ||
33 | if (sk->sk_state == TCP_LISTEN) { | 31 | if (sk->sk_state == TCP_LISTEN) { |
34 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | 32 | struct inet_listen_hashbucket *ilb; |
35 | lock = &hashinfo->lhash_lock; | 33 | |
36 | inet_listen_wlock(hashinfo); | 34 | ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; |
35 | spin_lock(&ilb->lock); | ||
36 | __sk_nulls_add_node_rcu(sk, &ilb->head); | ||
37 | spin_unlock(&ilb->lock); | ||
37 | } else { | 38 | } else { |
38 | unsigned int hash; | 39 | unsigned int hash; |
40 | struct hlist_nulls_head *list; | ||
41 | spinlock_t *lock; | ||
42 | |||
39 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | 43 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); |
40 | list = &inet_ehash_bucket(hashinfo, hash)->chain; | 44 | list = &inet_ehash_bucket(hashinfo, hash)->chain; |
41 | lock = inet_ehash_lockp(hashinfo, hash); | 45 | lock = inet_ehash_lockp(hashinfo, hash); |
42 | write_lock(lock); | 46 | spin_lock(lock); |
47 | __sk_nulls_add_node_rcu(sk, list); | ||
48 | spin_unlock(lock); | ||
43 | } | 49 | } |
44 | 50 | ||
45 | __sk_add_node(sk, list); | ||
46 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 51 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
47 | write_unlock(lock); | ||
48 | } | 52 | } |
49 | EXPORT_SYMBOL(__inet6_hash); | 53 | EXPORT_SYMBOL(__inet6_hash); |
50 | 54 | ||
@@ -63,77 +67,122 @@ struct sock *__inet6_lookup_established(struct net *net, | |||
63 | const int dif) | 67 | const int dif) |
64 | { | 68 | { |
65 | struct sock *sk; | 69 | struct sock *sk; |
66 | const struct hlist_node *node; | 70 | const struct hlist_nulls_node *node; |
67 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); | 71 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); |
68 | /* Optimize here for direct hit, only listening connections can | 72 | /* Optimize here for direct hit, only listening connections can |
69 | * have wildcards anyways. | 73 | * have wildcards anyways. |
70 | */ | 74 | */ |
71 | unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); | 75 | unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); |
72 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | 76 | unsigned int slot = hash & (hashinfo->ehash_size - 1); |
73 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | 77 | struct inet_ehash_bucket *head = &hashinfo->ehash[slot]; |
74 | 78 | ||
75 | prefetch(head->chain.first); | 79 | |
76 | read_lock(lock); | 80 | rcu_read_lock(); |
77 | sk_for_each(sk, node, &head->chain) { | 81 | begin: |
82 | sk_nulls_for_each_rcu(sk, node, &head->chain) { | ||
78 | /* For IPV6 do the cheaper port and family tests first. */ | 83 | /* For IPV6 do the cheaper port and family tests first. */ |
79 | if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) | 84 | if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { |
80 | goto hit; /* You sunk my battleship! */ | 85 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) |
86 | goto begintw; | ||
87 | if (!INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | ||
88 | sock_put(sk); | ||
89 | goto begin; | ||
90 | } | ||
91 | goto out; | ||
92 | } | ||
81 | } | 93 | } |
94 | if (get_nulls_value(node) != slot) | ||
95 | goto begin; | ||
96 | |||
97 | begintw: | ||
82 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | 98 | /* Must check for a TIME_WAIT'er before going to listener hash. */ |
83 | sk_for_each(sk, node, &head->twchain) { | 99 | sk_nulls_for_each_rcu(sk, node, &head->twchain) { |
84 | if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) | 100 | if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { |
85 | goto hit; | 101 | if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { |
102 | sk = NULL; | ||
103 | goto out; | ||
104 | } | ||
105 | if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) { | ||
106 | sock_put(sk); | ||
107 | goto begintw; | ||
108 | } | ||
109 | goto out; | ||
110 | } | ||
86 | } | 111 | } |
87 | read_unlock(lock); | 112 | if (get_nulls_value(node) != slot) |
88 | return NULL; | 113 | goto begintw; |
89 | 114 | sk = NULL; | |
90 | hit: | 115 | out: |
91 | sock_hold(sk); | 116 | rcu_read_unlock(); |
92 | read_unlock(lock); | ||
93 | return sk; | 117 | return sk; |
94 | } | 118 | } |
95 | EXPORT_SYMBOL(__inet6_lookup_established); | 119 | EXPORT_SYMBOL(__inet6_lookup_established); |
96 | 120 | ||
121 | static int inline compute_score(struct sock *sk, struct net *net, | ||
122 | const unsigned short hnum, | ||
123 | const struct in6_addr *daddr, | ||
124 | const int dif) | ||
125 | { | ||
126 | int score = -1; | ||
127 | |||
128 | if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && | ||
129 | sk->sk_family == PF_INET6) { | ||
130 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
131 | |||
132 | score = 1; | ||
133 | if (!ipv6_addr_any(&np->rcv_saddr)) { | ||
134 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | ||
135 | return -1; | ||
136 | score++; | ||
137 | } | ||
138 | if (sk->sk_bound_dev_if) { | ||
139 | if (sk->sk_bound_dev_if != dif) | ||
140 | return -1; | ||
141 | score++; | ||
142 | } | ||
143 | } | ||
144 | return score; | ||
145 | } | ||
146 | |||
97 | struct sock *inet6_lookup_listener(struct net *net, | 147 | struct sock *inet6_lookup_listener(struct net *net, |
98 | struct inet_hashinfo *hashinfo, const struct in6_addr *daddr, | 148 | struct inet_hashinfo *hashinfo, const struct in6_addr *daddr, |
99 | const unsigned short hnum, const int dif) | 149 | const unsigned short hnum, const int dif) |
100 | { | 150 | { |
101 | struct sock *sk; | 151 | struct sock *sk; |
102 | const struct hlist_node *node; | 152 | const struct hlist_nulls_node *node; |
103 | struct sock *result = NULL; | 153 | struct sock *result; |
104 | int score, hiscore = 0; | 154 | int score, hiscore; |
105 | 155 | unsigned int hash = inet_lhashfn(net, hnum); | |
106 | read_lock(&hashinfo->lhash_lock); | 156 | struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash]; |
107 | sk_for_each(sk, node, | 157 | |
108 | &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) { | 158 | rcu_read_lock(); |
109 | if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && | 159 | begin: |
110 | sk->sk_family == PF_INET6) { | 160 | result = NULL; |
111 | const struct ipv6_pinfo *np = inet6_sk(sk); | 161 | hiscore = -1; |
112 | 162 | sk_nulls_for_each(sk, node, &ilb->head) { | |
113 | score = 1; | 163 | score = compute_score(sk, net, hnum, daddr, dif); |
114 | if (!ipv6_addr_any(&np->rcv_saddr)) { | 164 | if (score > hiscore) { |
115 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | 165 | hiscore = score; |
116 | continue; | 166 | result = sk; |
117 | score++; | 167 | } |
118 | } | 168 | } |
119 | if (sk->sk_bound_dev_if) { | 169 | /* |
120 | if (sk->sk_bound_dev_if != dif) | 170 | * if the nulls value we got at the end of this lookup is |
121 | continue; | 171 | * not the expected one, we must restart lookup. |
122 | score++; | 172 | * We probably met an item that was moved to another chain. |
123 | } | 173 | */ |
124 | if (score == 3) { | 174 | if (get_nulls_value(node) != hash + LISTENING_NULLS_BASE) |
125 | result = sk; | 175 | goto begin; |
126 | break; | 176 | if (result) { |
127 | } | 177 | if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) |
128 | if (score > hiscore) { | 178 | result = NULL; |
129 | hiscore = score; | 179 | else if (unlikely(compute_score(result, net, hnum, daddr, |
130 | result = sk; | 180 | dif) < hiscore)) { |
131 | } | 181 | sock_put(result); |
182 | goto begin; | ||
132 | } | 183 | } |
133 | } | 184 | } |
134 | if (result) | 185 | rcu_read_unlock(); |
135 | sock_hold(result); | ||
136 | read_unlock(&hashinfo->lhash_lock); | ||
137 | return result; | 186 | return result; |
138 | } | 187 | } |
139 | 188 | ||
@@ -170,16 +219,15 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
170 | const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, | 219 | const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, |
171 | inet->dport); | 220 | inet->dport); |
172 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); | 221 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); |
173 | rwlock_t *lock = inet_ehash_lockp(hinfo, hash); | 222 | spinlock_t *lock = inet_ehash_lockp(hinfo, hash); |
174 | struct sock *sk2; | 223 | struct sock *sk2; |
175 | const struct hlist_node *node; | 224 | const struct hlist_nulls_node *node; |
176 | struct inet_timewait_sock *tw; | 225 | struct inet_timewait_sock *tw; |
177 | 226 | ||
178 | prefetch(head->chain.first); | 227 | spin_lock(lock); |
179 | write_lock(lock); | ||
180 | 228 | ||
181 | /* Check TIME-WAIT sockets first. */ | 229 | /* Check TIME-WAIT sockets first. */ |
182 | sk_for_each(sk2, node, &head->twchain) { | 230 | sk_nulls_for_each(sk2, node, &head->twchain) { |
183 | tw = inet_twsk(sk2); | 231 | tw = inet_twsk(sk2); |
184 | 232 | ||
185 | if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) { | 233 | if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) { |
@@ -192,7 +240,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, | |||
192 | tw = NULL; | 240 | tw = NULL; |
193 | 241 | ||
194 | /* And established part... */ | 242 | /* And established part... */ |
195 | sk_for_each(sk2, node, &head->chain) { | 243 | sk_nulls_for_each(sk2, node, &head->chain) { |
196 | if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) | 244 | if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) |
197 | goto not_unique; | 245 | goto not_unique; |
198 | } | 246 | } |
@@ -203,10 +251,10 @@ unique: | |||
203 | inet->num = lport; | 251 | inet->num = lport; |
204 | inet->sport = htons(lport); | 252 | inet->sport = htons(lport); |
205 | WARN_ON(!sk_unhashed(sk)); | 253 | WARN_ON(!sk_unhashed(sk)); |
206 | __sk_add_node(sk, &head->chain); | 254 | __sk_nulls_add_node_rcu(sk, &head->chain); |
207 | sk->sk_hash = hash; | 255 | sk->sk_hash = hash; |
256 | spin_unlock(lock); | ||
208 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 257 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
209 | write_unlock(lock); | ||
210 | 258 | ||
211 | if (twp != NULL) { | 259 | if (twp != NULL) { |
212 | *twp = tw; | 260 | *twp = tw; |
@@ -221,7 +269,7 @@ unique: | |||
221 | return 0; | 269 | return 0; |
222 | 270 | ||
223 | not_unique: | 271 | not_unique: |
224 | write_unlock(lock); | 272 | spin_unlock(lock); |
225 | return -EADDRNOTAVAIL; | 273 | return -EADDRNOTAVAIL; |
226 | } | 274 | } |
227 | 275 | ||
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 7927a8498d17..5656e8aa47d8 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -464,7 +464,7 @@ static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl, | |||
464 | 464 | ||
465 | int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) | 465 | int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) |
466 | { | 466 | { |
467 | int err; | 467 | int uninitialized_var(err); |
468 | struct net *net = sock_net(sk); | 468 | struct net *net = sock_net(sk); |
469 | struct ipv6_pinfo *np = inet6_sk(sk); | 469 | struct ipv6_pinfo *np = inet6_sk(sk); |
470 | struct in6_flowlabel_req freq; | 470 | struct in6_flowlabel_req freq; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 64ce3d33d9c6..58e2b0d93758 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -74,8 +74,8 @@ MODULE_LICENSE("GPL"); | |||
74 | (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ | 74 | (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ |
75 | (HASH_SIZE - 1)) | 75 | (HASH_SIZE - 1)) |
76 | 76 | ||
77 | static int ip6_fb_tnl_dev_init(struct net_device *dev); | 77 | static void ip6_fb_tnl_dev_init(struct net_device *dev); |
78 | static int ip6_tnl_dev_init(struct net_device *dev); | 78 | static void ip6_tnl_dev_init(struct net_device *dev); |
79 | static void ip6_tnl_dev_setup(struct net_device *dev); | 79 | static void ip6_tnl_dev_setup(struct net_device *dev); |
80 | 80 | ||
81 | static int ip6_tnl_net_id; | 81 | static int ip6_tnl_net_id; |
@@ -249,7 +249,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | t = netdev_priv(dev); | 251 | t = netdev_priv(dev); |
252 | dev->init = ip6_tnl_dev_init; | 252 | ip6_tnl_dev_init(dev); |
253 | t->parms = *p; | 253 | t->parms = *p; |
254 | 254 | ||
255 | if ((err = register_netdevice(dev)) < 0) | 255 | if ((err = register_netdevice(dev)) < 0) |
@@ -846,6 +846,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
846 | int encap_limit, | 846 | int encap_limit, |
847 | __u32 *pmtu) | 847 | __u32 *pmtu) |
848 | { | 848 | { |
849 | struct net *net = dev_net(dev); | ||
849 | struct ip6_tnl *t = netdev_priv(dev); | 850 | struct ip6_tnl *t = netdev_priv(dev); |
850 | struct net_device_stats *stats = &t->dev->stats; | 851 | struct net_device_stats *stats = &t->dev->stats; |
851 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); | 852 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); |
@@ -861,9 +862,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
861 | if ((dst = ip6_tnl_dst_check(t)) != NULL) | 862 | if ((dst = ip6_tnl_dst_check(t)) != NULL) |
862 | dst_hold(dst); | 863 | dst_hold(dst); |
863 | else { | 864 | else { |
864 | dst = ip6_route_output(dev_net(dev), NULL, fl); | 865 | dst = ip6_route_output(net, NULL, fl); |
865 | 866 | ||
866 | if (dst->error || xfrm_lookup(&dst, fl, NULL, 0) < 0) | 867 | if (dst->error || xfrm_lookup(net, &dst, fl, NULL, 0) < 0) |
867 | goto tx_err_link_failure; | 868 | goto tx_err_link_failure; |
868 | } | 869 | } |
869 | 870 | ||
@@ -1150,7 +1151,6 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1150 | * ip6_tnl_change - update the tunnel parameters | 1151 | * ip6_tnl_change - update the tunnel parameters |
1151 | * @t: tunnel to be changed | 1152 | * @t: tunnel to be changed |
1152 | * @p: tunnel configuration parameters | 1153 | * @p: tunnel configuration parameters |
1153 | * @active: != 0 if tunnel is ready for use | ||
1154 | * | 1154 | * |
1155 | * Description: | 1155 | * Description: |
1156 | * ip6_tnl_change() updates the tunnel parameters | 1156 | * ip6_tnl_change() updates the tunnel parameters |
@@ -1306,6 +1306,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1306 | return 0; | 1306 | return 0; |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | |||
1310 | static const struct net_device_ops ip6_tnl_netdev_ops = { | ||
1311 | .ndo_uninit = ip6_tnl_dev_uninit, | ||
1312 | .ndo_start_xmit = ip6_tnl_xmit, | ||
1313 | .ndo_do_ioctl = ip6_tnl_ioctl, | ||
1314 | .ndo_change_mtu = ip6_tnl_change_mtu, | ||
1315 | }; | ||
1316 | |||
1309 | /** | 1317 | /** |
1310 | * ip6_tnl_dev_setup - setup virtual tunnel device | 1318 | * ip6_tnl_dev_setup - setup virtual tunnel device |
1311 | * @dev: virtual device associated with tunnel | 1319 | * @dev: virtual device associated with tunnel |
@@ -1316,11 +1324,8 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1316 | 1324 | ||
1317 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1325 | static void ip6_tnl_dev_setup(struct net_device *dev) |
1318 | { | 1326 | { |
1319 | dev->uninit = ip6_tnl_dev_uninit; | 1327 | dev->netdev_ops = &ip6_tnl_netdev_ops; |
1320 | dev->destructor = free_netdev; | 1328 | dev->destructor = free_netdev; |
1321 | dev->hard_start_xmit = ip6_tnl_xmit; | ||
1322 | dev->do_ioctl = ip6_tnl_ioctl; | ||
1323 | dev->change_mtu = ip6_tnl_change_mtu; | ||
1324 | 1329 | ||
1325 | dev->type = ARPHRD_TUNNEL6; | 1330 | dev->type = ARPHRD_TUNNEL6; |
1326 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); | 1331 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); |
@@ -1349,13 +1354,11 @@ ip6_tnl_dev_init_gen(struct net_device *dev) | |||
1349 | * @dev: virtual device associated with tunnel | 1354 | * @dev: virtual device associated with tunnel |
1350 | **/ | 1355 | **/ |
1351 | 1356 | ||
1352 | static int | 1357 | static void ip6_tnl_dev_init(struct net_device *dev) |
1353 | ip6_tnl_dev_init(struct net_device *dev) | ||
1354 | { | 1358 | { |
1355 | struct ip6_tnl *t = netdev_priv(dev); | 1359 | struct ip6_tnl *t = netdev_priv(dev); |
1356 | ip6_tnl_dev_init_gen(dev); | 1360 | ip6_tnl_dev_init_gen(dev); |
1357 | ip6_tnl_link_config(t); | 1361 | ip6_tnl_link_config(t); |
1358 | return 0; | ||
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | /** | 1364 | /** |
@@ -1365,8 +1368,7 @@ ip6_tnl_dev_init(struct net_device *dev) | |||
1365 | * Return: 0 | 1368 | * Return: 0 |
1366 | **/ | 1369 | **/ |
1367 | 1370 | ||
1368 | static int | 1371 | static void ip6_fb_tnl_dev_init(struct net_device *dev) |
1369 | ip6_fb_tnl_dev_init(struct net_device *dev) | ||
1370 | { | 1372 | { |
1371 | struct ip6_tnl *t = netdev_priv(dev); | 1373 | struct ip6_tnl *t = netdev_priv(dev); |
1372 | struct net *net = dev_net(dev); | 1374 | struct net *net = dev_net(dev); |
@@ -1376,7 +1378,6 @@ ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1376 | t->parms.proto = IPPROTO_IPV6; | 1378 | t->parms.proto = IPPROTO_IPV6; |
1377 | dev_hold(dev); | 1379 | dev_hold(dev); |
1378 | ip6n->tnls_wc[0] = t; | 1380 | ip6n->tnls_wc[0] = t; |
1379 | return 0; | ||
1380 | } | 1381 | } |
1381 | 1382 | ||
1382 | static struct xfrm6_tunnel ip4ip6_handler = { | 1383 | static struct xfrm6_tunnel ip4ip6_handler = { |
@@ -1428,10 +1429,10 @@ static int ip6_tnl_init_net(struct net *net) | |||
1428 | 1429 | ||
1429 | if (!ip6n->fb_tnl_dev) | 1430 | if (!ip6n->fb_tnl_dev) |
1430 | goto err_alloc_dev; | 1431 | goto err_alloc_dev; |
1431 | |||
1432 | ip6n->fb_tnl_dev->init = ip6_fb_tnl_dev_init; | ||
1433 | dev_net_set(ip6n->fb_tnl_dev, net); | 1432 | dev_net_set(ip6n->fb_tnl_dev, net); |
1434 | 1433 | ||
1434 | ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); | ||
1435 | |||
1435 | err = register_netdev(ip6n->fb_tnl_dev); | 1436 | err = register_netdev(ip6n->fb_tnl_dev); |
1436 | if (err < 0) | 1437 | if (err < 0) |
1437 | goto err_register; | 1438 | goto err_register; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index c491fb98a5e3..dfba9fd0c248 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -224,7 +224,7 @@ static struct file_operations ip6mr_vif_fops = { | |||
224 | .open = ip6mr_vif_open, | 224 | .open = ip6mr_vif_open, |
225 | .read = seq_read, | 225 | .read = seq_read, |
226 | .llseek = seq_lseek, | 226 | .llseek = seq_lseek, |
227 | .release = seq_release, | 227 | .release = seq_release_private, |
228 | }; | 228 | }; |
229 | 229 | ||
230 | static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) | 230 | static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -337,7 +337,7 @@ static struct file_operations ip6mr_mfc_fops = { | |||
337 | .open = ipmr_mfc_open, | 337 | .open = ipmr_mfc_open, |
338 | .read = seq_read, | 338 | .read = seq_read, |
339 | .llseek = seq_lseek, | 339 | .llseek = seq_lseek, |
340 | .release = seq_release, | 340 | .release = seq_release_private, |
341 | }; | 341 | }; |
342 | #endif | 342 | #endif |
343 | 343 | ||
@@ -416,12 +416,16 @@ static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) | |||
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
419 | static const struct net_device_ops reg_vif_netdev_ops = { | ||
420 | .ndo_start_xmit = reg_vif_xmit, | ||
421 | }; | ||
422 | |||
419 | static void reg_vif_setup(struct net_device *dev) | 423 | static void reg_vif_setup(struct net_device *dev) |
420 | { | 424 | { |
421 | dev->type = ARPHRD_PIMREG; | 425 | dev->type = ARPHRD_PIMREG; |
422 | dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; | 426 | dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; |
423 | dev->flags = IFF_NOARP; | 427 | dev->flags = IFF_NOARP; |
424 | dev->hard_start_xmit = reg_vif_xmit; | 428 | dev->netdev_ops = ®_vif_netdev_ops; |
425 | dev->destructor = free_netdev; | 429 | dev->destructor = free_netdev; |
426 | } | 430 | } |
427 | 431 | ||
@@ -980,14 +984,15 @@ int __init ip6_mr_init(void) | |||
980 | goto proc_cache_fail; | 984 | goto proc_cache_fail; |
981 | #endif | 985 | #endif |
982 | return 0; | 986 | return 0; |
983 | reg_notif_fail: | ||
984 | kmem_cache_destroy(mrt_cachep); | ||
985 | #ifdef CONFIG_PROC_FS | 987 | #ifdef CONFIG_PROC_FS |
986 | proc_vif_fail: | ||
987 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
988 | proc_cache_fail: | 988 | proc_cache_fail: |
989 | proc_net_remove(&init_net, "ip6_mr_vif"); | 989 | proc_net_remove(&init_net, "ip6_mr_vif"); |
990 | proc_vif_fail: | ||
991 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
990 | #endif | 992 | #endif |
993 | reg_notif_fail: | ||
994 | del_timer(&ipmr_expire_timer); | ||
995 | kmem_cache_destroy(mrt_cachep); | ||
991 | return err; | 996 | return err; |
992 | } | 997 | } |
993 | 998 | ||
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index d4576a9c154f..3a0b3be7ece5 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -63,7 +63,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
63 | return; | 63 | return; |
64 | 64 | ||
65 | spi = htonl(ntohs(ipcomph->cpi)); | 65 | spi = htonl(ntohs(ipcomph->cpi)); |
66 | x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); | 66 | x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); |
67 | if (!x) | 67 | if (!x) |
68 | return; | 68 | return; |
69 | 69 | ||
@@ -76,7 +76,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) | |||
76 | { | 76 | { |
77 | struct xfrm_state *t = NULL; | 77 | struct xfrm_state *t = NULL; |
78 | 78 | ||
79 | t = xfrm_state_alloc(); | 79 | t = xfrm_state_alloc(&init_net); |
80 | if (!t) | 80 | if (!t) |
81 | goto out; | 81 | goto out; |
82 | 82 | ||
@@ -114,7 +114,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x) | |||
114 | 114 | ||
115 | spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); | 115 | spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); |
116 | if (spi) | 116 | if (spi) |
117 | t = xfrm_state_lookup((xfrm_address_t *)&x->id.daddr, | 117 | t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr, |
118 | spi, IPPROTO_IPV6, AF_INET6); | 118 | spi, IPPROTO_IPV6, AF_INET6); |
119 | if (!t) { | 119 | if (!t) { |
120 | t = ipcomp6_tunnel_create(x); | 120 | t = ipcomp6_tunnel_create(x); |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 4e5eac301f91..2aa294be0c79 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -366,11 +366,16 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
366 | } | 366 | } |
367 | 367 | ||
368 | /* routing header option needs extra check */ | 368 | /* routing header option needs extra check */ |
369 | retv = -EINVAL; | ||
369 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { | 370 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { |
370 | struct ipv6_rt_hdr *rthdr = opt->srcrt; | 371 | struct ipv6_rt_hdr *rthdr = opt->srcrt; |
371 | switch (rthdr->type) { | 372 | switch (rthdr->type) { |
372 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 373 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
373 | case IPV6_SRCRT_TYPE_2: | 374 | case IPV6_SRCRT_TYPE_2: |
375 | if (rthdr->hdrlen != 2 || | ||
376 | rthdr->segments_left != 1) | ||
377 | goto sticky_done; | ||
378 | |||
374 | break; | 379 | break; |
375 | #endif | 380 | #endif |
376 | default: | 381 | default: |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index a76199ecad23..0f3896032830 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1466,7 +1466,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1466 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1466 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1467 | skb->dev->ifindex); | 1467 | skb->dev->ifindex); |
1468 | 1468 | ||
1469 | err = xfrm_lookup(&skb->dst, &fl, NULL, 0); | 1469 | err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); |
1470 | if (err) | 1470 | if (err) |
1471 | goto err_out; | 1471 | goto err_out; |
1472 | 1472 | ||
@@ -1817,7 +1817,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1817 | 1817 | ||
1818 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, | 1818 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, |
1819 | IPPROTO_ICMPV6, | 1819 | IPPROTO_ICMPV6, |
1820 | csum_partial((__u8 *) hdr, len, 0)); | 1820 | csum_partial(hdr, len, 0)); |
1821 | 1821 | ||
1822 | idev = in6_dev_get(skb->dev); | 1822 | idev = in6_dev_get(skb->dev); |
1823 | 1823 | ||
@@ -1831,7 +1831,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1831 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 1831 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
1832 | skb->dev->ifindex); | 1832 | skb->dev->ifindex); |
1833 | 1833 | ||
1834 | err = xfrm_lookup(&skb->dst, &fl, NULL, 0); | 1834 | err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); |
1835 | if (err) | 1835 | if (err) |
1836 | goto err_out; | 1836 | goto err_out; |
1837 | 1837 | ||
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 31295c8f6196..f995e19c87a9 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c | |||
@@ -205,6 +205,7 @@ static inline int mip6_report_rl_allow(struct timeval *stamp, | |||
205 | 205 | ||
206 | static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl) | 206 | static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl) |
207 | { | 207 | { |
208 | struct net *net = xs_net(x); | ||
208 | struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; | 209 | struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; |
209 | struct ipv6_destopt_hao *hao = NULL; | 210 | struct ipv6_destopt_hao *hao = NULL; |
210 | struct xfrm_selector sel; | 211 | struct xfrm_selector sel; |
@@ -247,7 +248,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct | |||
247 | sel.sport_mask = htons(~0); | 248 | sel.sport_mask = htons(~0); |
248 | sel.ifindex = fl->oif; | 249 | sel.ifindex = fl->oif; |
249 | 250 | ||
250 | err = km_report(IPPROTO_DSTOPTS, &sel, | 251 | err = km_report(net, IPPROTO_DSTOPTS, &sel, |
251 | (hao ? (xfrm_address_t *)&hao->addr : NULL)); | 252 | (hao ? (xfrm_address_t *)&hao->addr : NULL)); |
252 | 253 | ||
253 | out: | 254 | out: |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2a6752dae09d..e4acc212345e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -437,38 +437,20 @@ static void pndisc_destructor(struct pneigh_entry *n) | |||
437 | ipv6_dev_mc_dec(dev, &maddr); | 437 | ipv6_dev_mc_dec(dev, &maddr); |
438 | } | 438 | } |
439 | 439 | ||
440 | /* | 440 | struct sk_buff *ndisc_build_skb(struct net_device *dev, |
441 | * Send a Neighbour Advertisement | 441 | const struct in6_addr *daddr, |
442 | */ | 442 | const struct in6_addr *saddr, |
443 | static void __ndisc_send(struct net_device *dev, | 443 | struct icmp6hdr *icmp6h, |
444 | struct neighbour *neigh, | 444 | const struct in6_addr *target, |
445 | const struct in6_addr *daddr, | 445 | int llinfo) |
446 | const struct in6_addr *saddr, | ||
447 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
448 | int llinfo) | ||
449 | { | 446 | { |
450 | struct flowi fl; | ||
451 | struct dst_entry *dst; | ||
452 | struct net *net = dev_net(dev); | 447 | struct net *net = dev_net(dev); |
453 | struct sock *sk = net->ipv6.ndisc_sk; | 448 | struct sock *sk = net->ipv6.ndisc_sk; |
454 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
455 | struct icmp6hdr *hdr; | 450 | struct icmp6hdr *hdr; |
456 | struct inet6_dev *idev; | ||
457 | int len; | 451 | int len; |
458 | int err; | 452 | int err; |
459 | u8 *opt, type; | 453 | u8 *opt; |
460 | |||
461 | type = icmp6h->icmp6_type; | ||
462 | |||
463 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
464 | |||
465 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
466 | if (!dst) | ||
467 | return; | ||
468 | |||
469 | err = xfrm_lookup(&dst, &fl, NULL, 0); | ||
470 | if (err < 0) | ||
471 | return; | ||
472 | 454 | ||
473 | if (!dev->addr_len) | 455 | if (!dev->addr_len) |
474 | llinfo = 0; | 456 | llinfo = 0; |
@@ -485,8 +467,7 @@ static void __ndisc_send(struct net_device *dev, | |||
485 | ND_PRINTK0(KERN_ERR | 467 | ND_PRINTK0(KERN_ERR |
486 | "ICMPv6 ND: %s() failed to allocate an skb.\n", | 468 | "ICMPv6 ND: %s() failed to allocate an skb.\n", |
487 | __func__); | 469 | __func__); |
488 | dst_release(dst); | 470 | return NULL; |
489 | return; | ||
490 | } | 471 | } |
491 | 472 | ||
492 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 473 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
@@ -510,9 +491,45 @@ static void __ndisc_send(struct net_device *dev, | |||
510 | 491 | ||
511 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, | 492 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, |
512 | IPPROTO_ICMPV6, | 493 | IPPROTO_ICMPV6, |
513 | csum_partial((__u8 *) hdr, | 494 | csum_partial(hdr, |
514 | len, 0)); | 495 | len, 0)); |
515 | 496 | ||
497 | return skb; | ||
498 | } | ||
499 | |||
500 | EXPORT_SYMBOL(ndisc_build_skb); | ||
501 | |||
502 | void ndisc_send_skb(struct sk_buff *skb, | ||
503 | struct net_device *dev, | ||
504 | struct neighbour *neigh, | ||
505 | const struct in6_addr *daddr, | ||
506 | const struct in6_addr *saddr, | ||
507 | struct icmp6hdr *icmp6h) | ||
508 | { | ||
509 | struct flowi fl; | ||
510 | struct dst_entry *dst; | ||
511 | struct net *net = dev_net(dev); | ||
512 | struct sock *sk = net->ipv6.ndisc_sk; | ||
513 | struct inet6_dev *idev; | ||
514 | int err; | ||
515 | u8 type; | ||
516 | |||
517 | type = icmp6h->icmp6_type; | ||
518 | |||
519 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
520 | |||
521 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
522 | if (!dst) { | ||
523 | kfree_skb(skb); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); | ||
528 | if (err < 0) { | ||
529 | kfree_skb(skb); | ||
530 | return; | ||
531 | } | ||
532 | |||
516 | skb->dst = dst; | 533 | skb->dst = dst; |
517 | 534 | ||
518 | idev = in6_dev_get(dst->dev); | 535 | idev = in6_dev_get(dst->dev); |
@@ -529,6 +546,27 @@ static void __ndisc_send(struct net_device *dev, | |||
529 | in6_dev_put(idev); | 546 | in6_dev_put(idev); |
530 | } | 547 | } |
531 | 548 | ||
549 | EXPORT_SYMBOL(ndisc_send_skb); | ||
550 | |||
551 | /* | ||
552 | * Send a Neighbour Discover packet | ||
553 | */ | ||
554 | static void __ndisc_send(struct net_device *dev, | ||
555 | struct neighbour *neigh, | ||
556 | const struct in6_addr *daddr, | ||
557 | const struct in6_addr *saddr, | ||
558 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
559 | int llinfo) | ||
560 | { | ||
561 | struct sk_buff *skb; | ||
562 | |||
563 | skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo); | ||
564 | if (!skb) | ||
565 | return; | ||
566 | |||
567 | ndisc_send_skb(skb, dev, neigh, daddr, saddr, icmp6h); | ||
568 | } | ||
569 | |||
532 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | 570 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, |
533 | const struct in6_addr *daddr, | 571 | const struct in6_addr *daddr, |
534 | const struct in6_addr *solicited_addr, | 572 | const struct in6_addr *solicited_addr, |
@@ -1486,7 +1524,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1486 | if (dst == NULL) | 1524 | if (dst == NULL) |
1487 | return; | 1525 | return; |
1488 | 1526 | ||
1489 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 1527 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); |
1490 | if (err) | 1528 | if (err) |
1491 | return; | 1529 | return; |
1492 | 1530 | ||
@@ -1574,7 +1612,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1574 | 1612 | ||
1575 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, | 1613 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, |
1576 | len, IPPROTO_ICMPV6, | 1614 | len, IPPROTO_ICMPV6, |
1577 | csum_partial((u8 *) icmph, len, 0)); | 1615 | csum_partial(icmph, len, 0)); |
1578 | 1616 | ||
1579 | buff->dst = dst; | 1617 | buff->dst = dst; |
1580 | idev = in6_dev_get(dst->dev); | 1618 | idev = in6_dev_get(dst->dev); |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 0b88c5632793..834cea69fb53 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -29,7 +29,7 @@ int ip6_route_me_harder(struct sk_buff *skb) | |||
29 | #ifdef CONFIG_XFRM | 29 | #ifdef CONFIG_XFRM |
30 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | 30 | if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && |
31 | xfrm_decode_session(skb, &fl, AF_INET6) == 0) | 31 | xfrm_decode_session(skb, &fl, AF_INET6) == 0) |
32 | if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0)) | 32 | if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0)) |
33 | return -1; | 33 | return -1; |
34 | #endif | 34 | #endif |
35 | 35 | ||
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 0981b4ccb8b1..5a2d0a41694a 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -97,7 +97,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
97 | dst = ip6_route_output(net, NULL, &fl); | 97 | dst = ip6_route_output(net, NULL, &fl); |
98 | if (dst == NULL) | 98 | if (dst == NULL) |
99 | return; | 99 | return; |
100 | if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) | 100 | if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0)) |
101 | return; | 101 | return; |
102 | 102 | ||
103 | hh_len = (dst->dev->hard_header_len + 15)&~15; | 103 | hh_len = (dst->dev->hard_header_len + 15)&~15; |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 07f0b76e7427..97c17fdd6f75 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -132,7 +132,7 @@ static struct snmp_mib snmp6_udplite6_list[] = { | |||
132 | 132 | ||
133 | static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) | 133 | static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) |
134 | { | 134 | { |
135 | static char name[32]; | 135 | char name[32]; |
136 | int i; | 136 | int i; |
137 | 137 | ||
138 | /* print by name -- deprecated items */ | 138 | /* print by name -- deprecated items */ |
@@ -144,7 +144,7 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) | |||
144 | p = icmp6type2name[icmptype]; | 144 | p = icmp6type2name[icmptype]; |
145 | if (!p) /* don't print un-named types here */ | 145 | if (!p) /* don't print un-named types here */ |
146 | continue; | 146 | continue; |
147 | (void) snprintf(name, sizeof(name)-1, "Icmp6%s%s", | 147 | snprintf(name, sizeof(name), "Icmp6%s%s", |
148 | i & 0x100 ? "Out" : "In", p); | 148 | i & 0x100 ? "Out" : "In", p); |
149 | seq_printf(seq, "%-32s\t%lu\n", name, | 149 | seq_printf(seq, "%-32s\t%lu\n", name, |
150 | snmp_fold_field(mib, i)); | 150 | snmp_fold_field(mib, i)); |
@@ -157,7 +157,7 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) | |||
157 | val = snmp_fold_field(mib, i); | 157 | val = snmp_fold_field(mib, i); |
158 | if (!val) | 158 | if (!val) |
159 | continue; | 159 | continue; |
160 | (void) snprintf(name, sizeof(name)-1, "Icmp6%sType%u", | 160 | snprintf(name, sizeof(name), "Icmp6%sType%u", |
161 | i & 0x100 ? "Out" : "In", i & 0xff); | 161 | i & 0x100 ? "Out" : "In", i & 0xff); |
162 | seq_printf(seq, "%-32s\t%lu\n", name, val); | 162 | seq_printf(seq, "%-32s\t%lu\n", name, val); |
163 | } | 163 | } |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 2ba04d41dc25..61f6827e5906 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -860,7 +860,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
860 | if (final_p) | 860 | if (final_p) |
861 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 861 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
862 | 862 | ||
863 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 863 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
864 | if (err < 0) { | ||
864 | if (err == -EREMOTE) | 865 | if (err == -EREMOTE) |
865 | err = ip6_dst_blackhole(sk, &dst, &fl); | 866 | err = ip6_dst_blackhole(sk, &dst, &fl); |
866 | if (err < 0) | 867 | if (err < 0) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4d40dc214b2d..9da1ece466a2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -108,7 +108,6 @@ static struct dst_ops ip6_dst_ops_template = { | |||
108 | .link_failure = ip6_link_failure, | 108 | .link_failure = ip6_link_failure, |
109 | .update_pmtu = ip6_rt_update_pmtu, | 109 | .update_pmtu = ip6_rt_update_pmtu, |
110 | .local_out = __ip6_local_out, | 110 | .local_out = __ip6_local_out, |
111 | .entry_size = sizeof(struct rt6_info), | ||
112 | .entries = ATOMIC_INIT(0), | 111 | .entries = ATOMIC_INIT(0), |
113 | }; | 112 | }; |
114 | 113 | ||
@@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
122 | .destroy = ip6_dst_destroy, | 121 | .destroy = ip6_dst_destroy, |
123 | .check = ip6_dst_check, | 122 | .check = ip6_dst_check, |
124 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 123 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
125 | .entry_size = sizeof(struct rt6_info), | ||
126 | .entries = ATOMIC_INIT(0), | 124 | .entries = ATOMIC_INIT(0), |
127 | }; | 125 | }; |
128 | 126 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b7a50e968506..d3467e563f02 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -62,8 +62,8 @@ | |||
62 | #define HASH_SIZE 16 | 62 | #define HASH_SIZE 16 |
63 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) | 63 | #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
64 | 64 | ||
65 | static int ipip6_fb_tunnel_init(struct net_device *dev); | 65 | static void ipip6_fb_tunnel_init(struct net_device *dev); |
66 | static int ipip6_tunnel_init(struct net_device *dev); | 66 | static void ipip6_tunnel_init(struct net_device *dev); |
67 | static void ipip6_tunnel_setup(struct net_device *dev); | 67 | static void ipip6_tunnel_setup(struct net_device *dev); |
68 | 68 | ||
69 | static int sit_net_id; | 69 | static int sit_net_id; |
@@ -188,7 +188,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | nt = netdev_priv(dev); | 190 | nt = netdev_priv(dev); |
191 | dev->init = ipip6_tunnel_init; | 191 | ipip6_tunnel_init(dev); |
192 | |||
192 | nt->parms = *parms; | 193 | nt->parms = *parms; |
193 | 194 | ||
194 | if (parms->i_flags & SIT_ISATAP) | 195 | if (parms->i_flags & SIT_ISATAP) |
@@ -926,13 +927,17 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) | |||
926 | return 0; | 927 | return 0; |
927 | } | 928 | } |
928 | 929 | ||
930 | static const struct net_device_ops ipip6_netdev_ops = { | ||
931 | .ndo_uninit = ipip6_tunnel_uninit, | ||
932 | .ndo_start_xmit = ipip6_tunnel_xmit, | ||
933 | .ndo_do_ioctl = ipip6_tunnel_ioctl, | ||
934 | .ndo_change_mtu = ipip6_tunnel_change_mtu, | ||
935 | }; | ||
936 | |||
929 | static void ipip6_tunnel_setup(struct net_device *dev) | 937 | static void ipip6_tunnel_setup(struct net_device *dev) |
930 | { | 938 | { |
931 | dev->uninit = ipip6_tunnel_uninit; | 939 | dev->netdev_ops = &ipip6_netdev_ops; |
932 | dev->destructor = free_netdev; | 940 | dev->destructor = free_netdev; |
933 | dev->hard_start_xmit = ipip6_tunnel_xmit; | ||
934 | dev->do_ioctl = ipip6_tunnel_ioctl; | ||
935 | dev->change_mtu = ipip6_tunnel_change_mtu; | ||
936 | 941 | ||
937 | dev->type = ARPHRD_SIT; | 942 | dev->type = ARPHRD_SIT; |
938 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); | 943 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); |
@@ -943,11 +948,9 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
943 | dev->features |= NETIF_F_NETNS_LOCAL; | 948 | dev->features |= NETIF_F_NETNS_LOCAL; |
944 | } | 949 | } |
945 | 950 | ||
946 | static int ipip6_tunnel_init(struct net_device *dev) | 951 | static void ipip6_tunnel_init(struct net_device *dev) |
947 | { | 952 | { |
948 | struct ip_tunnel *tunnel; | 953 | struct ip_tunnel *tunnel = netdev_priv(dev); |
949 | |||
950 | tunnel = netdev_priv(dev); | ||
951 | 954 | ||
952 | tunnel->dev = dev; | 955 | tunnel->dev = dev; |
953 | strcpy(tunnel->parms.name, dev->name); | 956 | strcpy(tunnel->parms.name, dev->name); |
@@ -956,11 +959,9 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
956 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); | 959 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
957 | 960 | ||
958 | ipip6_tunnel_bind_dev(dev); | 961 | ipip6_tunnel_bind_dev(dev); |
959 | |||
960 | return 0; | ||
961 | } | 962 | } |
962 | 963 | ||
963 | static int ipip6_fb_tunnel_init(struct net_device *dev) | 964 | static void ipip6_fb_tunnel_init(struct net_device *dev) |
964 | { | 965 | { |
965 | struct ip_tunnel *tunnel = netdev_priv(dev); | 966 | struct ip_tunnel *tunnel = netdev_priv(dev); |
966 | struct iphdr *iph = &tunnel->parms.iph; | 967 | struct iphdr *iph = &tunnel->parms.iph; |
@@ -977,7 +978,6 @@ static int ipip6_fb_tunnel_init(struct net_device *dev) | |||
977 | 978 | ||
978 | dev_hold(dev); | 979 | dev_hold(dev); |
979 | sitn->tunnels_wc[0] = tunnel; | 980 | sitn->tunnels_wc[0] = tunnel; |
980 | return 0; | ||
981 | } | 981 | } |
982 | 982 | ||
983 | static struct xfrm_tunnel sit_handler = { | 983 | static struct xfrm_tunnel sit_handler = { |
@@ -1025,16 +1025,17 @@ static int sit_init_net(struct net *net) | |||
1025 | err = -ENOMEM; | 1025 | err = -ENOMEM; |
1026 | goto err_alloc_dev; | 1026 | goto err_alloc_dev; |
1027 | } | 1027 | } |
1028 | |||
1029 | sitn->fb_tunnel_dev->init = ipip6_fb_tunnel_init; | ||
1030 | dev_net_set(sitn->fb_tunnel_dev, net); | 1028 | dev_net_set(sitn->fb_tunnel_dev, net); |
1031 | 1029 | ||
1030 | ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); | ||
1031 | |||
1032 | if ((err = register_netdev(sitn->fb_tunnel_dev))) | 1032 | if ((err = register_netdev(sitn->fb_tunnel_dev))) |
1033 | goto err_reg_dev; | 1033 | goto err_reg_dev; |
1034 | 1034 | ||
1035 | return 0; | 1035 | return 0; |
1036 | 1036 | ||
1037 | err_reg_dev: | 1037 | err_reg_dev: |
1038 | dev_put(sitn->fb_tunnel_dev); | ||
1038 | free_netdev(sitn->fb_tunnel_dev); | 1039 | free_netdev(sitn->fb_tunnel_dev); |
1039 | err_alloc_dev: | 1040 | err_alloc_dev: |
1040 | /* nothing */ | 1041 | /* nothing */ |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 676c80b5b14b..711175e0571f 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -259,7 +259,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
259 | 259 | ||
260 | if (final_p) | 260 | if (final_p) |
261 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 261 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
262 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 262 | if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
263 | goto out_free; | 263 | goto out_free; |
264 | } | 264 | } |
265 | 265 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 984276463a8d..8702b06cb60a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -260,7 +260,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
260 | if (final_p) | 260 | if (final_p) |
261 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 261 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
262 | 262 | ||
263 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 263 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
264 | if (err < 0) { | ||
264 | if (err == -EREMOTE) | 265 | if (err == -EREMOTE) |
265 | err = ip6_dst_blackhole(sk, &dst, &fl); | 266 | err = ip6_dst_blackhole(sk, &dst, &fl); |
266 | if (err < 0) | 267 | if (err < 0) |
@@ -390,7 +391,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
390 | goto out; | 391 | goto out; |
391 | } | 392 | } |
392 | 393 | ||
393 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 394 | if ((err = xfrm_lookup(net, &dst, &fl, sk, 0)) < 0) { |
394 | sk->sk_err_soft = -err; | 395 | sk->sk_err_soft = -err; |
395 | goto out; | 396 | goto out; |
396 | } | 397 | } |
@@ -492,7 +493,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) | |||
492 | goto done; | 493 | goto done; |
493 | if (final_p) | 494 | if (final_p) |
494 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 495 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
495 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 496 | if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
496 | goto done; | 497 | goto done; |
497 | 498 | ||
498 | skb = tcp_make_synack(sk, dst, req); | 499 | skb = tcp_make_synack(sk, dst, req); |
@@ -501,7 +502,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) | |||
501 | 502 | ||
502 | th->check = tcp_v6_check(th, skb->len, | 503 | th->check = tcp_v6_check(th, skb->len, |
503 | &treq->loc_addr, &treq->rmt_addr, | 504 | &treq->loc_addr, &treq->rmt_addr, |
504 | csum_partial((char *)th, skb->len, skb->csum)); | 505 | csum_partial(th, skb->len, skb->csum)); |
505 | 506 | ||
506 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); | 507 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); |
507 | err = ip6_xmit(sk, skb, &fl, opt, 0); | 508 | err = ip6_xmit(sk, skb, &fl, opt, 0); |
@@ -915,7 +916,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | |||
915 | skb->csum_offset = offsetof(struct tcphdr, check); | 916 | skb->csum_offset = offsetof(struct tcphdr, check); |
916 | } else { | 917 | } else { |
917 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, | 918 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, |
918 | csum_partial((char *)th, th->doff<<2, | 919 | csum_partial(th, th->doff<<2, |
919 | skb->csum)); | 920 | skb->csum)); |
920 | } | 921 | } |
921 | } | 922 | } |
@@ -997,7 +998,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
997 | } | 998 | } |
998 | #endif | 999 | #endif |
999 | 1000 | ||
1000 | buff->csum = csum_partial((char *)t1, tot_len, 0); | 1001 | buff->csum = csum_partial(t1, tot_len, 0); |
1001 | 1002 | ||
1002 | memset(&fl, 0, sizeof(fl)); | 1003 | memset(&fl, 0, sizeof(fl)); |
1003 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | 1004 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); |
@@ -1018,7 +1019,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1018 | * namespace | 1019 | * namespace |
1019 | */ | 1020 | */ |
1020 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { | 1021 | if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { |
1021 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | 1022 | if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) { |
1022 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | 1023 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); |
1023 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1024 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1024 | if (rst) | 1025 | if (rst) |
@@ -1316,7 +1317,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1316 | if (final_p) | 1317 | if (final_p) |
1317 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 1318 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
1318 | 1319 | ||
1319 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 1320 | if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) |
1320 | goto out; | 1321 | goto out; |
1321 | } | 1322 | } |
1322 | 1323 | ||
@@ -1829,7 +1830,7 @@ static int tcp_v6_init_sock(struct sock *sk) | |||
1829 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; | 1830 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; |
1830 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; | 1831 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |
1831 | 1832 | ||
1832 | atomic_inc(&tcp_sockets_allocated); | 1833 | percpu_counter_inc(&tcp_sockets_allocated); |
1833 | 1834 | ||
1834 | return 0; | 1835 | return 0; |
1835 | } | 1836 | } |
@@ -2043,6 +2044,7 @@ struct proto tcpv6_prot = { | |||
2043 | .sysctl_rmem = sysctl_tcp_rmem, | 2044 | .sysctl_rmem = sysctl_tcp_rmem, |
2044 | .max_header = MAX_TCP_HEADER, | 2045 | .max_header = MAX_TCP_HEADER, |
2045 | .obj_size = sizeof(struct tcp6_sock), | 2046 | .obj_size = sizeof(struct tcp6_sock), |
2047 | .slab_flags = SLAB_DESTROY_BY_RCU, | ||
2046 | .twsk_prot = &tcp6_timewait_sock_ops, | 2048 | .twsk_prot = &tcp6_timewait_sock_ops, |
2047 | .rsk_prot = &tcp6_request_sock_ops, | 2049 | .rsk_prot = &tcp6_request_sock_ops, |
2048 | .h.hashinfo = &tcp_hashinfo, | 2050 | .h.hashinfo = &tcp_hashinfo, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 32d914db6c4f..38390dd19636 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -98,7 +98,7 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
98 | int dif, struct udp_table *udptable) | 98 | int dif, struct udp_table *udptable) |
99 | { | 99 | { |
100 | struct sock *sk, *result; | 100 | struct sock *sk, *result; |
101 | struct hlist_node *node, *next; | 101 | struct hlist_nulls_node *node; |
102 | unsigned short hnum = ntohs(dport); | 102 | unsigned short hnum = ntohs(dport); |
103 | unsigned int hash = udp_hashfn(net, hnum); | 103 | unsigned int hash = udp_hashfn(net, hnum); |
104 | struct udp_hslot *hslot = &udptable->hash[hash]; | 104 | struct udp_hslot *hslot = &udptable->hash[hash]; |
@@ -108,19 +108,21 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
108 | begin: | 108 | begin: |
109 | result = NULL; | 109 | result = NULL; |
110 | badness = -1; | 110 | badness = -1; |
111 | sk_for_each_rcu_safenext(sk, node, &hslot->head, next) { | 111 | sk_nulls_for_each_rcu(sk, node, &hslot->head) { |
112 | /* | ||
113 | * lockless reader, and SLAB_DESTROY_BY_RCU items: | ||
114 | * We must check this item was not moved to another chain | ||
115 | */ | ||
116 | if (udp_hashfn(net, sk->sk_hash) != hash) | ||
117 | goto begin; | ||
118 | score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif); | 112 | score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif); |
119 | if (score > badness) { | 113 | if (score > badness) { |
120 | result = sk; | 114 | result = sk; |
121 | badness = score; | 115 | badness = score; |
122 | } | 116 | } |
123 | } | 117 | } |
118 | /* | ||
119 | * if the nulls value we got at the end of this lookup is | ||
120 | * not the expected one, we must restart lookup. | ||
121 | * We probably met an item that was moved to another chain. | ||
122 | */ | ||
123 | if (get_nulls_value(node) != hash) | ||
124 | goto begin; | ||
125 | |||
124 | if (result) { | 126 | if (result) { |
125 | if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) | 127 | if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) |
126 | result = NULL; | 128 | result = NULL; |
@@ -165,6 +167,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
165 | int peeked; | 167 | int peeked; |
166 | int err; | 168 | int err; |
167 | int is_udplite = IS_UDPLITE(sk); | 169 | int is_udplite = IS_UDPLITE(sk); |
170 | int is_udp4; | ||
168 | 171 | ||
169 | if (addr_len) | 172 | if (addr_len) |
170 | *addr_len=sizeof(struct sockaddr_in6); | 173 | *addr_len=sizeof(struct sockaddr_in6); |
@@ -185,6 +188,8 @@ try_again: | |||
185 | else if (copied < ulen) | 188 | else if (copied < ulen) |
186 | msg->msg_flags |= MSG_TRUNC; | 189 | msg->msg_flags |= MSG_TRUNC; |
187 | 190 | ||
191 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); | ||
192 | |||
188 | /* | 193 | /* |
189 | * If checksum is needed at all, try to do it while copying the | 194 | * If checksum is needed at all, try to do it while copying the |
190 | * data. If the data is truncated, or if we only want a partial | 195 | * data. If the data is truncated, or if we only want a partial |
@@ -207,9 +212,14 @@ try_again: | |||
207 | if (err) | 212 | if (err) |
208 | goto out_free; | 213 | goto out_free; |
209 | 214 | ||
210 | if (!peeked) | 215 | if (!peeked) { |
211 | UDP6_INC_STATS_USER(sock_net(sk), | 216 | if (is_udp4) |
212 | UDP_MIB_INDATAGRAMS, is_udplite); | 217 | UDP_INC_STATS_USER(sock_net(sk), |
218 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
219 | else | ||
220 | UDP6_INC_STATS_USER(sock_net(sk), | ||
221 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
222 | } | ||
213 | 223 | ||
214 | sock_recv_timestamp(msg, sk, skb); | 224 | sock_recv_timestamp(msg, sk, skb); |
215 | 225 | ||
@@ -223,7 +233,7 @@ try_again: | |||
223 | sin6->sin6_flowinfo = 0; | 233 | sin6->sin6_flowinfo = 0; |
224 | sin6->sin6_scope_id = 0; | 234 | sin6->sin6_scope_id = 0; |
225 | 235 | ||
226 | if (skb->protocol == htons(ETH_P_IP)) | 236 | if (is_udp4) |
227 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, | 237 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, |
228 | htonl(0xffff), ip_hdr(skb)->saddr); | 238 | htonl(0xffff), ip_hdr(skb)->saddr); |
229 | else { | 239 | else { |
@@ -234,7 +244,7 @@ try_again: | |||
234 | } | 244 | } |
235 | 245 | ||
236 | } | 246 | } |
237 | if (skb->protocol == htons(ETH_P_IP)) { | 247 | if (is_udp4) { |
238 | if (inet->cmsg_flags) | 248 | if (inet->cmsg_flags) |
239 | ip_cmsg_recv(msg, skb); | 249 | ip_cmsg_recv(msg, skb); |
240 | } else { | 250 | } else { |
@@ -255,8 +265,14 @@ out: | |||
255 | 265 | ||
256 | csum_copy_err: | 266 | csum_copy_err: |
257 | lock_sock(sk); | 267 | lock_sock(sk); |
258 | if (!skb_kill_datagram(sk, skb, flags)) | 268 | if (!skb_kill_datagram(sk, skb, flags)) { |
259 | UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 269 | if (is_udp4) |
270 | UDP_INC_STATS_USER(sock_net(sk), | ||
271 | UDP_MIB_INERRORS, is_udplite); | ||
272 | else | ||
273 | UDP6_INC_STATS_USER(sock_net(sk), | ||
274 | UDP_MIB_INERRORS, is_udplite); | ||
275 | } | ||
260 | release_sock(sk); | 276 | release_sock(sk); |
261 | 277 | ||
262 | if (flags & MSG_DONTWAIT) | 278 | if (flags & MSG_DONTWAIT) |
@@ -355,19 +371,19 @@ drop: | |||
355 | return -1; | 371 | return -1; |
356 | } | 372 | } |
357 | 373 | ||
358 | static struct sock *udp_v6_mcast_next(struct sock *sk, | 374 | static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, |
359 | __be16 loc_port, struct in6_addr *loc_addr, | 375 | __be16 loc_port, struct in6_addr *loc_addr, |
360 | __be16 rmt_port, struct in6_addr *rmt_addr, | 376 | __be16 rmt_port, struct in6_addr *rmt_addr, |
361 | int dif) | 377 | int dif) |
362 | { | 378 | { |
363 | struct hlist_node *node; | 379 | struct hlist_nulls_node *node; |
364 | struct sock *s = sk; | 380 | struct sock *s = sk; |
365 | unsigned short num = ntohs(loc_port); | 381 | unsigned short num = ntohs(loc_port); |
366 | 382 | ||
367 | sk_for_each_from(s, node) { | 383 | sk_nulls_for_each_from(s, node) { |
368 | struct inet_sock *inet = inet_sk(s); | 384 | struct inet_sock *inet = inet_sk(s); |
369 | 385 | ||
370 | if (sock_net(s) != sock_net(sk)) | 386 | if (!net_eq(sock_net(s), net)) |
371 | continue; | 387 | continue; |
372 | 388 | ||
373 | if (s->sk_hash == num && s->sk_family == PF_INET6) { | 389 | if (s->sk_hash == num && s->sk_family == PF_INET6) { |
@@ -409,16 +425,16 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
409 | int dif; | 425 | int dif; |
410 | 426 | ||
411 | spin_lock(&hslot->lock); | 427 | spin_lock(&hslot->lock); |
412 | sk = sk_head(&hslot->head); | 428 | sk = sk_nulls_head(&hslot->head); |
413 | dif = inet6_iif(skb); | 429 | dif = inet6_iif(skb); |
414 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 430 | sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); |
415 | if (!sk) { | 431 | if (!sk) { |
416 | kfree_skb(skb); | 432 | kfree_skb(skb); |
417 | goto out; | 433 | goto out; |
418 | } | 434 | } |
419 | 435 | ||
420 | sk2 = sk; | 436 | sk2 = sk; |
421 | while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, | 437 | while ((sk2 = udp_v6_mcast_next(net, sk_nulls_next(sk2), uh->dest, daddr, |
422 | uh->source, saddr, dif))) { | 438 | uh->source, saddr, dif))) { |
423 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 439 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
424 | if (buff) { | 440 | if (buff) { |
@@ -833,7 +849,8 @@ do_udp_sendmsg: | |||
833 | if (final_p) | 849 | if (final_p) |
834 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 850 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
835 | 851 | ||
836 | if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) { | 852 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); |
853 | if (err < 0) { | ||
837 | if (err == -EREMOTE) | 854 | if (err == -EREMOTE) |
838 | err = ip6_dst_blackhole(sk, &dst, &fl); | 855 | err = ip6_dst_blackhole(sk, &dst, &fl); |
839 | if (err < 0) | 856 | if (err < 0) |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index a71c7ddcb41e..9084582d236b 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(xfrm6_rcv); | |||
58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | 58 | int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, |
59 | xfrm_address_t *saddr, u8 proto) | 59 | xfrm_address_t *saddr, u8 proto) |
60 | { | 60 | { |
61 | struct net *net = dev_net(skb->dev); | ||
61 | struct xfrm_state *x = NULL; | 62 | struct xfrm_state *x = NULL; |
62 | int i = 0; | 63 | int i = 0; |
63 | 64 | ||
@@ -67,7 +68,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
67 | 68 | ||
68 | sp = secpath_dup(skb->sp); | 69 | sp = secpath_dup(skb->sp); |
69 | if (!sp) { | 70 | if (!sp) { |
70 | XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); | 71 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR); |
71 | goto drop; | 72 | goto drop; |
72 | } | 73 | } |
73 | if (skb->sp) | 74 | if (skb->sp) |
@@ -76,7 +77,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
76 | } | 77 | } |
77 | 78 | ||
78 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { | 79 | if (1 + skb->sp->len == XFRM_MAX_DEPTH) { |
79 | XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); | 80 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); |
80 | goto drop; | 81 | goto drop; |
81 | } | 82 | } |
82 | 83 | ||
@@ -100,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
100 | break; | 101 | break; |
101 | } | 102 | } |
102 | 103 | ||
103 | x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6); | 104 | x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6); |
104 | if (!x) | 105 | if (!x) |
105 | continue; | 106 | continue; |
106 | 107 | ||
@@ -122,7 +123,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | |||
122 | } | 123 | } |
123 | 124 | ||
124 | if (!x) { | 125 | if (!x) { |
125 | XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); | 126 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); |
126 | xfrm_audit_state_notfound_simple(skb, AF_INET6); | 127 | xfrm_audit_state_notfound_simple(skb, AF_INET6); |
127 | goto drop; | 128 | goto drop; |
128 | } | 129 | } |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 604bc0a96c05..97ab068e8ccc 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -27,7 +27,8 @@ | |||
27 | static struct dst_ops xfrm6_dst_ops; | 27 | static struct dst_ops xfrm6_dst_ops; |
28 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; | 28 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; |
29 | 29 | ||
30 | static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | 30 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, |
31 | xfrm_address_t *saddr, | ||
31 | xfrm_address_t *daddr) | 32 | xfrm_address_t *daddr) |
32 | { | 33 | { |
33 | struct flowi fl = {}; | 34 | struct flowi fl = {}; |
@@ -38,7 +39,7 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
38 | if (saddr) | 39 | if (saddr) |
39 | memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src)); | 40 | memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src)); |
40 | 41 | ||
41 | dst = ip6_route_output(&init_net, NULL, &fl); | 42 | dst = ip6_route_output(net, NULL, &fl); |
42 | 43 | ||
43 | err = dst->error; | 44 | err = dst->error; |
44 | if (dst->error) { | 45 | if (dst->error) { |
@@ -49,12 +50,13 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
49 | return dst; | 50 | return dst; |
50 | } | 51 | } |
51 | 52 | ||
52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) | 53 | static int xfrm6_get_saddr(struct net *net, |
54 | xfrm_address_t *saddr, xfrm_address_t *daddr) | ||
53 | { | 55 | { |
54 | struct dst_entry *dst; | 56 | struct dst_entry *dst; |
55 | struct net_device *dev; | 57 | struct net_device *dev; |
56 | 58 | ||
57 | dst = xfrm6_dst_lookup(0, NULL, daddr); | 59 | dst = xfrm6_dst_lookup(net, 0, NULL, daddr); |
58 | if (IS_ERR(dst)) | 60 | if (IS_ERR(dst)) |
59 | return -EHOSTUNREACH; | 61 | return -EHOSTUNREACH; |
60 | 62 | ||
@@ -220,7 +222,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
220 | 222 | ||
221 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) | 223 | static inline int xfrm6_garbage_collect(struct dst_ops *ops) |
222 | { | 224 | { |
223 | xfrm6_policy_afinfo.garbage_collect(); | 225 | xfrm6_policy_afinfo.garbage_collect(&init_net); |
224 | return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); | 226 | return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2); |
225 | } | 227 | } |
226 | 228 | ||
@@ -277,7 +279,6 @@ static struct dst_ops xfrm6_dst_ops = { | |||
277 | .ifdown = xfrm6_dst_ifdown, | 279 | .ifdown = xfrm6_dst_ifdown, |
278 | .local_out = __ip6_local_out, | 280 | .local_out = __ip6_local_out, |
279 | .gc_thresh = 1024, | 281 | .gc_thresh = 1024, |
280 | .entry_size = sizeof(struct xfrm_dst), | ||
281 | .entries = ATOMIC_INIT(0), | 282 | .entries = ATOMIC_INIT(0), |
282 | }; | 283 | }; |
283 | 284 | ||
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 89884a4f23aa..0e685b05496e 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <net/ipv6.h> | 19 | #include <net/ipv6.h> |
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static struct xfrm_state_afinfo xfrm6_state_afinfo; | ||
23 | |||
24 | static void | 22 | static void |
25 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, |
26 | struct xfrm_tmpl *tmpl, | 24 | struct xfrm_tmpl *tmpl, |
@@ -34,6 +32,7 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | |||
34 | x->sel.dport_mask = htons(0xffff); | 32 | x->sel.dport_mask = htons(0xffff); |
35 | x->sel.sport = xfrm_flowi_sport(fl); | 33 | x->sel.sport = xfrm_flowi_sport(fl); |
36 | x->sel.sport_mask = htons(0xffff); | 34 | x->sel.sport_mask = htons(0xffff); |
35 | x->sel.family = AF_INET6; | ||
37 | x->sel.prefixlen_d = 128; | 36 | x->sel.prefixlen_d = 128; |
38 | x->sel.prefixlen_s = 128; | 37 | x->sel.prefixlen_s = 128; |
39 | x->sel.proto = fl->proto; | 38 | x->sel.proto = fl->proto; |