summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2014-10-09 23:25:57 +0000
committerhrs <hrs@FreeBSD.org>2014-10-09 23:25:57 +0000
commitca07cfe57d03fa85669d0ee973e22437cc6c5f24 (patch)
tree47779c24c81b557c5852d07fb0d3c95ae0b9dd3a /sys/netinet6
parent90b42277dc21c65fc9805c42b5eddde0edb59b76 (diff)
downloadFreeBSD-src-ca07cfe57d03fa85669d0ee973e22437cc6c5f24.zip
FreeBSD-src-ca07cfe57d03fa85669d0ee973e22437cc6c5f24.tar.gz
MFC r266248:
Cancel DAD for an ifa when the ifp has ND6_IFF_IFDISABLED as early as possible and do not clear IN6_IFF_TENTATIVE. If IFDISABLED was accidentally set after a DAD started, TENTATIVE could be cleared because no NA was received due to IFDISABLED, and as a result it could prevent DAD when manually clearing IFDISABLED after that.
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/nd6_nbr.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index be81331..75ec443 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1328,6 +1328,7 @@ nd6_dad_timer(struct dadq *dp)
{
CURVNET_SET(dp->dad_vnet);
struct ifaddr *ifa = dp->dad_ifa;
+ struct ifnet *ifp = dp->dad_ifa->ifa_ifp;
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
char ip6buf[INET6_ADDRSTRLEN];
@@ -1336,6 +1337,16 @@ nd6_dad_timer(struct dadq *dp)
log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
goto done;
}
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
+ /* Do not need DAD for ifdisabled interface. */
+ TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
+ log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of "
+ "ND6_IFF_IFDISABLED.\n", ifp->if_xname);
+ free(dp, M_IP6NDP);
+ dp = NULL;
+ ifa_free(ifa);
+ goto done;
+ }
if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
"%s(%s)\n",
@@ -1402,9 +1413,12 @@ nd6_dad_timer(struct dadq *dp)
} else {
/*
* We are done with DAD. No NA came, no NS came.
- * No duplicate address found.
+ * No duplicate address found. Check IFDISABLED flag
+ * again in case that it is changed between the
+ * beginning of this function and here.
*/
- ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
+ if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0)
+ ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
nd6log((LOG_DEBUG,
"%s: DAD complete for %s - no duplicates found\n",
OpenPOWER on IntegriCloud