diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 43b3c9f89c12..c9b369034a40 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1371,12 +1371,14 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *add /* Gets referenced address, destroys ifaddr */ -static void addrconf_dad_stop(struct inet6_ifaddr *ifp) +static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) { if (ifp->flags&IFA_F_PERMANENT) { spin_lock_bh(&ifp->lock); addrconf_del_timer(ifp); ifp->flags |= IFA_F_TENTATIVE; + if (dad_failed) + ifp->flags |= IFA_F_DADFAILED; spin_unlock_bh(&ifp->lock); in6_ifa_put(ifp); #ifdef CONFIG_IPV6_PRIVACY @@ -1422,7 +1424,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) } } - addrconf_dad_stop(ifp); + addrconf_dad_stop(ifp, 1); } /* Join to solicited addr multicast group. */ @@ -2778,7 +2780,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) idev->cnf.accept_dad < 1 || !(ifp->flags&IFA_F_TENTATIVE) || ifp->flags & IFA_F_NODAD) { - ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); spin_unlock_bh(&ifp->lock); read_unlock_bh(&idev->lock); @@ -2795,7 +2797,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) * - otherwise, kill it. */ in6_ifa_hold(ifp); - addrconf_dad_stop(ifp); + addrconf_dad_stop(ifp, 0); return; } @@ -2829,7 +2831,7 @@ static void addrconf_dad_timer(unsigned long data) * DAD was successful */ - ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); spin_unlock_bh(&ifp->lock); read_unlock_bh(&idev->lock); |