Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Rearange interface detachement slightly: before...



details:   https://anonhg.NetBSD.org/src/rev/68e4a7758ef6
branches:  trunk
changeset: 336280:68e4a7758ef6
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Feb 23 19:15:59 2015 +0000

description:
Rearange interface detachement slightly: before we free the INET6 specific
per-interface data, make sure to call nd6_purge() with it to remove
routing entries pointing to the going interface.
When we should happen to call this function again later, with the data
already gone, just return.
Fixes PR kern/49682, ok: christos.

diffstat:

 sys/netinet6/in6.c          |   6 +++---
 sys/netinet6/in6_ifattach.c |   8 ++++----
 sys/netinet6/nd6.c          |  37 ++++++++++++++++++++++++++-----------
 sys/netinet6/nd6.h          |   8 ++++----
 sys/netinet6/nd6_nbr.c      |   6 +++---
 sys/netinet6/nd6_rtr.c      |  20 ++++++++++++++------
 6 files changed, 54 insertions(+), 31 deletions(-)

diffs (277 lines):

diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/in6.c        Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.181 2015/02/20 22:13:48 rjs Exp $    */
+/*     $NetBSD: in6.c,v 1.182 2015/02/23 19:15:59 martin Exp $ */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.181 2015/02/20 22:13:48 rjs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.182 2015/02/23 19:15:59 martin Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -2318,7 +2318,7 @@
 {
        struct in6_ifextra *ext = (struct in6_ifextra *)aux;
 
-       nd6_ifdetach(ext->nd_ifinfo);
+       nd6_ifdetach(ifp, ext);
        free(ext->in6_ifstat, M_IFADDR);
        free(ext->icmp6_ifstat, M_IFADDR);
        scope6_ifdetach(ext->scope6_id);
diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/in6_ifattach.c
--- a/sys/netinet6/in6_ifattach.c       Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/in6_ifattach.c       Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_ifattach.c,v 1.94 2014/11/14 17:34:23 maxv Exp $   */
+/*     $NetBSD: in6_ifattach.c,v 1.95 2015/02/23 19:15:59 martin Exp $ */
 /*     $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $  */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.94 2014/11/14 17:34:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.95 2015/02/23 19:15:59 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -848,7 +848,7 @@
        ip6_mrouter_detach(ifp);
 
        /* remove neighbor management table */
-       nd6_purge(ifp);
+       nd6_purge(ifp, NULL);
 
        /* XXX this code is duplicated in in6_purgeif() --dyoung */
        /* nuke any of IPv6 addresses we have */
@@ -919,7 +919,7 @@
         * prefixes after removing all addresses above.
         * (Or can we just delay calling nd6_purge until at this point?)
         */
-       nd6_purge(ifp);
+       nd6_purge(ifp, NULL);
 }
 
 int
diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/nd6.c        Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.157 2015/02/17 15:14:28 christos Exp $       */
+/*     $NetBSD: nd6.c,v 1.158 2015/02/23 19:15:59 martin 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.157 2015/02/17 15:14:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.158 2015/02/23 19:15:59 martin Exp $");
 
 #include "bridge.h"
 #include "carp.h"
@@ -205,10 +205,11 @@
 }
 
 void
-nd6_ifdetach(struct nd_ifinfo *nd)
+nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext)
 {
 
-       free(nd, M_IP6NDP);
+       nd6_purge(ifp, ext);
+       free(ext->nd_ifinfo, M_IP6NDP);
 }
 
 void
@@ -556,7 +557,7 @@
        
        TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, next_dr) {
                if (dr->expire && dr->expire < time_second) {
-                       defrtrlist_del(dr);
+                       defrtrlist_del(dr, NULL);
                }
        }
 
@@ -746,13 +747,23 @@
  * ifp goes away.
  */
 void
-nd6_purge(struct ifnet *ifp)
+nd6_purge(struct ifnet *ifp, struct in6_ifextra *ext)
 {
        struct llinfo_nd6 *ln, *nln;
        struct nd_defrouter *dr, *ndr;
        struct nd_prefix *pr, *npr;
 
        /*
+        * During detach, the ND info might be already removed, but
+        * then is explitly passed as argument.
+        * Otherwise get it from ifp->if_afdata.
+        */
+       if (ext == NULL)
+               ext = ifp->if_afdata[AF_INET6];
+       if (ext == NULL)
+               return;
+
+       /*
         * Nuke default router list entries toward ifp.
         * We defer removal of default router list entries that is installed
         * in the routing table, in order to keep additional side effects as
@@ -762,16 +773,20 @@
                if (dr->installed)
                        continue;
 
-               if (dr->ifp == ifp)
-                       defrtrlist_del(dr);
+               if (dr->ifp == ifp) {
+                       KASSERT(ext != NULL);
+                       defrtrlist_del(dr, ext);
+               }
        }
 
        TAILQ_FOREACH_SAFE(dr, &nd_defrouter, dr_entry, ndr) {
                if (!dr->installed)
                        continue;
 
-               if (dr->ifp == ifp)
-                       defrtrlist_del(dr);
+               if (dr->ifp == ifp) {
+                       KASSERT(ext != NULL);
+                       defrtrlist_del(dr, ext);
+               }
        }
 
        /* Nuke prefix list entries toward ifp */
@@ -1797,7 +1812,7 @@
                s = splsoftnet();
                defrouter_reset();
                TAILQ_FOREACH_SAFE(drtr, &nd_defrouter, dr_entry, next) {
-                       defrtrlist_del(drtr);
+                       defrtrlist_del(drtr, NULL);
                }
                defrouter_select();
                splx(s);
diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/nd6.h        Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.h,v 1.61 2014/12/16 11:42:27 roy Exp $     */
+/*     $NetBSD: nd6.h,v 1.62 2015/02/23 19:15:59 martin Exp $  */
 /*     $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $    */
 
 /*
@@ -407,7 +407,7 @@
 /* nd6.c */
 void nd6_init(void);
 struct nd_ifinfo *nd6_ifattach(struct ifnet *);
-void nd6_ifdetach(struct nd_ifinfo *);
+void nd6_ifdetach(struct ifnet *, struct in6_ifextra *);
 int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *);
 void nd6_option_init(void *, int, union nd_opts *);
 struct nd_opt_hdr *nd6_option(union nd_opts *);
@@ -417,7 +417,7 @@
 void nd6_setmtu(struct ifnet *);
 void nd6_llinfo_settimer(struct llinfo_nd6 *, long);
 void nd6_timer(void *);
-void nd6_purge(struct ifnet *);
+void nd6_purge(struct ifnet *, struct in6_ifextra *);
 void nd6_nud_hint(struct rtentry *, struct in6_addr *, int);
 int nd6_resolve(struct ifnet *, struct rtentry *,
        struct mbuf *, struct sockaddr *, u_char *);
@@ -454,7 +454,7 @@
 void defrouter_addreq(struct nd_defrouter *);
 void defrouter_reset(void);
 void defrouter_select(void);
-void defrtrlist_del(struct nd_defrouter *);
+void defrtrlist_del(struct nd_defrouter *, struct in6_ifextra *);
 void prelist_remove(struct nd_prefix *);
 int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
        struct nd_prefix **);
diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/nd6_nbr.c    Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_nbr.c,v 1.103 2014/12/16 11:42:27 roy Exp $        */
+/*     $NetBSD: nd6_nbr.c,v 1.104 2015/02/23 19:15:59 martin Exp $     */
 /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.103 2014/12/16 11:42:27 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.104 2015/02/23 19:15:59 martin Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -804,7 +804,7 @@
                        s = splsoftnet();
                        dr = defrouter_lookup(in6, rt->rt_ifp);
                        if (dr)
-                               defrtrlist_del(dr);
+                               defrtrlist_del(dr, NULL);
                        else if (!ip6_forwarding) {
                                /*
                                 * Even if the neighbor is not in the default
diff -r b081d0658841 -r 68e4a7758ef6 sys/netinet6/nd6_rtr.c
--- a/sys/netinet6/nd6_rtr.c    Mon Feb 23 19:05:16 2015 +0000
+++ b/sys/netinet6/nd6_rtr.c    Mon Feb 23 19:15:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_rtr.c,v 1.95 2014/12/16 11:42:27 roy Exp $ */
+/*     $NetBSD: nd6_rtr.c,v 1.96 2015/02/23 19:15:59 martin Exp $      */
 /*     $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.95 2014/12/16 11:42:27 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.96 2015/02/23 19:15:59 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -483,12 +483,20 @@
 }
 
 void
-defrtrlist_del(struct nd_defrouter *dr)
+defrtrlist_del(struct nd_defrouter *dr, struct in6_ifextra *ext)
 {
-       struct nd_ifinfo *ndi = ND_IFINFO(dr->ifp);
        struct nd_defrouter *deldr = NULL;
        struct nd_prefix *pr;
-       struct in6_ifextra *ext = dr->ifp->if_afdata[AF_INET6];
+       struct nd_ifinfo *ndi;
+
+       if (ext == NULL)
+               ext = dr->ifp->if_afdata[AF_INET6];
+
+       /* detach already in progress, can not do anything */
+       if (ext == NULL)
+               return;
+
+       ndi = ext->nd_ifinfo;
 
        /*
         * Flush all the routing table entries that use the router
@@ -749,7 +757,7 @@
        if ((dr = defrouter_lookup(&newdr->rtaddr, newdr->ifp)) != NULL) {
                /* entry exists */
                if (newdr->rtlifetime == 0) {
-                       defrtrlist_del(dr);
+                       defrtrlist_del(dr, ext);
                        dr = NULL;
                } else {
                        int oldpref = rtpref(dr);



Home | Main Index | Thread Index | Old Index