svn commit: r296991 - head/sys/netinet6

Mark Johnston markj at FreeBSD.org
Thu Mar 17 19:01:46 UTC 2016


Author: markj
Date: Thu Mar 17 19:01:44 2016
New Revision: 296991
URL: https://svnweb.freebsd.org/changeset/base/296991

Log:
  Modify defrouter_remove() to perform the router lookup before removal.
  
  This allows some simplification of its callers. No functional change
  intended.
  
  Tested by:	Larry Rosenman (as part of a larger change)
  MFC after:	1 month

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

Modified: head/sys/netinet6/nd6.h
==============================================================================
--- head/sys/netinet6/nd6.h	Thu Mar 17 18:55:54 2016	(r296990)
+++ head/sys/netinet6/nd6.h	Thu Mar 17 19:01:44 2016	(r296991)
@@ -459,7 +459,7 @@ void defrouter_reset(void);
 void defrouter_select(void);
 void defrouter_ref(struct nd_defrouter *);
 void defrouter_rele(struct nd_defrouter *);
-void defrouter_remove(struct nd_defrouter *);
+bool defrouter_remove(struct in6_addr *, struct ifnet *);
 void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *);
 void defrouter_del(struct nd_defrouter *);
 void prelist_remove(struct nd_prefix *);

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c	Thu Mar 17 18:55:54 2016	(r296990)
+++ head/sys/netinet6/nd6_nbr.c	Thu Mar 17 19:01:44 2016	(r296991)
@@ -857,30 +857,19 @@ nd6_na_input(struct mbuf *m, int off, in
 			 * Remove the sender from the Default Router List and
 			 * update the Destination Cache entries.
 			 */
-			struct nd_defrouter *dr;
 			struct ifnet *nd6_ifp;
 
 			nd6_ifp = lltable_get_ifp(ln->lle_tbl);
-			ND6_WLOCK();
-			dr = defrouter_lookup_locked(&ln->r_l3addr.addr6,
-			    nd6_ifp);
-			if (dr != NULL) {
-				/* releases the ND lock */
-				defrouter_remove(dr);
-				dr = NULL;
-			} else {
-				ND6_WUNLOCK();
-				if ((ND_IFINFO(nd6_ifp)->flags & ND6_IFF_ACCEPT_RTADV) != 0) {
-					/*
-					 * Even if the neighbor is not in the default
-					 * router list, the neighbor may be used
-					 * as a next hop for some destinations
-					 * (e.g. redirect case). So we must
-					 * call rt6_flush explicitly.
-					 */
-					rt6_flush(&ip6->ip6_src, ifp);
-				}
-			}
+			if (!defrouter_remove(&ln->r_l3addr.addr6, nd6_ifp) &&
+			    (ND_IFINFO(nd6_ifp)->flags &
+			     ND6_IFF_ACCEPT_RTADV) != 0)
+				/*
+				 * Even if the neighbor is not in the default
+				 * router list, the neighbor may be used as a
+				 * next hop for some destinations (e.g. redirect
+				 * case). So we must call rt6_flush explicitly.
+				 */
+				rt6_flush(&ip6->ip6_src, ifp);
 		}
 		ln->ln_router = is_router;
 	}

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c	Thu Mar 17 18:55:54 2016	(r296990)
+++ head/sys/netinet6/nd6_rtr.c	Thu Mar 17 19:01:44 2016	(r296991)
@@ -627,22 +627,26 @@ defrouter_reset(void)
 }
 
 /*
- * Remove a router from the global list and free it.
- *
- * The ND lock must be held and is released before returning. The caller must
- * hold a reference on the router object.
+ * Look up a matching default router list entry and remove it. Returns true if a
+ * matching entry was found, false otherwise.
  */
-void
-defrouter_remove(struct nd_defrouter *dr)
+bool
+defrouter_remove(struct in6_addr *addr, struct ifnet *ifp)
 {
+	struct nd_defrouter *dr;
 
-	ND6_WLOCK_ASSERT();
-	KASSERT(dr->refcnt >= 2, ("unexpected refcount 0x%x", dr->refcnt));
+	ND6_WLOCK();
+	dr = defrouter_lookup_locked(addr, ifp);
+	if (dr == NULL) {
+		ND6_WUNLOCK();
+		return (false);
+	}
 
 	defrouter_unlink(dr, NULL);
 	ND6_WUNLOCK();
 	defrouter_del(dr);
 	defrouter_rele(dr);
+	return (true);
 }
 
 /*
@@ -850,14 +854,14 @@ defrtrlist_update(struct nd_defrouter *n
 	struct nd_defrouter *dr, *n;
 	int oldpref;
 
-	ND6_WLOCK();
-	if ((dr = defrouter_lookup_locked(&new->rtaddr, new->ifp)) != NULL) {
-		if (new->rtlifetime == 0) {
-			/* releases the ND lock */
-			defrouter_remove(dr);
-			return (NULL);
-		}
+	if (new->rtlifetime == 0) {
+		defrouter_remove(&new->rtaddr, new->ifp);
+		return (NULL);
+	}
 
+	ND6_WLOCK();
+	dr = defrouter_lookup_locked(&new->rtaddr, new->ifp);
+	if (dr != NULL) {
 		oldpref = rtpref(dr);
 
 		/* override */
@@ -881,25 +885,17 @@ defrtrlist_update(struct nd_defrouter *n
 		 */
 		TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
 		n = dr;
-		goto insert;
-	}
-
-	/* entry does not exist */
-	if (new->rtlifetime == 0) {
-		ND6_WUNLOCK();
-		return (NULL);
-	}
-
-	n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
-	if (n == NULL) {
-		ND6_WUNLOCK();
-		return (NULL);
+	} else {
+		n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
+		if (n == NULL) {
+			ND6_WUNLOCK();
+			return (NULL);
+		}
+		memcpy(n, new, sizeof(*n));
+		/* Initialize with an extra reference for the caller. */
+		refcount_init(&n->refcnt, 2);
 	}
-	memcpy(n, new, sizeof(*n));
-	/* Initialize with an extra reference for the caller. */
-	refcount_init(&n->refcnt, 2);
 
-insert:
 	/*
 	 * Insert the new router in the Default Router List;
 	 * The Default Router List should be in the descending order


More information about the svn-src-all mailing list