commit a3f7b9dda59c43b7d0f24b83fd0647cac9012bc9 Author: Ryota Ozaki Date: Wed Jun 29 15:50:35 2016 +0900 Make sure all addresses of an interfaces are freed in if_detach diff --git a/sys/net/if.c b/sys/net/if.c index 314e352..8fa1b26 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1117,7 +1117,7 @@ if_detach(struct ifnet *ifp) sysctl_teardown(&ifp->if_sysctl_log); mutex_enter(ifp->if_ioctl_lock); - ifp->if_ioctl = if_nullioctl; + if_deactivate(ifp); mutex_exit(ifp->if_ioctl_lock); IFNET_LOCK(); @@ -1130,7 +1130,7 @@ if_detach(struct ifnet *ifp) mutex_obj_free(ifp->if_ioctl_lock); ifp->if_ioctl_lock = NULL; - if (ifp->if_slowtimo != NULL) { + if (ifp->if_slowtimo != NULL && ifp->if_slowtimo_ch != NULL) { ifp->if_slowtimo = NULL; callout_halt(ifp->if_slowtimo_ch, NULL); callout_destroy(ifp->if_slowtimo_ch); diff --git a/sys/net/route.c b/sys/net/route.c index 054b310..84c469d 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -150,6 +150,7 @@ static void rt_maskedcopy(const struct sockaddr *, struct sockaddr *, const struct sockaddr *); static void rtcache_clear(struct route *); +static void rtcache_clear_rtentry(int, struct rtentry *); static void rtcache_invalidate(struct dom_rtlist *); #ifdef DDB @@ -794,6 +795,7 @@ rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt) rt->rt_refcnt++; rtfree(rt); } + rtcache_clear_rtentry(dst->sa_family, rt); break; case RTM_ADD: @@ -1388,6 +1390,21 @@ rtcache_invalidate(struct dom_rtlist *rtlist) } static void +rtcache_clear_rtentry(int family, struct rtentry *rt) +{ + struct domain *dom; + struct route *ro; + + if ((dom = pffinddomain(family)) == NULL) + return; + + LIST_FOREACH(ro, &dom->dom_rtcache, ro_rtcache_next) { + if (ro->_ro_rt == rt) + rtcache_clear(ro); + } +} + +static void rtcache_clear(struct route *ro) { rtcache_invariants(ro); diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c index 2eaa34f..ca0f407 100644 --- a/sys/netinet/if_arp.c +++ b/sys/netinet/if_arp.c @@ -1483,7 +1483,7 @@ static void arp_dad_stoptimer(struct dadq *dp) { - callout_stop(&dp->dad_timer_ch); + callout_halt(&dp->dad_timer_ch, NULL); } static void diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index b786113..38dd0ac 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1074,7 +1074,7 @@ static void nd6_dad_stoptimer(struct dadq *dp) { - callout_stop(&dp->dad_timer_ch); + callout_halt(&dp->dad_timer_ch, NULL); } /*