diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c2e2a78787ec..96861c702c06 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1399,10 +1399,18 @@ static inline int ipv6_saddr_preferred(int type) | |||
1399 | return 0; | 1399 | return 0; |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) | 1402 | static bool ipv6_use_optimistic_addr(struct net *net, |
1403 | struct inet6_dev *idev) | ||
1403 | { | 1404 | { |
1404 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 1405 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
1405 | return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; | 1406 | if (!idev) |
1407 | return false; | ||
1408 | if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad) | ||
1409 | return false; | ||
1410 | if (!net->ipv6.devconf_all->use_optimistic && !idev->cnf.use_optimistic) | ||
1411 | return false; | ||
1412 | |||
1413 | return true; | ||
1406 | #else | 1414 | #else |
1407 | return false; | 1415 | return false; |
1408 | #endif | 1416 | #endif |
@@ -1472,7 +1480,7 @@ static int ipv6_get_saddr_eval(struct net *net, | |||
1472 | /* Rule 3: Avoid deprecated and optimistic addresses */ | 1480 | /* Rule 3: Avoid deprecated and optimistic addresses */ |
1473 | u8 avoid = IFA_F_DEPRECATED; | 1481 | u8 avoid = IFA_F_DEPRECATED; |
1474 | 1482 | ||
1475 | if (!ipv6_use_optimistic_addr(score->ifa->idev)) | 1483 | if (!ipv6_use_optimistic_addr(net, score->ifa->idev)) |
1476 | avoid |= IFA_F_OPTIMISTIC; | 1484 | avoid |= IFA_F_OPTIMISTIC; |
1477 | ret = ipv6_saddr_preferred(score->addr_type) || | 1485 | ret = ipv6_saddr_preferred(score->addr_type) || |
1478 | !(score->ifa->flags & avoid); | 1486 | !(score->ifa->flags & avoid); |
@@ -2460,7 +2468,8 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev, | |||
2460 | int max_addresses = in6_dev->cnf.max_addresses; | 2468 | int max_addresses = in6_dev->cnf.max_addresses; |
2461 | 2469 | ||
2462 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 2470 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
2463 | if (in6_dev->cnf.optimistic_dad && | 2471 | if ((net->ipv6.devconf_all->optimistic_dad || |
2472 | in6_dev->cnf.optimistic_dad) && | ||
2464 | !net->ipv6.devconf_all->forwarding && sllao) | 2473 | !net->ipv6.devconf_all->forwarding && sllao) |
2465 | addr_flags |= IFA_F_OPTIMISTIC; | 2474 | addr_flags |= IFA_F_OPTIMISTIC; |
2466 | #endif | 2475 | #endif |
@@ -3051,7 +3060,8 @@ void addrconf_add_linklocal(struct inet6_dev *idev, | |||
3051 | u32 addr_flags = flags | IFA_F_PERMANENT; | 3060 | u32 addr_flags = flags | IFA_F_PERMANENT; |
3052 | 3061 | ||
3053 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 3062 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
3054 | if (idev->cnf.optimistic_dad && | 3063 | if ((dev_net(idev->dev)->ipv6.devconf_all->optimistic_dad || |
3064 | idev->cnf.optimistic_dad) && | ||
3055 | !dev_net(idev->dev)->ipv6.devconf_all->forwarding) | 3065 | !dev_net(idev->dev)->ipv6.devconf_all->forwarding) |
3056 | addr_flags |= IFA_F_OPTIMISTIC; | 3066 | addr_flags |= IFA_F_OPTIMISTIC; |
3057 | #endif | 3067 | #endif |
@@ -3810,6 +3820,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) | |||
3810 | goto out; | 3820 | goto out; |
3811 | 3821 | ||
3812 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || | 3822 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || |
3823 | dev_net(dev)->ipv6.devconf_all->accept_dad < 1 || | ||
3813 | idev->cnf.accept_dad < 1 || | 3824 | idev->cnf.accept_dad < 1 || |
3814 | !(ifp->flags&IFA_F_TENTATIVE) || | 3825 | !(ifp->flags&IFA_F_TENTATIVE) || |
3815 | ifp->flags & IFA_F_NODAD) { | 3826 | ifp->flags & IFA_F_NODAD) { |
@@ -3841,7 +3852,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) | |||
3841 | */ | 3852 | */ |
3842 | if (ifp->flags & IFA_F_OPTIMISTIC) { | 3853 | if (ifp->flags & IFA_F_OPTIMISTIC) { |
3843 | ip6_ins_rt(ifp->rt); | 3854 | ip6_ins_rt(ifp->rt); |
3844 | if (ipv6_use_optimistic_addr(idev)) { | 3855 | if (ipv6_use_optimistic_addr(dev_net(dev), idev)) { |
3845 | /* Because optimistic nodes can use this address, | 3856 | /* Because optimistic nodes can use this address, |
3846 | * notify listeners. If DAD fails, RTM_DELADDR is sent. | 3857 | * notify listeners. If DAD fails, RTM_DELADDR is sent. |
3847 | */ | 3858 | */ |
@@ -3897,7 +3908,9 @@ static void addrconf_dad_work(struct work_struct *w) | |||
3897 | action = DAD_ABORT; | 3908 | action = DAD_ABORT; |
3898 | ifp->state = INET6_IFADDR_STATE_POSTDAD; | 3909 | ifp->state = INET6_IFADDR_STATE_POSTDAD; |
3899 | 3910 | ||
3900 | if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6 && | 3911 | if ((dev_net(idev->dev)->ipv6.devconf_all->accept_dad > 1 || |
3912 | idev->cnf.accept_dad > 1) && | ||
3913 | !idev->cnf.disable_ipv6 && | ||
3901 | !(ifp->flags & IFA_F_STABLE_PRIVACY)) { | 3914 | !(ifp->flags & IFA_F_STABLE_PRIVACY)) { |
3902 | struct in6_addr addr; | 3915 | struct in6_addr addr; |
3903 | 3916 | ||
@@ -4940,9 +4953,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) | |||
4940 | 4953 | ||
4941 | /* Don't send DELADDR notification for TENTATIVE address, | 4954 | /* Don't send DELADDR notification for TENTATIVE address, |
4942 | * since NEWADDR notification is sent only after removing | 4955 | * since NEWADDR notification is sent only after removing |
4943 | * TENTATIVE flag. | 4956 | * TENTATIVE flag, if DAD has not failed. |
4944 | */ | 4957 | */ |
4945 | if (ifa->flags & IFA_F_TENTATIVE && event == RTM_DELADDR) | 4958 | if (ifa->flags & IFA_F_TENTATIVE && !(ifa->flags & IFA_F_DADFAILED) && |
4959 | event == RTM_DELADDR) | ||
4946 | return; | 4960 | return; |
4947 | 4961 | ||
4948 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); | 4962 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); |