summaryrefslogtreecommitdiffstats
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-10-16 13:38:29 +0000
committerume <ume@FreeBSD.org>2003-10-16 13:38:29 +0000
commit0fb87ae0efeb90ac8a95983a5e83c87b78356e5c (patch)
tree8b1c446a173d4ed6c6bc6a9d6e7cba3437653b82 /sys/net/if.c
parent300addad5e8798817da8f6eea92ecd72cb8a881e (diff)
downloadFreeBSD-src-0fb87ae0efeb90ac8a95983a5e83c87b78356e5c.zip
FreeBSD-src-0fb87ae0efeb90ac8a95983a5e83c87b78356e5c.tar.gz
AF_LINK sockaddr has to be attached to ifp->if_addrlist until the
end, as many of the code assumes that TAILQ_FIRST(ifp->if_addrlist) is non-null. Submitted by: itojun
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 6cf8852..6f3091b 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -454,7 +454,7 @@ void
if_detach(ifp)
struct ifnet *ifp;
{
- struct ifaddr *ifa;
+ struct ifaddr *ifa, *next;
struct radix_node_head *rnh;
int s;
int i;
@@ -476,8 +476,11 @@ if_detach(ifp)
while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
if_index--;
- for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
- ifa = TAILQ_FIRST(&ifp->if_addrhead)) {
+ for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = next) {
+ next = TAILQ_NEXT(ifa, ifa_link);
+
+ if (ifa->ifa_addr->sa_family == AF_LINK)
+ continue;
#ifdef INET
/* XXX: Ugly!! ad hoc just for INET */
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
@@ -513,6 +516,11 @@ if_detach(ifp)
in6_ifdetach(ifp);
#endif
+ /* We can now free link ifaddr. */
+ ifa = TAILQ_FIRST(&ifp->if_addrhead);
+ TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
+ IFAFREE(ifa);
+
/*
* Delete all remaining routes using this interface
* Unfortuneatly the only way to do this is to slog through
OpenPOWER on IntegriCloud