diff options
-rw-r--r-- | include/linux/if_addr.h | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 12 |
2 files changed, 8 insertions, 5 deletions
diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index a60c821be44c..fd9740466757 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h | |||
@@ -41,6 +41,7 @@ enum | |||
41 | 41 | ||
42 | #define IFA_F_NODAD 0x02 | 42 | #define IFA_F_NODAD 0x02 |
43 | #define IFA_F_OPTIMISTIC 0x04 | 43 | #define IFA_F_OPTIMISTIC 0x04 |
44 | #define IFA_F_DADFAILED 0x08 | ||
44 | #define IFA_F_HOMEADDRESS 0x10 | 45 | #define IFA_F_HOMEADDRESS 0x10 |
45 | #define IFA_F_DEPRECATED 0x20 | 46 | #define IFA_F_DEPRECATED 0x20 |
46 | #define IFA_F_TENTATIVE 0x40 | 47 | #define IFA_F_TENTATIVE 0x40 |
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 | |||
1371 | 1371 | ||
1372 | /* Gets referenced address, destroys ifaddr */ | 1372 | /* Gets referenced address, destroys ifaddr */ |
1373 | 1373 | ||
1374 | static void addrconf_dad_stop(struct inet6_ifaddr *ifp) | 1374 | static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) |
1375 | { | 1375 | { |
1376 | if (ifp->flags&IFA_F_PERMANENT) { | 1376 | if (ifp->flags&IFA_F_PERMANENT) { |
1377 | spin_lock_bh(&ifp->lock); | 1377 | spin_lock_bh(&ifp->lock); |
1378 | addrconf_del_timer(ifp); | 1378 | addrconf_del_timer(ifp); |
1379 | ifp->flags |= IFA_F_TENTATIVE; | 1379 | ifp->flags |= IFA_F_TENTATIVE; |
1380 | if (dad_failed) | ||
1381 | ifp->flags |= IFA_F_DADFAILED; | ||
1380 | spin_unlock_bh(&ifp->lock); | 1382 | spin_unlock_bh(&ifp->lock); |
1381 | in6_ifa_put(ifp); | 1383 | in6_ifa_put(ifp); |
1382 | #ifdef CONFIG_IPV6_PRIVACY | 1384 | #ifdef CONFIG_IPV6_PRIVACY |
@@ -1422,7 +1424,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1422 | } | 1424 | } |
1423 | } | 1425 | } |
1424 | 1426 | ||
1425 | addrconf_dad_stop(ifp); | 1427 | addrconf_dad_stop(ifp, 1); |
1426 | } | 1428 | } |
1427 | 1429 | ||
1428 | /* Join to solicited addr multicast group. */ | 1430 | /* Join to solicited addr multicast group. */ |
@@ -2778,7 +2780,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2778 | idev->cnf.accept_dad < 1 || | 2780 | idev->cnf.accept_dad < 1 || |
2779 | !(ifp->flags&IFA_F_TENTATIVE) || | 2781 | !(ifp->flags&IFA_F_TENTATIVE) || |
2780 | ifp->flags & IFA_F_NODAD) { | 2782 | ifp->flags & IFA_F_NODAD) { |
2781 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); | 2783 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); |
2782 | spin_unlock_bh(&ifp->lock); | 2784 | spin_unlock_bh(&ifp->lock); |
2783 | read_unlock_bh(&idev->lock); | 2785 | read_unlock_bh(&idev->lock); |
2784 | 2786 | ||
@@ -2795,7 +2797,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2795 | * - otherwise, kill it. | 2797 | * - otherwise, kill it. |
2796 | */ | 2798 | */ |
2797 | in6_ifa_hold(ifp); | 2799 | in6_ifa_hold(ifp); |
2798 | addrconf_dad_stop(ifp); | 2800 | addrconf_dad_stop(ifp, 0); |
2799 | return; | 2801 | return; |
2800 | } | 2802 | } |
2801 | 2803 | ||
@@ -2829,7 +2831,7 @@ static void addrconf_dad_timer(unsigned long data) | |||
2829 | * DAD was successful | 2831 | * DAD was successful |
2830 | */ | 2832 | */ |
2831 | 2833 | ||
2832 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); | 2834 | ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); |
2833 | spin_unlock_bh(&ifp->lock); | 2835 | spin_unlock_bh(&ifp->lock); |
2834 | read_unlock_bh(&idev->lock); | 2836 | read_unlock_bh(&idev->lock); |
2835 | 2837 | ||