diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 81 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 7 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 25 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 7 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 54 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 31 | ||||
-rw-r--r-- | net/ipv6/raw.c | 8 | ||||
-rw-r--r-- | net/ipv6/sit.c | 12 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 8 | ||||
-rw-r--r-- | net/ipv6/udp.c | 4 |
11 files changed, 135 insertions, 111 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 12368c58606..e39239e6426 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -428,7 +428,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
428 | ndev->tstamp = jiffies; | 428 | ndev->tstamp = jiffies; |
429 | addrconf_sysctl_register(ndev); | 429 | addrconf_sysctl_register(ndev); |
430 | /* protected by rtnl_lock */ | 430 | /* protected by rtnl_lock */ |
431 | rcu_assign_pointer(dev->ip6_ptr, ndev); | 431 | RCU_INIT_POINTER(dev->ip6_ptr, ndev); |
432 | 432 | ||
433 | /* Join all-node multicast group */ | 433 | /* Join all-node multicast group */ |
434 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes); | 434 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes); |
@@ -824,12 +824,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
824 | { | 824 | { |
825 | struct inet6_dev *idev = ifp->idev; | 825 | struct inet6_dev *idev = ifp->idev; |
826 | struct in6_addr addr, *tmpaddr; | 826 | struct in6_addr addr, *tmpaddr; |
827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age; | 827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age; |
828 | unsigned long regen_advance; | 828 | unsigned long regen_advance; |
829 | int tmp_plen; | 829 | int tmp_plen; |
830 | int ret = 0; | 830 | int ret = 0; |
831 | int max_addresses; | 831 | int max_addresses; |
832 | u32 addr_flags; | 832 | u32 addr_flags; |
833 | unsigned long now = jiffies; | ||
833 | 834 | ||
834 | write_lock(&idev->lock); | 835 | write_lock(&idev->lock); |
835 | if (ift) { | 836 | if (ift) { |
@@ -874,7 +875,7 @@ retry: | |||
874 | goto out; | 875 | goto out; |
875 | } | 876 | } |
876 | memcpy(&addr.s6_addr[8], idev->rndid, 8); | 877 | memcpy(&addr.s6_addr[8], idev->rndid, 8); |
877 | age = (jiffies - ifp->tstamp) / HZ; | 878 | age = (now - ifp->tstamp) / HZ; |
878 | tmp_valid_lft = min_t(__u32, | 879 | tmp_valid_lft = min_t(__u32, |
879 | ifp->valid_lft, | 880 | ifp->valid_lft, |
880 | idev->cnf.temp_valid_lft + age); | 881 | idev->cnf.temp_valid_lft + age); |
@@ -884,7 +885,6 @@ retry: | |||
884 | idev->cnf.max_desync_factor); | 885 | idev->cnf.max_desync_factor); |
885 | tmp_plen = ifp->prefix_len; | 886 | tmp_plen = ifp->prefix_len; |
886 | max_addresses = idev->cnf.max_addresses; | 887 | max_addresses = idev->cnf.max_addresses; |
887 | tmp_cstamp = ifp->cstamp; | ||
888 | tmp_tstamp = ifp->tstamp; | 888 | tmp_tstamp = ifp->tstamp; |
889 | spin_unlock_bh(&ifp->lock); | 889 | spin_unlock_bh(&ifp->lock); |
890 | 890 | ||
@@ -929,7 +929,7 @@ retry: | |||
929 | ift->ifpub = ifp; | 929 | ift->ifpub = ifp; |
930 | ift->valid_lft = tmp_valid_lft; | 930 | ift->valid_lft = tmp_valid_lft; |
931 | ift->prefered_lft = tmp_prefered_lft; | 931 | ift->prefered_lft = tmp_prefered_lft; |
932 | ift->cstamp = tmp_cstamp; | 932 | ift->cstamp = now; |
933 | ift->tstamp = tmp_tstamp; | 933 | ift->tstamp = tmp_tstamp; |
934 | spin_unlock_bh(&ift->lock); | 934 | spin_unlock_bh(&ift->lock); |
935 | 935 | ||
@@ -1999,25 +1999,50 @@ ok: | |||
1999 | #ifdef CONFIG_IPV6_PRIVACY | 1999 | #ifdef CONFIG_IPV6_PRIVACY |
2000 | read_lock_bh(&in6_dev->lock); | 2000 | read_lock_bh(&in6_dev->lock); |
2001 | /* update all temporary addresses in the list */ | 2001 | /* update all temporary addresses in the list */ |
2002 | list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) { | 2002 | list_for_each_entry(ift, &in6_dev->tempaddr_list, |
2003 | /* | 2003 | tmp_list) { |
2004 | * When adjusting the lifetimes of an existing | 2004 | int age, max_valid, max_prefered; |
2005 | * temporary address, only lower the lifetimes. | 2005 | |
2006 | * Implementations must not increase the | ||
2007 | * lifetimes of an existing temporary address | ||
2008 | * when processing a Prefix Information Option. | ||
2009 | */ | ||
2010 | if (ifp != ift->ifpub) | 2006 | if (ifp != ift->ifpub) |
2011 | continue; | 2007 | continue; |
2012 | 2008 | ||
2009 | /* | ||
2010 | * RFC 4941 section 3.3: | ||
2011 | * If a received option will extend the lifetime | ||
2012 | * of a public address, the lifetimes of | ||
2013 | * temporary addresses should be extended, | ||
2014 | * subject to the overall constraint that no | ||
2015 | * temporary addresses should ever remain | ||
2016 | * "valid" or "preferred" for a time longer than | ||
2017 | * (TEMP_VALID_LIFETIME) or | ||
2018 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), | ||
2019 | * respectively. | ||
2020 | */ | ||
2021 | age = (now - ift->cstamp) / HZ; | ||
2022 | max_valid = in6_dev->cnf.temp_valid_lft - age; | ||
2023 | if (max_valid < 0) | ||
2024 | max_valid = 0; | ||
2025 | |||
2026 | max_prefered = in6_dev->cnf.temp_prefered_lft - | ||
2027 | in6_dev->cnf.max_desync_factor - | ||
2028 | age; | ||
2029 | if (max_prefered < 0) | ||
2030 | max_prefered = 0; | ||
2031 | |||
2032 | if (valid_lft > max_valid) | ||
2033 | valid_lft = max_valid; | ||
2034 | |||
2035 | if (prefered_lft > max_prefered) | ||
2036 | prefered_lft = max_prefered; | ||
2037 | |||
2013 | spin_lock(&ift->lock); | 2038 | spin_lock(&ift->lock); |
2014 | flags = ift->flags; | 2039 | flags = ift->flags; |
2015 | if (ift->valid_lft > valid_lft && | 2040 | ift->valid_lft = valid_lft; |
2016 | ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ) | 2041 | ift->prefered_lft = prefered_lft; |
2017 | ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ; | 2042 | ift->tstamp = now; |
2018 | if (ift->prefered_lft > prefered_lft && | 2043 | if (prefered_lft > 0) |
2019 | ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ) | 2044 | ift->flags &= ~IFA_F_DEPRECATED; |
2020 | ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ; | 2045 | |
2021 | spin_unlock(&ift->lock); | 2046 | spin_unlock(&ift->lock); |
2022 | if (!(flags&IFA_F_TENTATIVE)) | 2047 | if (!(flags&IFA_F_TENTATIVE)) |
2023 | ipv6_ifa_notify(0, ift); | 2048 | ipv6_ifa_notify(0, ift); |
@@ -2025,9 +2050,11 @@ ok: | |||
2025 | 2050 | ||
2026 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { | 2051 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { |
2027 | /* | 2052 | /* |
2028 | * When a new public address is created as described in [ADDRCONF], | 2053 | * When a new public address is created as |
2029 | * also create a new temporary address. Also create a temporary | 2054 | * described in [ADDRCONF], also create a new |
2030 | * address if it's enabled but no temporary address currently exists. | 2055 | * temporary address. Also create a temporary |
2056 | * address if it's enabled but no temporary | ||
2057 | * address currently exists. | ||
2031 | */ | 2058 | */ |
2032 | read_unlock_bh(&in6_dev->lock); | 2059 | read_unlock_bh(&in6_dev->lock); |
2033 | ipv6_create_tempaddr(ifp, NULL); | 2060 | ipv6_create_tempaddr(ifp, NULL); |
@@ -2706,7 +2733,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2706 | idev->dead = 1; | 2733 | idev->dead = 1; |
2707 | 2734 | ||
2708 | /* protected by rtnl_lock */ | 2735 | /* protected by rtnl_lock */ |
2709 | rcu_assign_pointer(dev->ip6_ptr, NULL); | 2736 | RCU_INIT_POINTER(dev->ip6_ptr, NULL); |
2710 | 2737 | ||
2711 | /* Step 1.5: remove snmp6 entry */ | 2738 | /* Step 1.5: remove snmp6 entry */ |
2712 | snmp6_unregister_dev(idev); | 2739 | snmp6_unregister_dev(idev); |
@@ -2969,12 +2996,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
2969 | 2996 | ||
2970 | ipv6_ifa_notify(RTM_NEWADDR, ifp); | 2997 | ipv6_ifa_notify(RTM_NEWADDR, ifp); |
2971 | 2998 | ||
2972 | /* If added prefix is link local and forwarding is off, | 2999 | /* If added prefix is link local and we are prepared to process |
2973 | start sending router solicitations. | 3000 | router advertisements, start sending router solicitations. |
2974 | */ | 3001 | */ |
2975 | 3002 | ||
2976 | if ((ifp->idev->cnf.forwarding == 0 || | 3003 | if (((ifp->idev->cnf.accept_ra == 1 && !ifp->idev->cnf.forwarding) || |
2977 | ifp->idev->cnf.forwarding == 2) && | 3004 | ifp->idev->cnf.accept_ra == 2) && |
2978 | ifp->idev->cnf.rtr_solicits > 0 && | 3005 | ifp->idev->cnf.rtr_solicits > 0 && |
2979 | (dev->flags&IFF_LOOPBACK) == 0 && | 3006 | (dev->flags&IFF_LOOPBACK) == 0 && |
2980 | (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { | 3007 | (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 79a485e8a70..1318de4c3e8 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -273,12 +273,12 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
273 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 273 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
274 | __u16 dstbuf; | 274 | __u16 dstbuf; |
275 | #endif | 275 | #endif |
276 | struct dst_entry *dst; | 276 | struct dst_entry *dst = skb_dst(skb); |
277 | 277 | ||
278 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 278 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
279 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 279 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
280 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | 280 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
281 | IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), | 281 | IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst), |
282 | IPSTATS_MIB_INHDRERRORS); | 282 | IPSTATS_MIB_INHDRERRORS); |
283 | kfree_skb(skb); | 283 | kfree_skb(skb); |
284 | return -1; | 284 | return -1; |
@@ -289,9 +289,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
289 | dstbuf = opt->dst1; | 289 | dstbuf = opt->dst1; |
290 | #endif | 290 | #endif |
291 | 291 | ||
292 | dst = dst_clone(skb_dst(skb)); | ||
293 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { | 292 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { |
294 | dst_release(dst); | ||
295 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; | 293 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; |
296 | opt = IP6CB(skb); | 294 | opt = IP6CB(skb); |
297 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 295 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
@@ -304,7 +302,6 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
304 | 302 | ||
305 | IP6_INC_STATS_BH(dev_net(dst->dev), | 303 | IP6_INC_STATS_BH(dev_net(dst->dev), |
306 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | 304 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); |
307 | dst_release(dst); | ||
308 | return -1; | 305 | return -1; |
309 | } | 306 | } |
310 | 307 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 11900417b1c..2b59154c65d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -490,7 +490,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
490 | goto out_dst_release; | 490 | goto out_dst_release; |
491 | } | 491 | } |
492 | 492 | ||
493 | idev = in6_dev_get(skb->dev); | 493 | rcu_read_lock(); |
494 | idev = __in6_dev_get(skb->dev); | ||
494 | 495 | ||
495 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, | 496 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, |
496 | len + sizeof(struct icmp6hdr), | 497 | len + sizeof(struct icmp6hdr), |
@@ -500,19 +501,16 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
500 | if (err) { | 501 | if (err) { |
501 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); | 502 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); |
502 | ip6_flush_pending_frames(sk); | 503 | ip6_flush_pending_frames(sk); |
503 | goto out_put; | 504 | } else { |
505 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, | ||
506 | len + sizeof(struct icmp6hdr)); | ||
504 | } | 507 | } |
505 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr)); | 508 | rcu_read_unlock(); |
506 | |||
507 | out_put: | ||
508 | if (likely(idev != NULL)) | ||
509 | in6_dev_put(idev); | ||
510 | out_dst_release: | 509 | out_dst_release: |
511 | dst_release(dst); | 510 | dst_release(dst); |
512 | out: | 511 | out: |
513 | icmpv6_xmit_unlock(sk); | 512 | icmpv6_xmit_unlock(sk); |
514 | } | 513 | } |
515 | |||
516 | EXPORT_SYMBOL(icmpv6_send); | 514 | EXPORT_SYMBOL(icmpv6_send); |
517 | 515 | ||
518 | static void icmpv6_echo_reply(struct sk_buff *skb) | 516 | static void icmpv6_echo_reply(struct sk_buff *skb) |
@@ -569,7 +567,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
569 | if (hlimit < 0) | 567 | if (hlimit < 0) |
570 | hlimit = ip6_dst_hoplimit(dst); | 568 | hlimit = ip6_dst_hoplimit(dst); |
571 | 569 | ||
572 | idev = in6_dev_get(skb->dev); | 570 | idev = __in6_dev_get(skb->dev); |
573 | 571 | ||
574 | msg.skb = skb; | 572 | msg.skb = skb; |
575 | msg.offset = 0; | 573 | msg.offset = 0; |
@@ -583,13 +581,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
583 | if (err) { | 581 | if (err) { |
584 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); | 582 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); |
585 | ip6_flush_pending_frames(sk); | 583 | ip6_flush_pending_frames(sk); |
586 | goto out_put; | 584 | } else { |
585 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, | ||
586 | skb->len + sizeof(struct icmp6hdr)); | ||
587 | } | 587 | } |
588 | err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); | ||
589 | |||
590 | out_put: | ||
591 | if (likely(idev != NULL)) | ||
592 | in6_dev_put(idev); | ||
593 | dst_release(dst); | 588 | dst_release(dst); |
594 | out: | 589 | out: |
595 | icmpv6_xmit_unlock(sk); | 590 | icmpv6_xmit_unlock(sk); |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 8a58e8cf664..2916200f90c 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -211,6 +211,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
211 | struct flowi6 fl6; | 211 | struct flowi6 fl6; |
212 | struct dst_entry *dst; | 212 | struct dst_entry *dst; |
213 | struct in6_addr *final_p, final; | 213 | struct in6_addr *final_p, final; |
214 | int res; | ||
214 | 215 | ||
215 | memset(&fl6, 0, sizeof(fl6)); | 216 | memset(&fl6, 0, sizeof(fl6)); |
216 | fl6.flowi6_proto = sk->sk_protocol; | 217 | fl6.flowi6_proto = sk->sk_protocol; |
@@ -241,12 +242,14 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
241 | __inet6_csk_dst_store(sk, dst, NULL, NULL); | 242 | __inet6_csk_dst_store(sk, dst, NULL, NULL); |
242 | } | 243 | } |
243 | 244 | ||
244 | skb_dst_set(skb, dst_clone(dst)); | 245 | rcu_read_lock(); |
246 | skb_dst_set_noref(skb, dst); | ||
245 | 247 | ||
246 | /* Restore final destination back after routing done */ | 248 | /* Restore final destination back after routing done */ |
247 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 249 | ipv6_addr_copy(&fl6.daddr, &np->daddr); |
248 | 250 | ||
249 | return ip6_xmit(sk, skb, &fl6, np->opt); | 251 | res = ip6_xmit(sk, skb, &fl6, np->opt); |
252 | rcu_read_unlock(); | ||
253 | return res; | ||
250 | } | 254 | } |
251 | |||
252 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); | 255 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4c882cf4e8a..835c04b5239 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1480,13 +1480,13 @@ alloc_new_skb: | |||
1480 | if (page && (left = PAGE_SIZE - off) > 0) { | 1480 | if (page && (left = PAGE_SIZE - off) > 0) { |
1481 | if (copy >= left) | 1481 | if (copy >= left) |
1482 | copy = left; | 1482 | copy = left; |
1483 | if (page != frag->page) { | 1483 | if (page != skb_frag_page(frag)) { |
1484 | if (i == MAX_SKB_FRAGS) { | 1484 | if (i == MAX_SKB_FRAGS) { |
1485 | err = -EMSGSIZE; | 1485 | err = -EMSGSIZE; |
1486 | goto error; | 1486 | goto error; |
1487 | } | 1487 | } |
1488 | get_page(page); | ||
1489 | skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); | 1488 | skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); |
1489 | skb_frag_ref(skb, i); | ||
1490 | frag = &skb_shinfo(skb)->frags[i]; | 1490 | frag = &skb_shinfo(skb)->frags[i]; |
1491 | } | 1491 | } |
1492 | } else if(i < MAX_SKB_FRAGS) { | 1492 | } else if(i < MAX_SKB_FRAGS) { |
@@ -1506,7 +1506,8 @@ alloc_new_skb: | |||
1506 | err = -EMSGSIZE; | 1506 | err = -EMSGSIZE; |
1507 | goto error; | 1507 | goto error; |
1508 | } | 1508 | } |
1509 | if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) { | 1509 | if (getfrag(from, skb_frag_address(frag)+frag->size, |
1510 | offset, copy, skb->len, skb) < 0) { | ||
1510 | err = -EFAULT; | 1511 | err = -EFAULT; |
1511 | goto error; | 1512 | goto error; |
1512 | } | 1513 | } |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 0bc98886c38..bdc15c9003d 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -218,8 +218,8 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) | |||
218 | { | 218 | { |
219 | struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms); | 219 | struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms); |
220 | 220 | ||
221 | rcu_assign_pointer(t->next , rtnl_dereference(*tp)); | 221 | RCU_INIT_POINTER(t->next , rtnl_dereference(*tp)); |
222 | rcu_assign_pointer(*tp, t); | 222 | RCU_INIT_POINTER(*tp, t); |
223 | } | 223 | } |
224 | 224 | ||
225 | /** | 225 | /** |
@@ -237,7 +237,7 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) | |||
237 | (iter = rtnl_dereference(*tp)) != NULL; | 237 | (iter = rtnl_dereference(*tp)) != NULL; |
238 | tp = &iter->next) { | 238 | tp = &iter->next) { |
239 | if (t == iter) { | 239 | if (t == iter) { |
240 | rcu_assign_pointer(*tp, t->next); | 240 | RCU_INIT_POINTER(*tp, t->next); |
241 | break; | 241 | break; |
242 | } | 242 | } |
243 | } | 243 | } |
@@ -350,7 +350,7 @@ ip6_tnl_dev_uninit(struct net_device *dev) | |||
350 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); | 350 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); |
351 | 351 | ||
352 | if (dev == ip6n->fb_tnl_dev) | 352 | if (dev == ip6n->fb_tnl_dev) |
353 | rcu_assign_pointer(ip6n->tnls_wc[0], NULL); | 353 | RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); |
354 | else | 354 | else |
355 | ip6_tnl_unlink(ip6n, t); | 355 | ip6_tnl_unlink(ip6n, t); |
356 | ip6_tnl_dst_reset(t); | 356 | ip6_tnl_dst_reset(t); |
@@ -889,7 +889,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
889 | struct net_device_stats *stats = &t->dev->stats; | 889 | struct net_device_stats *stats = &t->dev->stats; |
890 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); | 890 | struct ipv6hdr *ipv6h = ipv6_hdr(skb); |
891 | struct ipv6_tel_txoption opt; | 891 | struct ipv6_tel_txoption opt; |
892 | struct dst_entry *dst; | 892 | struct dst_entry *dst = NULL, *ndst = NULL; |
893 | struct net_device *tdev; | 893 | struct net_device *tdev; |
894 | int mtu; | 894 | int mtu; |
895 | unsigned int max_headroom = sizeof(struct ipv6hdr); | 895 | unsigned int max_headroom = sizeof(struct ipv6hdr); |
@@ -897,19 +897,20 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
897 | int err = -1; | 897 | int err = -1; |
898 | int pkt_len; | 898 | int pkt_len; |
899 | 899 | ||
900 | if ((dst = ip6_tnl_dst_check(t)) != NULL) | 900 | if (!fl6->flowi6_mark) |
901 | dst_hold(dst); | 901 | dst = ip6_tnl_dst_check(t); |
902 | else { | 902 | if (!dst) { |
903 | dst = ip6_route_output(net, NULL, fl6); | 903 | ndst = ip6_route_output(net, NULL, fl6); |
904 | 904 | ||
905 | if (dst->error) | 905 | if (ndst->error) |
906 | goto tx_err_link_failure; | 906 | goto tx_err_link_failure; |
907 | dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0); | 907 | ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(fl6), NULL, 0); |
908 | if (IS_ERR(dst)) { | 908 | if (IS_ERR(ndst)) { |
909 | err = PTR_ERR(dst); | 909 | err = PTR_ERR(ndst); |
910 | dst = NULL; | 910 | ndst = NULL; |
911 | goto tx_err_link_failure; | 911 | goto tx_err_link_failure; |
912 | } | 912 | } |
913 | dst = ndst; | ||
913 | } | 914 | } |
914 | 915 | ||
915 | tdev = dst->dev; | 916 | tdev = dst->dev; |
@@ -955,8 +956,12 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
955 | skb = new_skb; | 956 | skb = new_skb; |
956 | } | 957 | } |
957 | skb_dst_drop(skb); | 958 | skb_dst_drop(skb); |
958 | skb_dst_set(skb, dst_clone(dst)); | 959 | if (fl6->flowi6_mark) { |
959 | 960 | skb_dst_set(skb, dst); | |
961 | ndst = NULL; | ||
962 | } else { | ||
963 | skb_dst_set_noref(skb, dst); | ||
964 | } | ||
960 | skb->transport_header = skb->network_header; | 965 | skb->transport_header = skb->network_header; |
961 | 966 | ||
962 | proto = fl6->flowi6_proto; | 967 | proto = fl6->flowi6_proto; |
@@ -987,13 +992,14 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
987 | stats->tx_errors++; | 992 | stats->tx_errors++; |
988 | stats->tx_aborted_errors++; | 993 | stats->tx_aborted_errors++; |
989 | } | 994 | } |
990 | ip6_tnl_dst_store(t, dst); | 995 | if (ndst) |
996 | ip6_tnl_dst_store(t, ndst); | ||
991 | return 0; | 997 | return 0; |
992 | tx_err_link_failure: | 998 | tx_err_link_failure: |
993 | stats->tx_carrier_errors++; | 999 | stats->tx_carrier_errors++; |
994 | dst_link_failure(skb); | 1000 | dst_link_failure(skb); |
995 | tx_err_dst_release: | 1001 | tx_err_dst_release: |
996 | dst_release(dst); | 1002 | dst_release(ndst); |
997 | return err; | 1003 | return err; |
998 | } | 1004 | } |
999 | 1005 | ||
@@ -1020,9 +1026,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1020 | 1026 | ||
1021 | dsfield = ipv4_get_dsfield(iph); | 1027 | dsfield = ipv4_get_dsfield(iph); |
1022 | 1028 | ||
1023 | if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) | 1029 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
1024 | fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) | 1030 | fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) |
1025 | & IPV6_TCLASS_MASK; | 1031 | & IPV6_TCLASS_MASK; |
1032 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) | ||
1033 | fl6.flowi6_mark = skb->mark; | ||
1026 | 1034 | ||
1027 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); | 1035 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); |
1028 | if (err != 0) { | 1036 | if (err != 0) { |
@@ -1069,10 +1077,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1069 | fl6.flowi6_proto = IPPROTO_IPV6; | 1077 | fl6.flowi6_proto = IPPROTO_IPV6; |
1070 | 1078 | ||
1071 | dsfield = ipv6_get_dsfield(ipv6h); | 1079 | dsfield = ipv6_get_dsfield(ipv6h); |
1072 | if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) | 1080 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) |
1073 | fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); | 1081 | fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); |
1074 | if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) | 1082 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) |
1075 | fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK); | 1083 | fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK); |
1084 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) | ||
1085 | fl6.flowi6_mark = skb->mark; | ||
1076 | 1086 | ||
1077 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); | 1087 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); |
1078 | if (err != 0) { | 1088 | if (err != 0) { |
@@ -1439,7 +1449,7 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1439 | 1449 | ||
1440 | t->parms.proto = IPPROTO_IPV6; | 1450 | t->parms.proto = IPPROTO_IPV6; |
1441 | dev_hold(dev); | 1451 | dev_hold(dev); |
1442 | rcu_assign_pointer(ip6n->tnls_wc[0], t); | 1452 | RCU_INIT_POINTER(ip6n->tnls_wc[0], t); |
1443 | return 0; | 1453 | return 0; |
1444 | } | 1454 | } |
1445 | 1455 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 9da6e02eaae..1f52dd25763 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -533,7 +533,8 @@ void ndisc_send_skb(struct sk_buff *skb, | |||
533 | 533 | ||
534 | skb_dst_set(skb, dst); | 534 | skb_dst_set(skb, dst); |
535 | 535 | ||
536 | idev = in6_dev_get(dst->dev); | 536 | rcu_read_lock(); |
537 | idev = __in6_dev_get(dst->dev); | ||
537 | IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); | 538 | IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); |
538 | 539 | ||
539 | err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 540 | err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
@@ -543,8 +544,7 @@ void ndisc_send_skb(struct sk_buff *skb, | |||
543 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); | 544 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
544 | } | 545 | } |
545 | 546 | ||
546 | if (likely(idev != NULL)) | 547 | rcu_read_unlock(); |
547 | in6_dev_put(idev); | ||
548 | } | 548 | } |
549 | 549 | ||
550 | EXPORT_SYMBOL(ndisc_send_skb); | 550 | EXPORT_SYMBOL(ndisc_send_skb); |
@@ -1039,7 +1039,7 @@ static void ndisc_recv_rs(struct sk_buff *skb) | |||
1039 | if (skb->len < sizeof(*rs_msg)) | 1039 | if (skb->len < sizeof(*rs_msg)) |
1040 | return; | 1040 | return; |
1041 | 1041 | ||
1042 | idev = in6_dev_get(skb->dev); | 1042 | idev = __in6_dev_get(skb->dev); |
1043 | if (!idev) { | 1043 | if (!idev) { |
1044 | if (net_ratelimit()) | 1044 | if (net_ratelimit()) |
1045 | ND_PRINTK1("ICMP6 RS: can't find in6 device\n"); | 1045 | ND_PRINTK1("ICMP6 RS: can't find in6 device\n"); |
@@ -1080,7 +1080,7 @@ static void ndisc_recv_rs(struct sk_buff *skb) | |||
1080 | neigh_release(neigh); | 1080 | neigh_release(neigh); |
1081 | } | 1081 | } |
1082 | out: | 1082 | out: |
1083 | in6_dev_put(idev); | 1083 | return; |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) | 1086 | static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) |
@@ -1179,7 +1179,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1179 | * set the RA_RECV flag in the interface | 1179 | * set the RA_RECV flag in the interface |
1180 | */ | 1180 | */ |
1181 | 1181 | ||
1182 | in6_dev = in6_dev_get(skb->dev); | 1182 | in6_dev = __in6_dev_get(skb->dev); |
1183 | if (in6_dev == NULL) { | 1183 | if (in6_dev == NULL) { |
1184 | ND_PRINTK0(KERN_ERR | 1184 | ND_PRINTK0(KERN_ERR |
1185 | "ICMPv6 RA: can't find inet6 device for %s.\n", | 1185 | "ICMPv6 RA: can't find inet6 device for %s.\n", |
@@ -1188,7 +1188,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | if (!ndisc_parse_options(opt, optlen, &ndopts)) { | 1190 | if (!ndisc_parse_options(opt, optlen, &ndopts)) { |
1191 | in6_dev_put(in6_dev); | ||
1192 | ND_PRINTK2(KERN_WARNING | 1191 | ND_PRINTK2(KERN_WARNING |
1193 | "ICMP6 RA: invalid ND options\n"); | 1192 | "ICMP6 RA: invalid ND options\n"); |
1194 | return; | 1193 | return; |
@@ -1255,7 +1254,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1255 | ND_PRINTK0(KERN_ERR | 1254 | ND_PRINTK0(KERN_ERR |
1256 | "ICMPv6 RA: %s() failed to add default route.\n", | 1255 | "ICMPv6 RA: %s() failed to add default route.\n", |
1257 | __func__); | 1256 | __func__); |
1258 | in6_dev_put(in6_dev); | ||
1259 | return; | 1257 | return; |
1260 | } | 1258 | } |
1261 | 1259 | ||
@@ -1265,7 +1263,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1265 | "ICMPv6 RA: %s() got default router without neighbour.\n", | 1263 | "ICMPv6 RA: %s() got default router without neighbour.\n", |
1266 | __func__); | 1264 | __func__); |
1267 | dst_release(&rt->dst); | 1265 | dst_release(&rt->dst); |
1268 | in6_dev_put(in6_dev); | ||
1269 | return; | 1266 | return; |
1270 | } | 1267 | } |
1271 | neigh->flags |= NTF_ROUTER; | 1268 | neigh->flags |= NTF_ROUTER; |
@@ -1422,7 +1419,6 @@ out: | |||
1422 | dst_release(&rt->dst); | 1419 | dst_release(&rt->dst); |
1423 | else if (neigh) | 1420 | else if (neigh) |
1424 | neigh_release(neigh); | 1421 | neigh_release(neigh); |
1425 | in6_dev_put(in6_dev); | ||
1426 | } | 1422 | } |
1427 | 1423 | ||
1428 | static void ndisc_redirect_rcv(struct sk_buff *skb) | 1424 | static void ndisc_redirect_rcv(struct sk_buff *skb) |
@@ -1481,13 +1477,11 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1481 | return; | 1477 | return; |
1482 | } | 1478 | } |
1483 | 1479 | ||
1484 | in6_dev = in6_dev_get(skb->dev); | 1480 | in6_dev = __in6_dev_get(skb->dev); |
1485 | if (!in6_dev) | 1481 | if (!in6_dev) |
1486 | return; | 1482 | return; |
1487 | if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) { | 1483 | if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) |
1488 | in6_dev_put(in6_dev); | ||
1489 | return; | 1484 | return; |
1490 | } | ||
1491 | 1485 | ||
1492 | /* RFC2461 8.1: | 1486 | /* RFC2461 8.1: |
1493 | * The IP source address of the Redirect MUST be the same as the current | 1487 | * The IP source address of the Redirect MUST be the same as the current |
@@ -1497,7 +1491,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1497 | if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { | 1491 | if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { |
1498 | ND_PRINTK2(KERN_WARNING | 1492 | ND_PRINTK2(KERN_WARNING |
1499 | "ICMPv6 Redirect: invalid ND options\n"); | 1493 | "ICMPv6 Redirect: invalid ND options\n"); |
1500 | in6_dev_put(in6_dev); | ||
1501 | return; | 1494 | return; |
1502 | } | 1495 | } |
1503 | if (ndopts.nd_opts_tgt_lladdr) { | 1496 | if (ndopts.nd_opts_tgt_lladdr) { |
@@ -1506,7 +1499,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1506 | if (!lladdr) { | 1499 | if (!lladdr) { |
1507 | ND_PRINTK2(KERN_WARNING | 1500 | ND_PRINTK2(KERN_WARNING |
1508 | "ICMPv6 Redirect: invalid link-layer address length\n"); | 1501 | "ICMPv6 Redirect: invalid link-layer address length\n"); |
1509 | in6_dev_put(in6_dev); | ||
1510 | return; | 1502 | return; |
1511 | } | 1503 | } |
1512 | } | 1504 | } |
@@ -1518,7 +1510,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1518 | on_link); | 1510 | on_link); |
1519 | neigh_release(neigh); | 1511 | neigh_release(neigh); |
1520 | } | 1512 | } |
1521 | in6_dev_put(in6_dev); | ||
1522 | } | 1513 | } |
1523 | 1514 | ||
1524 | void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | 1515 | void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, |
@@ -1651,7 +1642,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1651 | csum_partial(icmph, len, 0)); | 1642 | csum_partial(icmph, len, 0)); |
1652 | 1643 | ||
1653 | skb_dst_set(buff, dst); | 1644 | skb_dst_set(buff, dst); |
1654 | idev = in6_dev_get(dst->dev); | 1645 | rcu_read_lock(); |
1646 | idev = __in6_dev_get(dst->dev); | ||
1655 | IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); | 1647 | IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); |
1656 | err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, | 1648 | err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, |
1657 | dst_output); | 1649 | dst_output); |
@@ -1660,8 +1652,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1660 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); | 1652 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
1661 | } | 1653 | } |
1662 | 1654 | ||
1663 | if (likely(idev != NULL)) | 1655 | rcu_read_unlock(); |
1664 | in6_dev_put(idev); | ||
1665 | return; | 1656 | return; |
1666 | 1657 | ||
1667 | release: | 1658 | release: |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 343852e5c70..3486f62befa 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -130,14 +130,14 @@ static mh_filter_t __rcu *mh_filter __read_mostly; | |||
130 | 130 | ||
131 | int rawv6_mh_filter_register(mh_filter_t filter) | 131 | int rawv6_mh_filter_register(mh_filter_t filter) |
132 | { | 132 | { |
133 | rcu_assign_pointer(mh_filter, filter); | 133 | RCU_INIT_POINTER(mh_filter, filter); |
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | EXPORT_SYMBOL(rawv6_mh_filter_register); | 136 | EXPORT_SYMBOL(rawv6_mh_filter_register); |
137 | 137 | ||
138 | int rawv6_mh_filter_unregister(mh_filter_t filter) | 138 | int rawv6_mh_filter_unregister(mh_filter_t filter) |
139 | { | 139 | { |
140 | rcu_assign_pointer(mh_filter, NULL); | 140 | RCU_INIT_POINTER(mh_filter, NULL); |
141 | synchronize_rcu(); | 141 | synchronize_rcu(); |
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
@@ -372,9 +372,9 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, | |||
372 | read_unlock(&raw_v6_hashinfo.lock); | 372 | read_unlock(&raw_v6_hashinfo.lock); |
373 | } | 373 | } |
374 | 374 | ||
375 | static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | 375 | static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) |
376 | { | 376 | { |
377 | if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) && | 377 | if ((raw6_sk(sk)->checksum || rcu_access_pointer(sk->sk_filter)) && |
378 | skb_checksum_complete(skb)) { | 378 | skb_checksum_complete(skb)) { |
379 | atomic_inc(&sk->sk_drops); | 379 | atomic_inc(&sk->sk_drops); |
380 | kfree_skb(skb); | 380 | kfree_skb(skb); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 00b15ac7a70..a7a18602a04 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -182,7 +182,7 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) | |||
182 | (iter = rtnl_dereference(*tp)) != NULL; | 182 | (iter = rtnl_dereference(*tp)) != NULL; |
183 | tp = &iter->next) { | 183 | tp = &iter->next) { |
184 | if (t == iter) { | 184 | if (t == iter) { |
185 | rcu_assign_pointer(*tp, t->next); | 185 | RCU_INIT_POINTER(*tp, t->next); |
186 | break; | 186 | break; |
187 | } | 187 | } |
188 | } | 188 | } |
@@ -192,8 +192,8 @@ static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) | |||
192 | { | 192 | { |
193 | struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); | 193 | struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); |
194 | 194 | ||
195 | rcu_assign_pointer(t->next, rtnl_dereference(*tp)); | 195 | RCU_INIT_POINTER(t->next, rtnl_dereference(*tp)); |
196 | rcu_assign_pointer(*tp, t); | 196 | RCU_INIT_POINTER(*tp, t); |
197 | } | 197 | } |
198 | 198 | ||
199 | static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) | 199 | static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) |
@@ -391,7 +391,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) | |||
391 | p->addr = a->addr; | 391 | p->addr = a->addr; |
392 | p->flags = a->flags; | 392 | p->flags = a->flags; |
393 | t->prl_count++; | 393 | t->prl_count++; |
394 | rcu_assign_pointer(t->prl, p); | 394 | RCU_INIT_POINTER(t->prl, p); |
395 | out: | 395 | out: |
396 | return err; | 396 | return err; |
397 | } | 397 | } |
@@ -474,7 +474,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
474 | struct sit_net *sitn = net_generic(net, sit_net_id); | 474 | struct sit_net *sitn = net_generic(net, sit_net_id); |
475 | 475 | ||
476 | if (dev == sitn->fb_tunnel_dev) { | 476 | if (dev == sitn->fb_tunnel_dev) { |
477 | rcu_assign_pointer(sitn->tunnels_wc[0], NULL); | 477 | RCU_INIT_POINTER(sitn->tunnels_wc[0], NULL); |
478 | } else { | 478 | } else { |
479 | ipip6_tunnel_unlink(sitn, netdev_priv(dev)); | 479 | ipip6_tunnel_unlink(sitn, netdev_priv(dev)); |
480 | ipip6_tunnel_del_prl(netdev_priv(dev), NULL); | 480 | ipip6_tunnel_del_prl(netdev_priv(dev), NULL); |
@@ -1176,7 +1176,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1176 | if (!dev->tstats) | 1176 | if (!dev->tstats) |
1177 | return -ENOMEM; | 1177 | return -ENOMEM; |
1178 | dev_hold(dev); | 1178 | dev_hold(dev); |
1179 | rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); | 1179 | RCU_INIT_POINTER(sitn->tunnels_wc[0], tunnel); |
1180 | return 0; | 1180 | return 0; |
1181 | } | 1181 | } |
1182 | 1182 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 7b8fc579435..5357902c797 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1608,7 +1608,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1608 | opt_skb = skb_clone(skb, GFP_ATOMIC); | 1608 | opt_skb = skb_clone(skb, GFP_ATOMIC); |
1609 | 1609 | ||
1610 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ | 1610 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
1611 | sock_rps_save_rxhash(sk, skb->rxhash); | 1611 | sock_rps_save_rxhash(sk, skb); |
1612 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) | 1612 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) |
1613 | goto reset; | 1613 | goto reset; |
1614 | if (opt_skb) | 1614 | if (opt_skb) |
@@ -1630,7 +1630,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1630 | * the new socket.. | 1630 | * the new socket.. |
1631 | */ | 1631 | */ |
1632 | if(nsk != sk) { | 1632 | if(nsk != sk) { |
1633 | sock_rps_save_rxhash(nsk, skb->rxhash); | 1633 | sock_rps_save_rxhash(nsk, skb); |
1634 | if (tcp_child_process(sk, nsk, skb)) | 1634 | if (tcp_child_process(sk, nsk, skb)) |
1635 | goto reset; | 1635 | goto reset; |
1636 | if (opt_skb) | 1636 | if (opt_skb) |
@@ -1638,7 +1638,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1638 | return 0; | 1638 | return 0; |
1639 | } | 1639 | } |
1640 | } else | 1640 | } else |
1641 | sock_rps_save_rxhash(sk, skb->rxhash); | 1641 | sock_rps_save_rxhash(sk, skb); |
1642 | 1642 | ||
1643 | if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) | 1643 | if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) |
1644 | goto reset; | 1644 | goto reset; |
@@ -1722,7 +1722,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1722 | skb->len - th->doff*4); | 1722 | skb->len - th->doff*4); |
1723 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | 1723 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); |
1724 | TCP_SKB_CB(skb)->when = 0; | 1724 | TCP_SKB_CB(skb)->when = 0; |
1725 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(hdr); | 1725 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); |
1726 | TCP_SKB_CB(skb)->sacked = 0; | 1726 | TCP_SKB_CB(skb)->sacked = 0; |
1727 | 1727 | ||
1728 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); | 1728 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index bb95e8e1c6f..f4ca0a5b345 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -509,7 +509,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
509 | int is_udplite = IS_UDPLITE(sk); | 509 | int is_udplite = IS_UDPLITE(sk); |
510 | 510 | ||
511 | if (!ipv6_addr_any(&inet6_sk(sk)->daddr)) | 511 | if (!ipv6_addr_any(&inet6_sk(sk)->daddr)) |
512 | sock_rps_save_rxhash(sk, skb->rxhash); | 512 | sock_rps_save_rxhash(sk, skb); |
513 | 513 | ||
514 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 514 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
515 | goto drop; | 515 | goto drop; |
@@ -533,7 +533,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
533 | } | 533 | } |
534 | } | 534 | } |
535 | 535 | ||
536 | if (rcu_dereference_raw(sk->sk_filter)) { | 536 | if (rcu_access_pointer(sk->sk_filter)) { |
537 | if (udp_lib_checksum_complete(skb)) | 537 | if (udp_lib_checksum_complete(skb)) |
538 | goto drop; | 538 | goto drop; |
539 | } | 539 | } |