diff options
author | ume <ume@FreeBSD.org> | 2003-10-16 13:38:29 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-10-16 13:38:29 +0000 |
commit | 0fb87ae0efeb90ac8a95983a5e83c87b78356e5c (patch) | |
tree | 8b1c446a173d4ed6c6bc6a9d6e7cba3437653b82 /sys/net/if.c | |
parent | 300addad5e8798817da8f6eea92ecd72cb8a881e (diff) | |
download | FreeBSD-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.c | 14 |
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 |