Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 Kill pr->ndpr_refcnt = 0



details:   https://anonhg.NetBSD.org/src/rev/1daf518c8fd0
branches:  trunk
changeset: 819837:1daf518c8fd0
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Dec 19 04:52:17 2016 +0000

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

diffstat:

 sys/netinet6/nd6.c |  21 ++++++---------------
 1 files changed, 6 insertions(+), 15 deletions(-)

diffs (50 lines):

diff -r 2b48394190e8 -r 1daf518c8fd0 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Mon Dec 19 04:44:35 2016 +0000
+++ b/sys/netinet6/nd6.c        Mon Dec 19 04:52:17 2016 +0000
@@ -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 @@
 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 @@
        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.
+                        * All addresses referencing pr should be already freed.
                         */
-                       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.
-                        * (jinmei%kame.net@localhost 20010129)
-                        */
+                       KASSERT(pr->ndpr_refcnt == 0);
                        nd6_prelist_remove(pr);
                }
        }



Home | Main Index | Thread Index | Old Index