aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/route.c15
-rw-r--r--sys/net/route.h2
-rw-r--r--sys/net/route/route_ctl.c36
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet6/ip6_input.c5
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();