diff options
-rw-r--r-- | sys/net/route.c | 15 | ||||
-rw-r--r-- | sys/net/route.h | 2 | ||||
-rw-r--r-- | sys/net/route/route_ctl.c | 36 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 5 |
5 files changed, 41 insertions, 23 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index a68e46c37861..f07cb3f6581a 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -495,21 +495,6 @@ rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *nh, void *arg) return (1); } -/* - * Delete all remaining routes using this interface - * Unfortuneatly the only way to do this is to slog through - * the entire routing table looking for routes which point - * to this interface...oh well... - */ -void -rt_flushifroutes_af(struct ifnet *ifp, int af) -{ - KASSERT((af >= 1 && af <= AF_MAX), ("%s: af %d not >= 1 and <= %d", - __func__, af, AF_MAX)); - - rib_foreach_table_walk_del(af, rt_ifdelroute, ifp); -} - void rt_flushifroutes(struct ifnet *ifp) { diff --git a/sys/net/route.h b/sys/net/route.h index ab6e1aabc5ae..3fdca303596e 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -429,7 +429,6 @@ struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst, void rt_updatemtu(struct ifnet *); -void rt_flushifroutes_af(struct ifnet *, int); void rt_flushifroutes(struct ifnet *ifp); /* XXX MRT NEW VERSIONS THAT USE FIBs @@ -442,6 +441,7 @@ int rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, uint32_t, void rib_free_info(struct rt_addrinfo *info); /* New API */ +void rib_flush_routes_family(int family); struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags, uint32_t flowid); #endif diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index 9aedfb9d5855..46e0bcfee6b7 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -1341,6 +1341,42 @@ rib_walk_del(u_int fibnum, int family, rib_filter_f_t *filter_f, void *arg, bool NET_EPOCH_EXIT(et); } +static int +rt_delete_unconditional(struct radix_node *rn, void *arg) +{ + struct rtentry *rt = RNTORT(rn); + struct rib_head *rnh = (struct rib_head *)arg; + + rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), &rnh->head); + if (RNTORT(rn) == rt) + rtfree(rt); + + return (0); +} + +/* + * Removes all routes from the routing table without executing notifications. + * rtentres will be removed after the end of a current epoch. + */ +static void +rib_flush_routes(struct rib_head *rnh) +{ + RIB_WLOCK(rnh); + rnh->rnh_walktree(&rnh->head, rt_delete_unconditional, rnh); + RIB_WUNLOCK(rnh); +} + +void +rib_flush_routes_family(int family) +{ + struct rib_head *rnh; + + for (uint32_t fibnum = 0; fibnum < rt_numfibs; fibnum++) { + if ((rnh = rt_tables_get_rnh(fibnum, family)) != NULL) + rib_flush_routes(rnh); + } +} + static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type, struct rib_cmd_info *rc) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index be21decff6cb..a85f8ac7b567 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -379,7 +379,6 @@ ip_init(void) static void ip_destroy(void *unused __unused) { - struct ifnet *ifp; int error; #ifdef RSS @@ -405,10 +404,7 @@ ip_destroy(void *unused __unused) in_ifscrub_all(); /* Make sure the IPv4 routes are gone as well. */ - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) - rt_flushifroutes_af(ifp, AF_INET); - IFNET_RUNLOCK(); + 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 index 80e5acc62548..9ea578f88417 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -386,11 +386,12 @@ ip6_destroy(void *unused __unused) /* IF_ADDR_UNLOCK(ifp); */ in6_ifdetach_destroy(ifp); mld_domifdetach(ifp); - /* Make sure any routes are gone as well. */ - rt_flushifroutes_af(ifp, AF_INET6); } IFNET_RUNLOCK(); + /* Make sure any routes are gone as well. */ + rib_flush_routes_family(AF_INET6); + frag6_destroy(); nd6_destroy(); in6_ifattach_destroy(); |