summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-05-05 07:58:16 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-05-05 07:58:16 +0000
commita43b5df214133af6a6889146f4984205d4be6fb1 (patch)
treeeb065f1bb4876cfaf9a767860a48c93a9a3aba1c /sys
parent4cc63638780c31e4180bcc7d766109461b985c5a (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.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 */