diff --git a/sys/net/if.c b/sys/net/if.c --- a/sys/net/if.c +++ b/sys/net/if.c @@ -521,7 +521,7 @@ free(pending, M_IFNET); } -VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY, +VNET_SHUTDOWN(vnet_if_return, SI_SUB_PROTO_IF, SI_ORDER_ANY, vnet_if_return, NULL); #endif diff --git a/sys/net/route/route_tables.c b/sys/net/route/route_tables.c --- a/sys/net/route/route_tables.c +++ b/sys/net/route/route_tables.c @@ -289,7 +289,7 @@ #ifdef VIMAGE static void -rtables_destroy(const void *unused __unused) +rtables_flush(const void *unused __unused) { struct rib_head *rnh; struct domain *dom; @@ -303,10 +303,19 @@ for (int i = 0; i < V_rt_numfibs; i++) { rnh = rt_tables_get_rnh(i, family); dom->dom_rtdetach(rnh); + // FIXME give other components a chance to cleanup nh ref ? + // XXX RIB_NOTIFY_DELAYED ? + // rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, NULL); } } RTABLES_UNLOCK(); +} +VNET_SHUTDOWN(rtables_flush, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, + rtables_flush, NULL); +static void +rtables_destroy(const void *unused __unused) +{ /* * dom_rtdetach calls rt_table_destroy(), which * schedules deletion for all rtentries, nexthops and control diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -378,6 +378,17 @@ SYSINIT(ip_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip_init, NULL); #ifdef VIMAGE +static void +ip_shutdown(void *unused __unused) +{ + /* Remove the IPv4 addresses from all interfaces. */ + in_ifscrub_all(); + + /* Make sure the IPv4 routes are gone as well. */ + rib_flush_routes_family(AF_INET); +} +VNET_SHUTDOWN(ip_shutdown, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip_shutdown, NULL); + static void ip_destroy(void *unused __unused) { @@ -402,12 +413,6 @@ "error %d returned\n", __func__, error); } - /* Remove the IPv4 addresses from all interfaces. */ - in_ifscrub_all(); - - /* Make sure the IPv4 routes are gone as well. */ - rib_flush_routes_family(AF_INET); - /* Destroy IP reassembly queue. */ ipreass_destroy(); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -336,10 +336,36 @@ #ifdef VIMAGE static void -ip6_destroy(void *unused __unused) +ip6_shutdown(void *unused __unused) { struct ifaddr *ifa, *nifa; struct ifnet *ifp; + + /* Cleanup addresses. */ + IFNET_RLOCK(); + CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { + /* Cannot lock here - lock recursion. */ + /* IF_ADDR_LOCK(ifp); */ + CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, nifa) { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + in6_purgeaddr(ifa); + } + /* IF_ADDR_UNLOCK(ifp); */ + // FIXME in6_ifdetach() or in6_ifdetach_destroy() ? + in6_ifdetach(ifp); + mld_domifdetach(ifp); + } + IFNET_RUNLOCK(); + + /* Make sure any routes are gone as well. */ + rib_flush_routes_family(AF_INET6); +} +VNET_SHUTDOWN(ip6_shutdown, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_shutdown, NULL); + +static void +ip6_destroy(void *unused __unused) +{ int error; #ifdef RSS @@ -361,25 +387,6 @@ "error %d returned\n", __func__, error); } - /* Cleanup addresses. */ - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - /* Cannot lock here - lock recursion. */ - /* IF_ADDR_LOCK(ifp); */ - CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, nifa) { - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - in6_purgeaddr(ifa); - } - /* IF_ADDR_UNLOCK(ifp); */ - in6_ifdetach_destroy(ifp); - mld_domifdetach(ifp); - } - IFNET_RUNLOCK(); - - /* Make sure any routes are gone as well. */ - rib_flush_routes_family(AF_INET6); - frag6_destroy(); nd6_destroy(); in6_ifattach_destroy();