Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 May 2014 15:53:31 +0000 (UTC)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r266248 - head/sys/netinet6
Message-ID:  <201405161553.s4GFrVa3019325@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hrs
Date: Fri May 16 15:53:31 2014
New Revision: 266248
URL: http://svnweb.freebsd.org/changeset/base/266248

Log:
  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.

Modified:
  head/sys/netinet6/nd6_nbr.c

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c	Fri May 16 15:53:27 2014	(r266247)
+++ head/sys/netinet6/nd6_nbr.c	Fri May 16 15:53:31 2014	(r266248)
@@ -1312,6 +1312,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];
 
@@ -1320,6 +1321,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",
@@ -1384,9 +1395,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",



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405161553.s4GFrVa3019325>