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); } }