diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c341371..ddac8b0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -593,13 +593,8 @@ ipv6_add_addr(struct inet6_dev *idev, co ifa->cstamp = ifa->tstamp = jiffies; ifa->rt = rt; -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (!idev->cnf.optimistic_dad || ipv6_devconf.forwarding || - (ifa->rt->rt6i_nexthop == NULL)) + if (rt->rt6i_nexthop == NULL) ifa->flags &= ~IFA_F_OPTIMISTIC; -#else - ifa->flags &= ~IFA_F_OPTIMISTIC; -#endif ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -776,6 +771,7 @@ static int ipv6_create_tempaddr(struct i int tmp_plen; int ret = 0; int max_addresses; + u32 addr_flags; write_lock(&idev->lock); if (ift) { @@ -833,11 +829,17 @@ retry: spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); + + addr_flags = IFA_F_TEMPORARY; + /* set in addrconf_prefix_rcv() */ + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, - IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; + addr_flags) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1746,6 +1748,13 @@ ok: if (ifp == NULL && valid_lft) { int max_addresses = in6_dev->cnf.max_addresses; + u32 addr_flags = 0; + +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + if (in6_dev->cnf.optimistic_dad && + !ipv6_devconf.forwarding) + addr_flags = IFA_F_OPTIMISTIC; +#endif /* Do not allow to create too much of autoconfigured * addresses; this would be too easy way to crash kernel. @@ -1753,7 +1762,8 @@ ok: if (!max_addresses || ipv6_count_addresses(in6_dev) < max_addresses) ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, - addr_type&IPV6_ADDR_SCOPE_MASK, 0); + addr_type&IPV6_ADDR_SCOPE_MASK, + addr_flags); if (!ifp || IS_ERR(ifp)) { in6_dev_put(in6_dev); @@ -1762,10 +1772,6 @@ ok: update_lft = create = 1; ifp->cstamp = jiffies; -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (ifp->idev->cnf.optimistic_dad) - ifp->flags |= IFA_F_OPTIMISTIC; -#endif addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT); } @@ -2141,9 +2147,16 @@ static void init_loopback(struct net_dev static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) { struct inet6_ifaddr * ifp; + u32 addr_flags = IFA_F_PERMANENT; + +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + if (idev->cnf.optimistic_dad && + !ipv6_devconf.forwarding) + addr_flags |= IFA_F_OPTIMISTIC; +#endif + - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, - IFA_F_PERMANENT|IFA_F_OPTIMISTIC); + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags); if (!IS_ERR(ifp)) { addrconf_dad_start(ifp, 0); in6_ifa_put(ifp);