aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c32
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
1402static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) 1402static 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);