Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 implement in6_purgemkludge(). in6_ifdetach() c...



details:   https://anonhg.NetBSD.org/src/rev/a7f25bcf3d30
branches:  trunk
changeset: 481612:a7f25bcf3d30
user:      itojun <itojun%NetBSD.org@localhost>
date:      Wed Feb 02 16:58:10 2000 +0000

description:
implement in6_purgemkludge().  in6_ifdetach() calls it to avoid dangling
kludge entries.  the situation would occur if you take the following steps:
- join multicast groups (default ones like linklocal all-node is fine)
- remove all IPv6 addresses manually
- remove pcmcia card

to thorpej: pls call in6_ifdetach() when PRU_PURGEIF is raised (just before
removing ifnet).  it should do the right thing (unable to perform real test
though)

diffstat:

 sys/netinet6/in6.c          |  32 ++++++++++++++++++++++++++++++--
 sys/netinet6/in6_ifattach.c |  12 +++++++++++-
 sys/netinet6/in6_var.h      |   3 ++-
 3 files changed, 43 insertions(+), 4 deletions(-)

diffs (124 lines):

diff -r c0ae2eab66cf -r a7f25bcf3d30 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Wed Feb 02 16:41:56 2000 +0000
+++ b/sys/netinet6/in6.c        Wed Feb 02 16:58:10 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.11 2000/02/02 13:44:05 itojun Exp $  */
+/*     $NetBSD: in6.c,v 1.12 2000/02/02 16:58:10 itojun Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1331,6 +1331,8 @@
 
                for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
                        next = in6m->in6m_entry.le_next;
+                       IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
+                       in6m->in6m_ia = NULL;
                        LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);
                }
 
@@ -1361,6 +1363,8 @@
 
                        for (in6m = mk->mk_head.lh_first; in6m; in6m = next){
                                next = in6m->in6m_entry.le_next;
+                               in6m->in6m_ia = ia;
+                               IFAREF(&ia->ia_ifa);    /* gain a reference */
                                LIST_INSERT_HEAD(&ia->ia6_multiaddrs,
                                                 in6m, in6m_entry);
                        }
@@ -1371,6 +1375,29 @@
        }
 }
 
+void
+in6_purgemkludge(ifp)
+       struct ifnet *ifp;
+{
+       struct multi6_kludge *mk;
+       struct in6_multi *in6m, *next;
+
+       for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
+               if (mk->mk_ifp != ifp)
+                       continue;
+
+               for (in6m = mk->mk_head.lh_first; in6m; in6m = next) {
+                       next = in6m->in6m_entry.le_next;
+                       LIST_REMOVE(in6m, in6m_entry);
+                       in6_delmulti(in6m);
+                       in6m = NULL;
+               }
+               LIST_REMOVE(mk, mk_entry);
+               free(mk, M_IPMADDR);
+               break;
+       }
+}
+
 /*
  * Add an address to the list of IP6 multicast addresses for a 
  * given interface.
@@ -1472,7 +1499,8 @@
                 * Unlink from list.
                 */
                LIST_REMOVE(in6m, in6m_entry);
-               IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
+               if (in6m->in6m_ia)
+                       IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
 
                /*
                 * Notify the network driver to update its multicast 
diff -r c0ae2eab66cf -r a7f25bcf3d30 sys/netinet6/in6_ifattach.c
--- a/sys/netinet6/in6_ifattach.c       Wed Feb 02 16:41:56 2000 +0000
+++ b/sys/netinet6/in6_ifattach.c       Wed Feb 02 16:58:10 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_ifattach.c,v 1.16 2000/02/02 13:44:06 itojun Exp $ */
+/*     $NetBSD: in6_ifattach.c,v 1.17 2000/02/02 16:58:11 itojun Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -221,6 +221,10 @@
        }
 }
 
+/*
+ * XXX multiple loopback interface needs more care.  for instance,
+ * nodelocal address needs to be configured onto only one of them.
+ */
 void
 in6_ifattach(ifp, type, laddr, noloop)
        struct ifnet *ifp;
@@ -611,6 +615,9 @@
        return;
 }
 
+/*
+ * NOTE: in6_ifdetach() does not support loopback if at this moment.
+ */
 void
 in6_ifdetach(ifp)
        struct ifnet *ifp;
@@ -664,6 +671,9 @@
                free(ia, M_IFADDR);
        }
 
+       /* cleanup multicast address kludge table, if there is any */
+       in6_purgemkludge(ifp);
+  
        /* remove route to link-local allnodes multicast (ff02::1) */
        bzero(&sin6, sizeof(sin6));
        sin6.sin6_len = sizeof(struct sockaddr_in6);
diff -r c0ae2eab66cf -r a7f25bcf3d30 sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h    Wed Feb 02 16:41:56 2000 +0000
+++ b/sys/netinet6/in6_var.h    Wed Feb 02 16:58:10 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_var.h,v 1.7 2000/02/01 22:52:11 thorpej Exp $      */
+/*     $NetBSD: in6_var.h,v 1.8 2000/02/02 16:58:11 itojun Exp $       */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -554,6 +554,7 @@
 void   in6_savemkludge __P((struct in6_ifaddr *));
 void   in6_setmaxmtu   __P((void));
 void   in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *));
+void   in6_purgemkludge __P((struct ifnet *));
 struct in6_ifaddr *in6ifa_ifpforlinklocal __P((struct ifnet *));
 struct in6_ifaddr *in6ifa_ifpwithaddr __P((struct ifnet *,
                                             struct in6_addr *));



Home | Main Index | Thread Index | Old Index