diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/Kconfig | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 198 | ||||
-rw-r--r-- | net/ipv6/exthdrs_core.c | 2 | ||||
-rw-r--r-- | net/ipv6/exthdrs_offload.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_offload.c | 20 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 17 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 13 | ||||
-rw-r--r-- | net/ipv6/ping.c | 1 | ||||
-rw-r--r-- | net/ipv6/route.c | 2 | ||||
-rw-r--r-- | net/ipv6/sit.c | 19 | ||||
-rw-r--r-- | net/ipv6/udp_offload.c | 2 |
11 files changed, 198 insertions, 81 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index d92e5586783e..438a73aa777c 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
@@ -138,6 +138,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION | |||
138 | config IPV6_VTI | 138 | config IPV6_VTI |
139 | tristate "Virtual (secure) IPv6: tunneling" | 139 | tristate "Virtual (secure) IPv6: tunneling" |
140 | select IPV6_TUNNEL | 140 | select IPV6_TUNNEL |
141 | select NET_IP_TUNNEL | ||
141 | depends on INET6_XFRM_MODE_TUNNEL | 142 | depends on INET6_XFRM_MODE_TUNNEL |
142 | ---help--- | 143 | ---help--- |
143 | Tunneling means encapsulating data of one protocol type within | 144 | Tunneling means encapsulating data of one protocol type within |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index fdbfeca36d63..6c7fa0853fc7 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -133,10 +133,12 @@ static int ipv6_count_addresses(struct inet6_dev *idev); | |||
133 | static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE]; | 133 | static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE]; |
134 | static DEFINE_SPINLOCK(addrconf_hash_lock); | 134 | static DEFINE_SPINLOCK(addrconf_hash_lock); |
135 | 135 | ||
136 | static void addrconf_verify(unsigned long); | 136 | static void addrconf_verify(void); |
137 | static void addrconf_verify_rtnl(void); | ||
138 | static void addrconf_verify_work(struct work_struct *); | ||
137 | 139 | ||
138 | static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); | 140 | static struct workqueue_struct *addrconf_wq; |
139 | static DEFINE_SPINLOCK(addrconf_verify_lock); | 141 | static DECLARE_DELAYED_WORK(addr_chk_work, addrconf_verify_work); |
140 | 142 | ||
141 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); | 143 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); |
142 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); | 144 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); |
@@ -151,7 +153,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, | |||
151 | u32 flags, u32 noflags); | 153 | u32 flags, u32 noflags); |
152 | 154 | ||
153 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); | 155 | static void addrconf_dad_start(struct inet6_ifaddr *ifp); |
154 | static void addrconf_dad_timer(unsigned long data); | 156 | static void addrconf_dad_work(struct work_struct *w); |
155 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); | 157 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); |
156 | static void addrconf_dad_run(struct inet6_dev *idev); | 158 | static void addrconf_dad_run(struct inet6_dev *idev); |
157 | static void addrconf_rs_timer(unsigned long data); | 159 | static void addrconf_rs_timer(unsigned long data); |
@@ -247,9 +249,9 @@ static void addrconf_del_rs_timer(struct inet6_dev *idev) | |||
247 | __in6_dev_put(idev); | 249 | __in6_dev_put(idev); |
248 | } | 250 | } |
249 | 251 | ||
250 | static void addrconf_del_dad_timer(struct inet6_ifaddr *ifp) | 252 | static void addrconf_del_dad_work(struct inet6_ifaddr *ifp) |
251 | { | 253 | { |
252 | if (del_timer(&ifp->dad_timer)) | 254 | if (cancel_delayed_work(&ifp->dad_work)) |
253 | __in6_ifa_put(ifp); | 255 | __in6_ifa_put(ifp); |
254 | } | 256 | } |
255 | 257 | ||
@@ -261,12 +263,12 @@ static void addrconf_mod_rs_timer(struct inet6_dev *idev, | |||
261 | mod_timer(&idev->rs_timer, jiffies + when); | 263 | mod_timer(&idev->rs_timer, jiffies + when); |
262 | } | 264 | } |
263 | 265 | ||
264 | static void addrconf_mod_dad_timer(struct inet6_ifaddr *ifp, | 266 | static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp, |
265 | unsigned long when) | 267 | unsigned long delay) |
266 | { | 268 | { |
267 | if (!timer_pending(&ifp->dad_timer)) | 269 | if (!delayed_work_pending(&ifp->dad_work)) |
268 | in6_ifa_hold(ifp); | 270 | in6_ifa_hold(ifp); |
269 | mod_timer(&ifp->dad_timer, jiffies + when); | 271 | mod_delayed_work(addrconf_wq, &ifp->dad_work, delay); |
270 | } | 272 | } |
271 | 273 | ||
272 | static int snmp6_alloc_dev(struct inet6_dev *idev) | 274 | static int snmp6_alloc_dev(struct inet6_dev *idev) |
@@ -751,8 +753,9 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
751 | 753 | ||
752 | in6_dev_put(ifp->idev); | 754 | in6_dev_put(ifp->idev); |
753 | 755 | ||
754 | if (del_timer(&ifp->dad_timer)) | 756 | if (cancel_delayed_work(&ifp->dad_work)) |
755 | pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); | 757 | pr_notice("delayed DAD work was pending while freeing ifa=%p\n", |
758 | ifp); | ||
756 | 759 | ||
757 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { | 760 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { |
758 | pr_warn("Freeing alive inet6 address %p\n", ifp); | 761 | pr_warn("Freeing alive inet6 address %p\n", ifp); |
@@ -849,8 +852,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
849 | 852 | ||
850 | spin_lock_init(&ifa->lock); | 853 | spin_lock_init(&ifa->lock); |
851 | spin_lock_init(&ifa->state_lock); | 854 | spin_lock_init(&ifa->state_lock); |
852 | setup_timer(&ifa->dad_timer, addrconf_dad_timer, | 855 | INIT_DELAYED_WORK(&ifa->dad_work, addrconf_dad_work); |
853 | (unsigned long)ifa); | ||
854 | INIT_HLIST_NODE(&ifa->addr_lst); | 856 | INIT_HLIST_NODE(&ifa->addr_lst); |
855 | ifa->scope = scope; | 857 | ifa->scope = scope; |
856 | ifa->prefix_len = pfxlen; | 858 | ifa->prefix_len = pfxlen; |
@@ -990,6 +992,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
990 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP; | 992 | enum cleanup_prefix_rt_t action = CLEANUP_PREFIX_RT_NOP; |
991 | unsigned long expires; | 993 | unsigned long expires; |
992 | 994 | ||
995 | ASSERT_RTNL(); | ||
996 | |||
993 | spin_lock_bh(&ifp->state_lock); | 997 | spin_lock_bh(&ifp->state_lock); |
994 | state = ifp->state; | 998 | state = ifp->state; |
995 | ifp->state = INET6_IFADDR_STATE_DEAD; | 999 | ifp->state = INET6_IFADDR_STATE_DEAD; |
@@ -1021,7 +1025,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
1021 | 1025 | ||
1022 | write_unlock_bh(&ifp->idev->lock); | 1026 | write_unlock_bh(&ifp->idev->lock); |
1023 | 1027 | ||
1024 | addrconf_del_dad_timer(ifp); | 1028 | addrconf_del_dad_work(ifp); |
1025 | 1029 | ||
1026 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 1030 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
1027 | 1031 | ||
@@ -1103,8 +1107,11 @@ retry: | |||
1103 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, | 1107 | * Lifetime is greater than REGEN_ADVANCE time units. In particular, |
1104 | * an implementation must not create a temporary address with a zero | 1108 | * an implementation must not create a temporary address with a zero |
1105 | * Preferred Lifetime. | 1109 | * Preferred Lifetime. |
1110 | * Use age calculation as in addrconf_verify to avoid unnecessary | ||
1111 | * temporary addresses being generated. | ||
1106 | */ | 1112 | */ |
1107 | if (tmp_prefered_lft <= regen_advance) { | 1113 | age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; |
1114 | if (tmp_prefered_lft <= regen_advance + age) { | ||
1108 | in6_ifa_put(ifp); | 1115 | in6_ifa_put(ifp); |
1109 | in6_dev_put(idev); | 1116 | in6_dev_put(idev); |
1110 | ret = -1; | 1117 | ret = -1; |
@@ -1601,7 +1608,7 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
1601 | { | 1608 | { |
1602 | if (ifp->flags&IFA_F_PERMANENT) { | 1609 | if (ifp->flags&IFA_F_PERMANENT) { |
1603 | spin_lock_bh(&ifp->lock); | 1610 | spin_lock_bh(&ifp->lock); |
1604 | addrconf_del_dad_timer(ifp); | 1611 | addrconf_del_dad_work(ifp); |
1605 | ifp->flags |= IFA_F_TENTATIVE; | 1612 | ifp->flags |= IFA_F_TENTATIVE; |
1606 | if (dad_failed) | 1613 | if (dad_failed) |
1607 | ifp->flags |= IFA_F_DADFAILED; | 1614 | ifp->flags |= IFA_F_DADFAILED; |
@@ -1622,20 +1629,21 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
1622 | spin_unlock_bh(&ifp->lock); | 1629 | spin_unlock_bh(&ifp->lock); |
1623 | } | 1630 | } |
1624 | ipv6_del_addr(ifp); | 1631 | ipv6_del_addr(ifp); |
1625 | } else | 1632 | } else { |
1626 | ipv6_del_addr(ifp); | 1633 | ipv6_del_addr(ifp); |
1634 | } | ||
1627 | } | 1635 | } |
1628 | 1636 | ||
1629 | static int addrconf_dad_end(struct inet6_ifaddr *ifp) | 1637 | static int addrconf_dad_end(struct inet6_ifaddr *ifp) |
1630 | { | 1638 | { |
1631 | int err = -ENOENT; | 1639 | int err = -ENOENT; |
1632 | 1640 | ||
1633 | spin_lock(&ifp->state_lock); | 1641 | spin_lock_bh(&ifp->state_lock); |
1634 | if (ifp->state == INET6_IFADDR_STATE_DAD) { | 1642 | if (ifp->state == INET6_IFADDR_STATE_DAD) { |
1635 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | 1643 | ifp->state = INET6_IFADDR_STATE_POSTDAD; |
1636 | err = 0; | 1644 | err = 0; |
1637 | } | 1645 | } |
1638 | spin_unlock(&ifp->state_lock); | 1646 | spin_unlock_bh(&ifp->state_lock); |
1639 | 1647 | ||
1640 | return err; | 1648 | return err; |
1641 | } | 1649 | } |
@@ -1668,7 +1676,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1668 | } | 1676 | } |
1669 | } | 1677 | } |
1670 | 1678 | ||
1671 | addrconf_dad_stop(ifp, 1); | 1679 | spin_lock_bh(&ifp->state_lock); |
1680 | /* transition from _POSTDAD to _ERRDAD */ | ||
1681 | ifp->state = INET6_IFADDR_STATE_ERRDAD; | ||
1682 | spin_unlock_bh(&ifp->state_lock); | ||
1683 | |||
1684 | addrconf_mod_dad_work(ifp, 0); | ||
1672 | } | 1685 | } |
1673 | 1686 | ||
1674 | /* Join to solicited addr multicast group. */ | 1687 | /* Join to solicited addr multicast group. */ |
@@ -1677,6 +1690,8 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr) | |||
1677 | { | 1690 | { |
1678 | struct in6_addr maddr; | 1691 | struct in6_addr maddr; |
1679 | 1692 | ||
1693 | ASSERT_RTNL(); | ||
1694 | |||
1680 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1695 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
1681 | return; | 1696 | return; |
1682 | 1697 | ||
@@ -1688,6 +1703,8 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
1688 | { | 1703 | { |
1689 | struct in6_addr maddr; | 1704 | struct in6_addr maddr; |
1690 | 1705 | ||
1706 | ASSERT_RTNL(); | ||
1707 | |||
1691 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1708 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
1692 | return; | 1709 | return; |
1693 | 1710 | ||
@@ -1698,6 +1715,9 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
1698 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1715 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
1699 | { | 1716 | { |
1700 | struct in6_addr addr; | 1717 | struct in6_addr addr; |
1718 | |||
1719 | ASSERT_RTNL(); | ||
1720 | |||
1701 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1721 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1702 | return; | 1722 | return; |
1703 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1723 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
@@ -1709,6 +1729,9 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
1709 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1729 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
1710 | { | 1730 | { |
1711 | struct in6_addr addr; | 1731 | struct in6_addr addr; |
1732 | |||
1733 | ASSERT_RTNL(); | ||
1734 | |||
1712 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1735 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1713 | return; | 1736 | return; |
1714 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1737 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
@@ -2268,11 +2291,13 @@ ok: | |||
2268 | return; | 2291 | return; |
2269 | } | 2292 | } |
2270 | 2293 | ||
2271 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
2272 | update_lft = 0; | 2294 | update_lft = 0; |
2273 | create = 1; | 2295 | create = 1; |
2296 | spin_lock_bh(&ifp->lock); | ||
2297 | ifp->flags |= IFA_F_MANAGETEMPADDR; | ||
2274 | ifp->cstamp = jiffies; | 2298 | ifp->cstamp = jiffies; |
2275 | ifp->tokenized = tokenized; | 2299 | ifp->tokenized = tokenized; |
2300 | spin_unlock_bh(&ifp->lock); | ||
2276 | addrconf_dad_start(ifp); | 2301 | addrconf_dad_start(ifp); |
2277 | } | 2302 | } |
2278 | 2303 | ||
@@ -2323,7 +2348,7 @@ ok: | |||
2323 | create, now); | 2348 | create, now); |
2324 | 2349 | ||
2325 | in6_ifa_put(ifp); | 2350 | in6_ifa_put(ifp); |
2326 | addrconf_verify(0); | 2351 | addrconf_verify(); |
2327 | } | 2352 | } |
2328 | } | 2353 | } |
2329 | inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo); | 2354 | inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo); |
@@ -2472,7 +2497,7 @@ static int inet6_addr_add(struct net *net, int ifindex, | |||
2472 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, | 2497 | manage_tempaddrs(idev, ifp, valid_lft, prefered_lft, |
2473 | true, jiffies); | 2498 | true, jiffies); |
2474 | in6_ifa_put(ifp); | 2499 | in6_ifa_put(ifp); |
2475 | addrconf_verify(0); | 2500 | addrconf_verify_rtnl(); |
2476 | return 0; | 2501 | return 0; |
2477 | } | 2502 | } |
2478 | 2503 | ||
@@ -3008,7 +3033,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
3008 | hlist_for_each_entry_rcu(ifa, h, addr_lst) { | 3033 | hlist_for_each_entry_rcu(ifa, h, addr_lst) { |
3009 | if (ifa->idev == idev) { | 3034 | if (ifa->idev == idev) { |
3010 | hlist_del_init_rcu(&ifa->addr_lst); | 3035 | hlist_del_init_rcu(&ifa->addr_lst); |
3011 | addrconf_del_dad_timer(ifa); | 3036 | addrconf_del_dad_work(ifa); |
3012 | goto restart; | 3037 | goto restart; |
3013 | } | 3038 | } |
3014 | } | 3039 | } |
@@ -3046,7 +3071,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
3046 | while (!list_empty(&idev->addr_list)) { | 3071 | while (!list_empty(&idev->addr_list)) { |
3047 | ifa = list_first_entry(&idev->addr_list, | 3072 | ifa = list_first_entry(&idev->addr_list, |
3048 | struct inet6_ifaddr, if_list); | 3073 | struct inet6_ifaddr, if_list); |
3049 | addrconf_del_dad_timer(ifa); | 3074 | addrconf_del_dad_work(ifa); |
3050 | 3075 | ||
3051 | list_del(&ifa->if_list); | 3076 | list_del(&ifa->if_list); |
3052 | 3077 | ||
@@ -3145,10 +3170,10 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | |||
3145 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); | 3170 | rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1); |
3146 | 3171 | ||
3147 | ifp->dad_probes = idev->cnf.dad_transmits; | 3172 | ifp->dad_probes = idev->cnf.dad_transmits; |
3148 | addrconf_mod_dad_timer(ifp, rand_num); | 3173 | addrconf_mod_dad_work(ifp, rand_num); |
3149 | } | 3174 | } |
3150 | 3175 | ||
3151 | static void addrconf_dad_start(struct inet6_ifaddr *ifp) | 3176 | static void addrconf_dad_begin(struct inet6_ifaddr *ifp) |
3152 | { | 3177 | { |
3153 | struct inet6_dev *idev = ifp->idev; | 3178 | struct inet6_dev *idev = ifp->idev; |
3154 | struct net_device *dev = idev->dev; | 3179 | struct net_device *dev = idev->dev; |
@@ -3200,25 +3225,68 @@ out: | |||
3200 | read_unlock_bh(&idev->lock); | 3225 | read_unlock_bh(&idev->lock); |
3201 | } | 3226 | } |
3202 | 3227 | ||
3203 | static void addrconf_dad_timer(unsigned long data) | 3228 | static void addrconf_dad_start(struct inet6_ifaddr *ifp) |
3204 | { | 3229 | { |
3205 | struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; | 3230 | bool begin_dad = false; |
3231 | |||
3232 | spin_lock_bh(&ifp->state_lock); | ||
3233 | if (ifp->state != INET6_IFADDR_STATE_DEAD) { | ||
3234 | ifp->state = INET6_IFADDR_STATE_PREDAD; | ||
3235 | begin_dad = true; | ||
3236 | } | ||
3237 | spin_unlock_bh(&ifp->state_lock); | ||
3238 | |||
3239 | if (begin_dad) | ||
3240 | addrconf_mod_dad_work(ifp, 0); | ||
3241 | } | ||
3242 | |||
3243 | static void addrconf_dad_work(struct work_struct *w) | ||
3244 | { | ||
3245 | struct inet6_ifaddr *ifp = container_of(to_delayed_work(w), | ||
3246 | struct inet6_ifaddr, | ||
3247 | dad_work); | ||
3206 | struct inet6_dev *idev = ifp->idev; | 3248 | struct inet6_dev *idev = ifp->idev; |
3207 | struct in6_addr mcaddr; | 3249 | struct in6_addr mcaddr; |
3208 | 3250 | ||
3251 | enum { | ||
3252 | DAD_PROCESS, | ||
3253 | DAD_BEGIN, | ||
3254 | DAD_ABORT, | ||
3255 | } action = DAD_PROCESS; | ||
3256 | |||
3257 | rtnl_lock(); | ||
3258 | |||
3259 | spin_lock_bh(&ifp->state_lock); | ||
3260 | if (ifp->state == INET6_IFADDR_STATE_PREDAD) { | ||
3261 | action = DAD_BEGIN; | ||
3262 | ifp->state = INET6_IFADDR_STATE_DAD; | ||
3263 | } else if (ifp->state == INET6_IFADDR_STATE_ERRDAD) { | ||
3264 | action = DAD_ABORT; | ||
3265 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | ||
3266 | } | ||
3267 | spin_unlock_bh(&ifp->state_lock); | ||
3268 | |||
3269 | if (action == DAD_BEGIN) { | ||
3270 | addrconf_dad_begin(ifp); | ||
3271 | goto out; | ||
3272 | } else if (action == DAD_ABORT) { | ||
3273 | addrconf_dad_stop(ifp, 1); | ||
3274 | goto out; | ||
3275 | } | ||
3276 | |||
3209 | if (!ifp->dad_probes && addrconf_dad_end(ifp)) | 3277 | if (!ifp->dad_probes && addrconf_dad_end(ifp)) |
3210 | goto out; | 3278 | goto out; |
3211 | 3279 | ||
3212 | write_lock(&idev->lock); | 3280 | write_lock_bh(&idev->lock); |
3213 | if (idev->dead || !(idev->if_flags & IF_READY)) { | 3281 | if (idev->dead || !(idev->if_flags & IF_READY)) { |
3214 | write_unlock(&idev->lock); | 3282 | write_unlock_bh(&idev->lock); |
3215 | goto out; | 3283 | goto out; |
3216 | } | 3284 | } |
3217 | 3285 | ||
3218 | spin_lock(&ifp->lock); | 3286 | spin_lock(&ifp->lock); |
3219 | if (ifp->state == INET6_IFADDR_STATE_DEAD) { | 3287 | if (ifp->state == INET6_IFADDR_STATE_DEAD) { |
3220 | spin_unlock(&ifp->lock); | 3288 | spin_unlock(&ifp->lock); |
3221 | write_unlock(&idev->lock); | 3289 | write_unlock_bh(&idev->lock); |
3222 | goto out; | 3290 | goto out; |
3223 | } | 3291 | } |
3224 | 3292 | ||
@@ -3229,7 +3297,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
3229 | 3297 | ||
3230 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); | 3298 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); |
3231 | spin_unlock(&ifp->lock); | 3299 | spin_unlock(&ifp->lock); |
3232 | write_unlock(&idev->lock); | 3300 | write_unlock_bh(&idev->lock); |
3233 | 3301 | ||
3234 | addrconf_dad_completed(ifp); | 3302 | addrconf_dad_completed(ifp); |
3235 | 3303 | ||
@@ -3237,16 +3305,17 @@ static void addrconf_dad_timer(unsigned long data) | |||
3237 | } | 3305 | } |
3238 | 3306 | ||
3239 | ifp->dad_probes--; | 3307 | ifp->dad_probes--; |
3240 | addrconf_mod_dad_timer(ifp, | 3308 | addrconf_mod_dad_work(ifp, |
3241 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); | 3309 | NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); |
3242 | spin_unlock(&ifp->lock); | 3310 | spin_unlock(&ifp->lock); |
3243 | write_unlock(&idev->lock); | 3311 | write_unlock_bh(&idev->lock); |
3244 | 3312 | ||
3245 | /* send a neighbour solicitation for our addr */ | 3313 | /* send a neighbour solicitation for our addr */ |
3246 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); | 3314 | addrconf_addr_solict_mult(&ifp->addr, &mcaddr); |
3247 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); | 3315 | ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any); |
3248 | out: | 3316 | out: |
3249 | in6_ifa_put(ifp); | 3317 | in6_ifa_put(ifp); |
3318 | rtnl_unlock(); | ||
3250 | } | 3319 | } |
3251 | 3320 | ||
3252 | /* ifp->idev must be at least read locked */ | 3321 | /* ifp->idev must be at least read locked */ |
@@ -3273,7 +3342,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
3273 | struct in6_addr lladdr; | 3342 | struct in6_addr lladdr; |
3274 | bool send_rs, send_mld; | 3343 | bool send_rs, send_mld; |
3275 | 3344 | ||
3276 | addrconf_del_dad_timer(ifp); | 3345 | addrconf_del_dad_work(ifp); |
3277 | 3346 | ||
3278 | /* | 3347 | /* |
3279 | * Configure the address for reception. Now it is valid. | 3348 | * Configure the address for reception. Now it is valid. |
@@ -3514,23 +3583,23 @@ int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) | |||
3514 | * Periodic address status verification | 3583 | * Periodic address status verification |
3515 | */ | 3584 | */ |
3516 | 3585 | ||
3517 | static void addrconf_verify(unsigned long foo) | 3586 | static void addrconf_verify_rtnl(void) |
3518 | { | 3587 | { |
3519 | unsigned long now, next, next_sec, next_sched; | 3588 | unsigned long now, next, next_sec, next_sched; |
3520 | struct inet6_ifaddr *ifp; | 3589 | struct inet6_ifaddr *ifp; |
3521 | int i; | 3590 | int i; |
3522 | 3591 | ||
3592 | ASSERT_RTNL(); | ||
3593 | |||
3523 | rcu_read_lock_bh(); | 3594 | rcu_read_lock_bh(); |
3524 | spin_lock(&addrconf_verify_lock); | ||
3525 | now = jiffies; | 3595 | now = jiffies; |
3526 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); | 3596 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); |
3527 | 3597 | ||
3528 | del_timer(&addr_chk_timer); | 3598 | cancel_delayed_work(&addr_chk_work); |
3529 | 3599 | ||
3530 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | 3600 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { |
3531 | restart: | 3601 | restart: |
3532 | hlist_for_each_entry_rcu_bh(ifp, | 3602 | hlist_for_each_entry_rcu_bh(ifp, &inet6_addr_lst[i], addr_lst) { |
3533 | &inet6_addr_lst[i], addr_lst) { | ||
3534 | unsigned long age; | 3603 | unsigned long age; |
3535 | 3604 | ||
3536 | /* When setting preferred_lft to a value not zero or | 3605 | /* When setting preferred_lft to a value not zero or |
@@ -3625,13 +3694,22 @@ restart: | |||
3625 | 3694 | ||
3626 | ADBG(KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n", | 3695 | ADBG(KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n", |
3627 | now, next, next_sec, next_sched); | 3696 | now, next, next_sec, next_sched); |
3628 | 3697 | mod_delayed_work(addrconf_wq, &addr_chk_work, next_sched - now); | |
3629 | addr_chk_timer.expires = next_sched; | ||
3630 | add_timer(&addr_chk_timer); | ||
3631 | spin_unlock(&addrconf_verify_lock); | ||
3632 | rcu_read_unlock_bh(); | 3698 | rcu_read_unlock_bh(); |
3633 | } | 3699 | } |
3634 | 3700 | ||
3701 | static void addrconf_verify_work(struct work_struct *w) | ||
3702 | { | ||
3703 | rtnl_lock(); | ||
3704 | addrconf_verify_rtnl(); | ||
3705 | rtnl_unlock(); | ||
3706 | } | ||
3707 | |||
3708 | static void addrconf_verify(void) | ||
3709 | { | ||
3710 | mod_delayed_work(addrconf_wq, &addr_chk_work, 0); | ||
3711 | } | ||
3712 | |||
3635 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local, | 3713 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local, |
3636 | struct in6_addr **peer_pfx) | 3714 | struct in6_addr **peer_pfx) |
3637 | { | 3715 | { |
@@ -3688,6 +3766,8 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | |||
3688 | bool was_managetempaddr; | 3766 | bool was_managetempaddr; |
3689 | bool had_prefixroute; | 3767 | bool had_prefixroute; |
3690 | 3768 | ||
3769 | ASSERT_RTNL(); | ||
3770 | |||
3691 | if (!valid_lft || (prefered_lft > valid_lft)) | 3771 | if (!valid_lft || (prefered_lft > valid_lft)) |
3692 | return -EINVAL; | 3772 | return -EINVAL; |
3693 | 3773 | ||
@@ -3753,7 +3833,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags, | |||
3753 | !was_managetempaddr, jiffies); | 3833 | !was_managetempaddr, jiffies); |
3754 | } | 3834 | } |
3755 | 3835 | ||
3756 | addrconf_verify(0); | 3836 | addrconf_verify_rtnl(); |
3757 | 3837 | ||
3758 | return 0; | 3838 | return 0; |
3759 | } | 3839 | } |
@@ -4383,6 +4463,8 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
4383 | bool update_rs = false; | 4463 | bool update_rs = false; |
4384 | struct in6_addr ll_addr; | 4464 | struct in6_addr ll_addr; |
4385 | 4465 | ||
4466 | ASSERT_RTNL(); | ||
4467 | |||
4386 | if (token == NULL) | 4468 | if (token == NULL) |
4387 | return -EINVAL; | 4469 | return -EINVAL; |
4388 | if (ipv6_addr_any(token)) | 4470 | if (ipv6_addr_any(token)) |
@@ -4431,7 +4513,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
4431 | } | 4513 | } |
4432 | 4514 | ||
4433 | write_unlock_bh(&idev->lock); | 4515 | write_unlock_bh(&idev->lock); |
4434 | addrconf_verify(0); | 4516 | addrconf_verify_rtnl(); |
4435 | return 0; | 4517 | return 0; |
4436 | } | 4518 | } |
4437 | 4519 | ||
@@ -4633,6 +4715,9 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4633 | { | 4715 | { |
4634 | struct net *net = dev_net(ifp->idev->dev); | 4716 | struct net *net = dev_net(ifp->idev->dev); |
4635 | 4717 | ||
4718 | if (event) | ||
4719 | ASSERT_RTNL(); | ||
4720 | |||
4636 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); | 4721 | inet6_ifa_notify(event ? : RTM_NEWADDR, ifp); |
4637 | 4722 | ||
4638 | switch (event) { | 4723 | switch (event) { |
@@ -5241,6 +5326,12 @@ int __init addrconf_init(void) | |||
5241 | if (err < 0) | 5326 | if (err < 0) |
5242 | goto out_addrlabel; | 5327 | goto out_addrlabel; |
5243 | 5328 | ||
5329 | addrconf_wq = create_workqueue("ipv6_addrconf"); | ||
5330 | if (!addrconf_wq) { | ||
5331 | err = -ENOMEM; | ||
5332 | goto out_nowq; | ||
5333 | } | ||
5334 | |||
5244 | /* The addrconf netdev notifier requires that loopback_dev | 5335 | /* The addrconf netdev notifier requires that loopback_dev |
5245 | * has it's ipv6 private information allocated and setup | 5336 | * has it's ipv6 private information allocated and setup |
5246 | * before it can bring up and give link-local addresses | 5337 | * before it can bring up and give link-local addresses |
@@ -5271,7 +5362,7 @@ int __init addrconf_init(void) | |||
5271 | 5362 | ||
5272 | register_netdevice_notifier(&ipv6_dev_notf); | 5363 | register_netdevice_notifier(&ipv6_dev_notf); |
5273 | 5364 | ||
5274 | addrconf_verify(0); | 5365 | addrconf_verify(); |
5275 | 5366 | ||
5276 | rtnl_af_register(&inet6_ops); | 5367 | rtnl_af_register(&inet6_ops); |
5277 | 5368 | ||
@@ -5299,6 +5390,8 @@ errout: | |||
5299 | rtnl_af_unregister(&inet6_ops); | 5390 | rtnl_af_unregister(&inet6_ops); |
5300 | unregister_netdevice_notifier(&ipv6_dev_notf); | 5391 | unregister_netdevice_notifier(&ipv6_dev_notf); |
5301 | errlo: | 5392 | errlo: |
5393 | destroy_workqueue(addrconf_wq); | ||
5394 | out_nowq: | ||
5302 | unregister_pernet_subsys(&addrconf_ops); | 5395 | unregister_pernet_subsys(&addrconf_ops); |
5303 | out_addrlabel: | 5396 | out_addrlabel: |
5304 | ipv6_addr_label_cleanup(); | 5397 | ipv6_addr_label_cleanup(); |
@@ -5334,7 +5427,8 @@ void addrconf_cleanup(void) | |||
5334 | for (i = 0; i < IN6_ADDR_HSIZE; i++) | 5427 | for (i = 0; i < IN6_ADDR_HSIZE; i++) |
5335 | WARN_ON(!hlist_empty(&inet6_addr_lst[i])); | 5428 | WARN_ON(!hlist_empty(&inet6_addr_lst[i])); |
5336 | spin_unlock_bh(&addrconf_hash_lock); | 5429 | spin_unlock_bh(&addrconf_hash_lock); |
5337 | 5430 | cancel_delayed_work(&addr_chk_work); | |
5338 | del_timer(&addr_chk_timer); | ||
5339 | rtnl_unlock(); | 5431 | rtnl_unlock(); |
5432 | |||
5433 | destroy_workqueue(addrconf_wq); | ||
5340 | } | 5434 | } |
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 140748debc4a..8af3eb57f438 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c | |||
@@ -212,7 +212,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
212 | found = (nexthdr == target); | 212 | found = (nexthdr == target); |
213 | 213 | ||
214 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { | 214 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { |
215 | if (target < 0) | 215 | if (target < 0 || found) |
216 | break; | 216 | break; |
217 | return -ENOENT; | 217 | return -ENOENT; |
218 | } | 218 | } |
diff --git a/net/ipv6/exthdrs_offload.c b/net/ipv6/exthdrs_offload.c index cf77f3abfd06..447a7fbd1bb6 100644 --- a/net/ipv6/exthdrs_offload.c +++ b/net/ipv6/exthdrs_offload.c | |||
@@ -25,11 +25,11 @@ int __init ipv6_exthdrs_offload_init(void) | |||
25 | int ret; | 25 | int ret; |
26 | 26 | ||
27 | ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); | 27 | ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); |
28 | if (!ret) | 28 | if (ret) |
29 | goto out; | 29 | goto out; |
30 | 30 | ||
31 | ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); | 31 | ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); |
32 | if (!ret) | 32 | if (ret) |
33 | goto out_rt; | 33 | goto out_rt; |
34 | 34 | ||
35 | out: | 35 | out: |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 1e8683b135bb..59f95affceb0 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -89,7 +89,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
89 | unsigned int unfrag_ip6hlen; | 89 | unsigned int unfrag_ip6hlen; |
90 | u8 *prevhdr; | 90 | u8 *prevhdr; |
91 | int offset = 0; | 91 | int offset = 0; |
92 | bool tunnel; | 92 | bool encap, udpfrag; |
93 | int nhoff; | 93 | int nhoff; |
94 | 94 | ||
95 | if (unlikely(skb_shinfo(skb)->gso_type & | 95 | if (unlikely(skb_shinfo(skb)->gso_type & |
@@ -110,8 +110,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
110 | if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) | 110 | if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) |
111 | goto out; | 111 | goto out; |
112 | 112 | ||
113 | tunnel = SKB_GSO_CB(skb)->encap_level > 0; | 113 | encap = SKB_GSO_CB(skb)->encap_level > 0; |
114 | if (tunnel) | 114 | if (encap) |
115 | features = skb->dev->hw_enc_features & netif_skb_features(skb); | 115 | features = skb->dev->hw_enc_features & netif_skb_features(skb); |
116 | SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h); | 116 | SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h); |
117 | 117 | ||
@@ -121,6 +121,12 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
121 | 121 | ||
122 | proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr); | 122 | proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr); |
123 | 123 | ||
124 | if (skb->encapsulation && | ||
125 | skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP)) | ||
126 | udpfrag = proto == IPPROTO_UDP && encap; | ||
127 | else | ||
128 | udpfrag = proto == IPPROTO_UDP && !skb->encapsulation; | ||
129 | |||
124 | ops = rcu_dereference(inet6_offloads[proto]); | 130 | ops = rcu_dereference(inet6_offloads[proto]); |
125 | if (likely(ops && ops->callbacks.gso_segment)) { | 131 | if (likely(ops && ops->callbacks.gso_segment)) { |
126 | skb_reset_transport_header(skb); | 132 | skb_reset_transport_header(skb); |
@@ -133,13 +139,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
133 | for (skb = segs; skb; skb = skb->next) { | 139 | for (skb = segs; skb; skb = skb->next) { |
134 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); | 140 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); |
135 | ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h)); | 141 | ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h)); |
136 | if (tunnel) { | ||
137 | skb_reset_inner_headers(skb); | ||
138 | skb->encapsulation = 1; | ||
139 | } | ||
140 | skb->network_header = (u8 *)ipv6h - skb->head; | 142 | skb->network_header = (u8 *)ipv6h - skb->head; |
141 | 143 | ||
142 | if (!tunnel && proto == IPPROTO_UDP) { | 144 | if (udpfrag) { |
143 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | 145 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
144 | fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); | 146 | fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); |
145 | fptr->frag_off = htons(offset); | 147 | fptr->frag_off = htons(offset); |
@@ -148,6 +150,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
148 | offset += (ntohs(ipv6h->payload_len) - | 150 | offset += (ntohs(ipv6h->payload_len) - |
149 | sizeof(struct frag_hdr)); | 151 | sizeof(struct frag_hdr)); |
150 | } | 152 | } |
153 | if (encap) | ||
154 | skb_reset_inner_headers(skb); | ||
151 | } | 155 | } |
152 | 156 | ||
153 | out: | 157 | out: |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 070a2fae2375..64d6073731d3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -530,9 +530,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
530 | to->tc_index = from->tc_index; | 530 | to->tc_index = from->tc_index; |
531 | #endif | 531 | #endif |
532 | nf_copy(to, from); | 532 | nf_copy(to, from); |
533 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) | ||
534 | to->nf_trace = from->nf_trace; | ||
535 | #endif | ||
536 | skb_copy_secmark(to, from); | 533 | skb_copy_secmark(to, from); |
537 | } | 534 | } |
538 | 535 | ||
@@ -1104,21 +1101,19 @@ static void ip6_append_data_mtu(unsigned int *mtu, | |||
1104 | unsigned int fragheaderlen, | 1101 | unsigned int fragheaderlen, |
1105 | struct sk_buff *skb, | 1102 | struct sk_buff *skb, |
1106 | struct rt6_info *rt, | 1103 | struct rt6_info *rt, |
1107 | bool pmtuprobe) | 1104 | unsigned int orig_mtu) |
1108 | { | 1105 | { |
1109 | if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { | 1106 | if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { |
1110 | if (skb == NULL) { | 1107 | if (skb == NULL) { |
1111 | /* first fragment, reserve header_len */ | 1108 | /* first fragment, reserve header_len */ |
1112 | *mtu = *mtu - rt->dst.header_len; | 1109 | *mtu = orig_mtu - rt->dst.header_len; |
1113 | 1110 | ||
1114 | } else { | 1111 | } else { |
1115 | /* | 1112 | /* |
1116 | * this fragment is not first, the headers | 1113 | * this fragment is not first, the headers |
1117 | * space is regarded as data space. | 1114 | * space is regarded as data space. |
1118 | */ | 1115 | */ |
1119 | *mtu = min(*mtu, pmtuprobe ? | 1116 | *mtu = orig_mtu; |
1120 | rt->dst.dev->mtu : | ||
1121 | dst_mtu(rt->dst.path)); | ||
1122 | } | 1117 | } |
1123 | *maxfraglen = ((*mtu - fragheaderlen) & ~7) | 1118 | *maxfraglen = ((*mtu - fragheaderlen) & ~7) |
1124 | + fragheaderlen - sizeof(struct frag_hdr); | 1119 | + fragheaderlen - sizeof(struct frag_hdr); |
@@ -1135,7 +1130,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1135 | struct ipv6_pinfo *np = inet6_sk(sk); | 1130 | struct ipv6_pinfo *np = inet6_sk(sk); |
1136 | struct inet_cork *cork; | 1131 | struct inet_cork *cork; |
1137 | struct sk_buff *skb, *skb_prev = NULL; | 1132 | struct sk_buff *skb, *skb_prev = NULL; |
1138 | unsigned int maxfraglen, fragheaderlen, mtu; | 1133 | unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; |
1139 | int exthdrlen; | 1134 | int exthdrlen; |
1140 | int dst_exthdrlen; | 1135 | int dst_exthdrlen; |
1141 | int hh_len; | 1136 | int hh_len; |
@@ -1217,6 +1212,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1217 | dst_exthdrlen = 0; | 1212 | dst_exthdrlen = 0; |
1218 | mtu = cork->fragsize; | 1213 | mtu = cork->fragsize; |
1219 | } | 1214 | } |
1215 | orig_mtu = mtu; | ||
1220 | 1216 | ||
1221 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); | 1217 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
1222 | 1218 | ||
@@ -1314,8 +1310,7 @@ alloc_new_skb: | |||
1314 | if (skb == NULL || skb_prev == NULL) | 1310 | if (skb == NULL || skb_prev == NULL) |
1315 | ip6_append_data_mtu(&mtu, &maxfraglen, | 1311 | ip6_append_data_mtu(&mtu, &maxfraglen, |
1316 | fragheaderlen, skb, rt, | 1312 | fragheaderlen, skb, rt, |
1317 | np->pmtudisc >= | 1313 | orig_mtu); |
1318 | IPV6_PMTUDISC_PROBE); | ||
1319 | 1314 | ||
1320 | skb_prev = skb; | 1315 | skb_prev = skb; |
1321 | 1316 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 0eb4038a4d63..8737400af0a0 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -2349,13 +2349,14 @@ int ip6mr_get_route(struct net *net, | |||
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | 2351 | static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, |
2352 | u32 portid, u32 seq, struct mfc6_cache *c, int cmd) | 2352 | u32 portid, u32 seq, struct mfc6_cache *c, int cmd, |
2353 | int flags) | ||
2353 | { | 2354 | { |
2354 | struct nlmsghdr *nlh; | 2355 | struct nlmsghdr *nlh; |
2355 | struct rtmsg *rtm; | 2356 | struct rtmsg *rtm; |
2356 | int err; | 2357 | int err; |
2357 | 2358 | ||
2358 | nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), NLM_F_MULTI); | 2359 | nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags); |
2359 | if (nlh == NULL) | 2360 | if (nlh == NULL) |
2360 | return -EMSGSIZE; | 2361 | return -EMSGSIZE; |
2361 | 2362 | ||
@@ -2423,7 +2424,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc, | |||
2423 | if (skb == NULL) | 2424 | if (skb == NULL) |
2424 | goto errout; | 2425 | goto errout; |
2425 | 2426 | ||
2426 | err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd); | 2427 | err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0); |
2427 | if (err < 0) | 2428 | if (err < 0) |
2428 | goto errout; | 2429 | goto errout; |
2429 | 2430 | ||
@@ -2462,7 +2463,8 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) | |||
2462 | if (ip6mr_fill_mroute(mrt, skb, | 2463 | if (ip6mr_fill_mroute(mrt, skb, |
2463 | NETLINK_CB(cb->skb).portid, | 2464 | NETLINK_CB(cb->skb).portid, |
2464 | cb->nlh->nlmsg_seq, | 2465 | cb->nlh->nlmsg_seq, |
2465 | mfc, RTM_NEWROUTE) < 0) | 2466 | mfc, RTM_NEWROUTE, |
2467 | NLM_F_MULTI) < 0) | ||
2466 | goto done; | 2468 | goto done; |
2467 | next_entry: | 2469 | next_entry: |
2468 | e++; | 2470 | e++; |
@@ -2476,7 +2478,8 @@ next_entry: | |||
2476 | if (ip6mr_fill_mroute(mrt, skb, | 2478 | if (ip6mr_fill_mroute(mrt, skb, |
2477 | NETLINK_CB(cb->skb).portid, | 2479 | NETLINK_CB(cb->skb).portid, |
2478 | cb->nlh->nlmsg_seq, | 2480 | cb->nlh->nlmsg_seq, |
2479 | mfc, RTM_NEWROUTE) < 0) { | 2481 | mfc, RTM_NEWROUTE, |
2482 | NLM_F_MULTI) < 0) { | ||
2480 | spin_unlock_bh(&mfc_unres_lock); | 2483 | spin_unlock_bh(&mfc_unres_lock); |
2481 | goto done; | 2484 | goto done; |
2482 | } | 2485 | } |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index fb9beb78f00b..587bbdcb22b4 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
@@ -135,6 +135,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
135 | fl6.flowi6_proto = IPPROTO_ICMPV6; | 135 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
136 | fl6.saddr = np->saddr; | 136 | fl6.saddr = np->saddr; |
137 | fl6.daddr = *daddr; | 137 | fl6.daddr = *daddr; |
138 | fl6.flowi6_mark = sk->sk_mark; | ||
138 | fl6.fl6_icmp_type = user_icmph.icmp6_type; | 139 | fl6.fl6_icmp_type = user_icmph.icmp6_type; |
139 | fl6.fl6_icmp_code = user_icmph.icmp6_code; | 140 | fl6.fl6_icmp_code = user_icmph.icmp6_code; |
140 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 141 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 11dac21e6586..fba54a407bb2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1513,7 +1513,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1513 | if (!table) | 1513 | if (!table) |
1514 | goto out; | 1514 | goto out; |
1515 | 1515 | ||
1516 | rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table); | 1516 | rt = ip6_dst_alloc(net, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT, table); |
1517 | 1517 | ||
1518 | if (!rt) { | 1518 | if (!rt) { |
1519 | err = -ENOMEM; | 1519 | err = -ENOMEM; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3dfbcf1dcb1c..b4d74c86586c 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -475,6 +475,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
475 | ipip6_tunnel_unlink(sitn, tunnel); | 475 | ipip6_tunnel_unlink(sitn, tunnel); |
476 | ipip6_tunnel_del_prl(tunnel, NULL); | 476 | ipip6_tunnel_del_prl(tunnel, NULL); |
477 | } | 477 | } |
478 | ip_tunnel_dst_reset_all(tunnel); | ||
478 | dev_put(dev); | 479 | dev_put(dev); |
479 | } | 480 | } |
480 | 481 | ||
@@ -1082,6 +1083,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p) | |||
1082 | t->parms.link = p->link; | 1083 | t->parms.link = p->link; |
1083 | ipip6_tunnel_bind_dev(t->dev); | 1084 | ipip6_tunnel_bind_dev(t->dev); |
1084 | } | 1085 | } |
1086 | ip_tunnel_dst_reset_all(t); | ||
1085 | netdev_state_change(t->dev); | 1087 | netdev_state_change(t->dev); |
1086 | } | 1088 | } |
1087 | 1089 | ||
@@ -1112,6 +1114,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t, | |||
1112 | t->ip6rd.relay_prefix = relay_prefix; | 1114 | t->ip6rd.relay_prefix = relay_prefix; |
1113 | t->ip6rd.prefixlen = ip6rd->prefixlen; | 1115 | t->ip6rd.prefixlen = ip6rd->prefixlen; |
1114 | t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; | 1116 | t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; |
1117 | ip_tunnel_dst_reset_all(t); | ||
1115 | netdev_state_change(t->dev); | 1118 | netdev_state_change(t->dev); |
1116 | return 0; | 1119 | return 0; |
1117 | } | 1120 | } |
@@ -1271,6 +1274,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1271 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); | 1274 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); |
1272 | break; | 1275 | break; |
1273 | } | 1276 | } |
1277 | ip_tunnel_dst_reset_all(t); | ||
1274 | netdev_state_change(dev); | 1278 | netdev_state_change(dev); |
1275 | break; | 1279 | break; |
1276 | 1280 | ||
@@ -1326,6 +1330,9 @@ static const struct net_device_ops ipip6_netdev_ops = { | |||
1326 | 1330 | ||
1327 | static void ipip6_dev_free(struct net_device *dev) | 1331 | static void ipip6_dev_free(struct net_device *dev) |
1328 | { | 1332 | { |
1333 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
1334 | |||
1335 | free_percpu(tunnel->dst_cache); | ||
1329 | free_percpu(dev->tstats); | 1336 | free_percpu(dev->tstats); |
1330 | free_netdev(dev); | 1337 | free_netdev(dev); |
1331 | } | 1338 | } |
@@ -1375,6 +1382,12 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
1375 | u64_stats_init(&ipip6_tunnel_stats->syncp); | 1382 | u64_stats_init(&ipip6_tunnel_stats->syncp); |
1376 | } | 1383 | } |
1377 | 1384 | ||
1385 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | ||
1386 | if (!tunnel->dst_cache) { | ||
1387 | free_percpu(dev->tstats); | ||
1388 | return -ENOMEM; | ||
1389 | } | ||
1390 | |||
1378 | return 0; | 1391 | return 0; |
1379 | } | 1392 | } |
1380 | 1393 | ||
@@ -1405,6 +1418,12 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1405 | u64_stats_init(&ipip6_fb_stats->syncp); | 1418 | u64_stats_init(&ipip6_fb_stats->syncp); |
1406 | } | 1419 | } |
1407 | 1420 | ||
1421 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | ||
1422 | if (!tunnel->dst_cache) { | ||
1423 | free_percpu(dev->tstats); | ||
1424 | return -ENOMEM; | ||
1425 | } | ||
1426 | |||
1408 | dev_hold(dev); | 1427 | dev_hold(dev); |
1409 | rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); | 1428 | rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); |
1410 | return 0; | 1429 | return 0; |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index e7359f9eaa8d..b261ee8b83fc 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -113,7 +113,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
113 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); | 113 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); |
114 | fptr->nexthdr = nexthdr; | 114 | fptr->nexthdr = nexthdr; |
115 | fptr->reserved = 0; | 115 | fptr->reserved = 0; |
116 | ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); | 116 | fptr->identification = skb_shinfo(skb)->ip6_frag_id; |
117 | 117 | ||
118 | /* Fragment the skb. ipv6 header and the remaining fields of the | 118 | /* Fragment the skb. ipv6 header and the remaining fields of the |
119 | * fragment header are updated in ipv6_gso_segment() | 119 | * fragment header are updated in ipv6_gso_segment() |