diff options
author | 2000-05-05 07:58:15 +0000 | |
---|---|---|
committer | 2000-05-05 07:58:15 +0000 | |
commit | 2b3f5aceaff644e3277eb368fe1515a970a11f89 (patch) | |
tree | dbbd185e8a34c1d197039f2ac26462679daa01d5 | |
parent | some docs (diff) | |
download | wireguard-openbsd-2b3f5aceaff644e3277eb368fe1515a970a11f89.tar.xz wireguard-openbsd-2b3f5aceaff644e3277eb368fe1515a970a11f89.zip |
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.
-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 */ |