Module Name:    src
Committed By:   ozaki-r
Date:           Mon Dec 19 04:52:17 UTC 2016

Modified Files:
        src/sys/netinet6: nd6.c

Log Message:
Kill pr->ndpr_refcnt = 0

The reference counter represents the numuber of references from IPv6
addresses to a prefix entry. If all IPv6 addresses assigned to an
interface are purged, all references to a prefix for the interface are
also released. For now nd6_purge is always called after purging all IPv6
addresses, so we can get rid of clearing pr->ndpr_refcnt from nd6_purge
and instead we can assert it's 0 there.

Note that nd6_ifdetach is only called via dom_ifdetach when processing
if_detach where dom_ifdetach is called after pr_purgeif that eventually
calls in6_ifdetach. So in the call path nd6_purge in nd6_ifdetach does
nothing. That said, we should explicitly make it sure to purge all
IPv6 addresses before nd6_purge for future changes (or the case I missed
something). So if_purgeaddrs is added to nd6_ifdetach.


To generate a diff of this commit:
cvs rdiff -u -r1.218 -r1.219 src/sys/netinet6/nd6.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.218 src/sys/netinet6/nd6.c:1.219
--- src/sys/netinet6/nd6.c:1.218	Mon Dec 19 03:32:54 2016
+++ src/sys/netinet6/nd6.c	Mon Dec 19 04:52:17 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.218 2016/12/19 03:32:54 ozaki-r Exp $	*/
+/*	$NetBSD: nd6.c,v 1.219 2016/12/19 04:52:17 ozaki-r Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.218 2016/12/19 03:32:54 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.219 2016/12/19 04:52:17 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -196,6 +196,8 @@ void
 nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext)
 {
 
+	/* Ensure all IPv6 addresses are purged before calling nd6_purge */
+	if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
 	nd6_purge(ifp, ext);
 	free(ext->nd_ifinfo, M_IP6NDP);
 }
@@ -863,20 +865,9 @@ nd6_purge(struct ifnet *ifp, struct in6_
 	ND_PREFIX_LIST_FOREACH_SAFE(pr, npr) {
 		if (pr->ndpr_ifp == ifp) {
 			/*
-			 * Because if_detach() does *not* release prefixes
-			 * while purging addresses the reference count will
-			 * still be above zero. We therefore reset it to
-			 * make sure that the prefix really gets purged.
-			 */
-			pr->ndpr_refcnt = 0;
-			/*
-			 * Previously, pr->ndpr_addr is removed as well,
-			 * but I strongly believe we don't have to do it.
-			 * nd6_purge() is only called from in6_ifdetach(),
-			 * which removes all the associated interface addresses
-			 * by itself.
-			 * (jin...@kame.net 20010129)
+			 * All addresses referencing pr should be already freed.
 			 */
+			KASSERT(pr->ndpr_refcnt == 0);
 			nd6_prelist_remove(pr);
 		}
 	}

Reply via email to