summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoritojun <itojun@openbsd.org>2000-05-05 07:58:15 +0000
committeritojun <itojun@openbsd.org>2000-05-05 07:58:15 +0000
commit2b3f5aceaff644e3277eb368fe1515a970a11f89 (patch)
treedbbd185e8a34c1d197039f2ac26462679daa01d5
parentsome docs (diff)
downloadwireguard-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.c6
-rw-r--r--sys/netinet6/in6_ifattach.c21
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 */