Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Nov 2014 16:01:39 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r274347 - head/sys/netinet6
Message-ID:  <201411101601.sAAG1dlF038794@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Mon Nov 10 16:01:39 2014
New Revision: 274347
URL: https://svnweb.freebsd.org/changeset/base/274347

Log:
  * Make nd6_dad_duplicated() constant.
  * Simplify refcounting by using nd6_dad_add() / nd6_dad_del().
  
  Reviewed by:	ae
  MFC after:	2 weeks
  Sponsored by:	Yandex LLC

Modified:
  head/sys/netinet6/nd6.h
  head/sys/netinet6/nd6_nbr.c

Modified: head/sys/netinet6/nd6.h
==============================================================================
--- head/sys/netinet6/nd6.h	Mon Nov 10 16:01:31 2014	(r274346)
+++ head/sys/netinet6/nd6.h	Mon Nov 10 16:01:39 2014	(r274347)
@@ -430,7 +430,6 @@ void nd6_ns_output(struct ifnet *, const
 caddr_t nd6_ifptomac(struct ifnet *);
 void nd6_dad_start(struct ifaddr *, int);
 void nd6_dad_stop(struct ifaddr *);
-void nd6_dad_duplicated(struct ifaddr *);
 
 /* nd6_rtr.c */
 void nd6_rs_input(struct mbuf *, int, int);

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c	Mon Nov 10 16:01:31 2014	(r274346)
+++ head/sys/netinet6/nd6_nbr.c	Mon Nov 10 16:01:39 2014	(r274347)
@@ -79,9 +79,12 @@ __FBSDID("$FreeBSD$");
 
 struct dadq;
 static struct dadq *nd6_dad_find(struct ifaddr *);
+static void nd6_dad_add(struct dadq *dp);
+static void nd6_dad_del(struct dadq *dp);
 static void nd6_dad_starttimer(struct dadq *, int);
 static void nd6_dad_stoptimer(struct dadq *);
 static void nd6_dad_timer(struct dadq *);
+static void nd6_dad_duplicated(struct ifaddr *, struct dadq *);
 static void nd6_dad_ns_output(struct dadq *, struct ifaddr *);
 static void nd6_dad_ns_input(struct ifaddr *);
 static void nd6_dad_na_input(struct ifaddr *);
@@ -1179,6 +1182,26 @@ static VNET_DEFINE(struct rwlock, dad_rw
 #define	DADQ_WLOCK()		rw_wlock(&V_dad_rwlock)	
 #define	DADQ_WUNLOCK()		rw_wunlock(&V_dad_rwlock)	
 
+static void
+nd6_dad_add(struct dadq *dp)
+{
+
+	ifa_ref(dp->dad_ifa);	/* just for safety */
+	DADQ_WLOCK();
+	TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list);
+	DADQ_WUNLOCK();
+}
+
+static void
+nd6_dad_del(struct dadq *dp)
+{
+
+	ifa_free(dp->dad_ifa);
+	DADQ_WLOCK();
+	TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
+	DADQ_WUNLOCK();
+}
+
 static struct dadq *
 nd6_dad_find(struct ifaddr *ifa)
 {
@@ -1270,10 +1293,6 @@ nd6_dad_start(struct ifaddr *ifa, int de
 #ifdef VIMAGE
 	dp->dad_vnet = curvnet;
 #endif
-	DADQ_WLOCK();
-	TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list);
-	DADQ_WUNLOCK();
-
 	nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
 	    ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
 
@@ -1284,10 +1303,10 @@ nd6_dad_start(struct ifaddr *ifa, int de
 	 * (re)initialization.
 	 */
 	dp->dad_ifa = ifa;
-	ifa_ref(ifa);	/* just for safety */
 	dp->dad_count = V_ip6_dad_count;
 	dp->dad_ns_icount = dp->dad_na_icount = 0;
 	dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
+	nd6_dad_add(dp);
 	if (delay == 0) {
 		nd6_dad_ns_output(dp, ifa);
 		nd6_dad_starttimer(dp,
@@ -1315,12 +1334,8 @@ nd6_dad_stop(struct ifaddr *ifa)
 
 	nd6_dad_stoptimer(dp);
 
-	DADQ_WLOCK();
-	TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
-	DADQ_WUNLOCK();
+	nd6_dad_del(dp);
 	free(dp, M_IP6NDP);
-	dp = NULL;
-	ifa_free(ifa);
 }
 
 static void
@@ -1367,12 +1382,9 @@ nd6_dad_timer(struct dadq *dp)
 		nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n",
 		    if_name(ifa->ifa_ifp)));
 
-		DADQ_WLOCK();
-		TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
-		DADQ_WUNLOCK();
+		nd6_dad_del(dp);
 		free(dp, M_IP6NDP);
 		dp = NULL;
-		ifa_free(ifa);
 		goto done;
 	}
 
@@ -1408,8 +1420,8 @@ nd6_dad_timer(struct dadq *dp)
 
 		if (duplicate) {
 			/* (*dp) will be freed in nd6_dad_duplicated() */
+			nd6_dad_duplicated(ifa, dp);
 			dp = NULL;
-			nd6_dad_duplicated(ifa);
 		} else {
 			/*
 			 * We are done with DAD.  No NA came, no NS came.
@@ -1425,12 +1437,9 @@ nd6_dad_timer(struct dadq *dp)
 			    if_name(ifa->ifa_ifp),
 			    ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
 
-			DADQ_WLOCK();
-			TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
-			DADQ_WUNLOCK();
+			nd6_dad_del(dp);
 			free(dp, M_IP6NDP);
 			dp = NULL;
-			ifa_free(ifa);
 		}
 	}
 
@@ -1439,19 +1448,12 @@ done:
 }
 
 void
-nd6_dad_duplicated(struct ifaddr *ifa)
+nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp)
 {
 	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
 	struct ifnet *ifp;
-	struct dadq *dp;
 	char ip6buf[INET6_ADDRSTRLEN];
 
-	dp = nd6_dad_find(ifa);
-	if (dp == NULL) {
-		log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n");
-		return;
-	}
-
 	log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: "
 	    "NS in/out=%d/%d, NA in=%d\n",
 	    if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
@@ -1504,12 +1506,8 @@ nd6_dad_duplicated(struct ifaddr *ifa)
 		}
 	}
 
-	DADQ_WLOCK();
-	TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
-	DADQ_WUNLOCK();
+	nd6_dad_del(dp);
 	free(dp, M_IP6NDP);
-	dp = NULL;
-	ifa_free(ifa);
 }
 
 static void
@@ -1568,8 +1566,8 @@ nd6_dad_ns_input(struct ifaddr *ifa)
 	/* XXX more checks for loopback situation - see nd6_dad_timer too */
 
 	if (duplicate) {
+		nd6_dad_duplicated(ifa, dp);
 		dp = NULL;	/* will be freed in nd6_dad_duplicated() */
-		nd6_dad_duplicated(ifa);
 	} else {
 		/*
 		 * not sure if I got a duplicate.
@@ -1593,5 +1591,5 @@ nd6_dad_na_input(struct ifaddr *ifa)
 		dp->dad_na_icount++;
 
 	/* remove the address. */
-	nd6_dad_duplicated(ifa);
+	nd6_dad_duplicated(ifa, dp);
 }



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