diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-05-05 07:58:16 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-05-05 07:58:16 +0000 |
commit | a43b5df214133af6a6889146f4984205d4be6fb1 (patch) | |
tree | eb065f1bb4876cfaf9a767860a48c93a9a3aba1c /sys | |
parent | 4cc63638780c31e4180bcc7d766109461b985c5a (diff) |
cope with interface detach (like pcmcia card removal). remove any
IPv6 addresses assigned to the interface. reported by ho, bunch of
help from niklas. KAME PR 231.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.c | 6 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 21 |
2 files changed, 21 insertions, 6 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 49fafcc6d7d..39c3e3eff2c 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.30 2000/03/22 11:28:42 itojun Exp $ */ +/* $OpenBSD: if.c,v 1.31 2000/05/05 07:58:15 itojun Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -99,6 +99,7 @@ #ifndef INET #include <netinet/in.h> #endif +#include <netinet6/in6_ifattach.h> #endif #ifdef IPFILTER @@ -326,6 +327,9 @@ if_detach(ifp) vif_delete(ifp); #endif #endif +#ifdef INET6 + in6_ifdetach(ifp); +#endif /* * XXX transient ifp refs? inpcb.ip_moptions.imo_multicast_ifp? * Other network stacks than INET? diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index d77e85fd413..61932b90851 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_ifattach.c,v 1.9 2000/04/27 15:40:37 itojun Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.10 2000/05/05 07:58:15 itojun Exp $ */ /* $KAME: in6_ifattach.c,v 1.53 2000/04/16 14:01:42 itojun Exp $ */ /* @@ -794,7 +794,7 @@ in6_ifdetach(ifp) struct ifnet *ifp; { struct in6_ifaddr *ia, *oia; - struct ifaddr *ifa; + struct ifaddr *ifa, *next; struct rtentry *rt; short rtflags; struct sockaddr_in6 sin6; @@ -806,7 +806,17 @@ in6_ifdetach(ifp) /* remove neighbor management table */ nd6_purge(ifp); - for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) + /* nuke any of IPv6 addresses we have */ + for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next) + { + next = ifa->ifa_list.tqe_next; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + in6_purgeaddr(ifa, ifp); + } + + /* undo everything done by in6_ifattach(), just in case */ + for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next) { if (ifa->ifa_addr->sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) { @@ -816,7 +826,7 @@ in6_ifdetach(ifp) ia = (struct in6_ifaddr *)ifa; /* leave from all multicast groups joined */ - while ((in6m = LIST_FIRST(&oia->ia6_multiaddrs)) != NULL) + while ((in6m = LIST_FIRST(&ia->ia6_multiaddrs)) != NULL) in6_delmulti(in6m); /* remove from the routing table */ @@ -833,6 +843,7 @@ in6_ifdetach(ifp) /* remove from the linked list */ TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list); + IFAFREE(&ia->ia_ifa); /* also remove from the IPv6 address chain(itojun&jinmei) */ oia = ia; @@ -850,7 +861,7 @@ in6_ifdetach(ifp) #endif } - free(oia, M_IFADDR); + IFAFREE(&oia->ia_ifa); } /* cleanup multicast address kludge table, if there is any */ |