svn commit: r367941 - in head/sys: net net/route netinet netinet6

Alexander V. Chernikov melifaro at FreeBSD.org
Sun Nov 22 20:21:12 UTC 2020


Author: melifaro
Date: Sun Nov 22 20:21:10 2020
New Revision: 367941
URL: https://svnweb.freebsd.org/changeset/base/367941

Log:
  Refactor rib iterator functions.
  
  * Make rib_walk() order of arguments consistent with the rest of RIB api
  * Add rib_walk_ext() allowing to exec callback before/after iteration.
  * Rename rt_foreach_fib_walk_del -> rib_foreach_table_walk_del
  * Rename rt_forach_fib_walk -> rib_foreach_table_walk
  * Move rib_foreach_table_walk{_del} to route/route_helpers.c
  * Slightly refactor rib_foreach_table_walk{_del} to make the implementation
   consistent and prepare for upcoming iterator optimizations.
  
  Differential Revision:	https://reviews.freebsd.org/D27219

Modified:
  head/sys/net/route.c
  head/sys/net/route.h
  head/sys/net/route/route_ctl.c
  head/sys/net/route/route_ctl.h
  head/sys/net/route/route_helpers.c
  head/sys/netinet/in_rmx.c
  head/sys/netinet6/nd6_rtr.c

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/net/route.c	Sun Nov 22 20:21:10 2020	(r367941)
@@ -458,81 +458,6 @@ rib_free_info(struct rt_addrinfo *info)
 }
 
 /*
- * Iterates over all existing fibs in system calling
- *  @setwa_f function prior to traversing each fib.
- *  Calls @wa_f function for each element in current fib.
- * If af is not AF_UNSPEC, iterates over fibs in particular
- * address family.
- */
-void
-rt_foreach_fib_walk(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f,
-    void *arg)
-{
-	struct rib_head *rnh;
-	uint32_t fibnum;
-	int i;
-
-	for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
-		/* Do we want some specific family? */
-		if (af != AF_UNSPEC) {
-			rnh = rt_tables_get_rnh(fibnum, af);
-			if (rnh == NULL)
-				continue;
-			if (setwa_f != NULL)
-				setwa_f(rnh, fibnum, af, arg);
-
-			RIB_WLOCK(rnh);
-			rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg);
-			RIB_WUNLOCK(rnh);
-			continue;
-		}
-
-		for (i = 1; i <= AF_MAX; i++) {
-			rnh = rt_tables_get_rnh(fibnum, i);
-			if (rnh == NULL)
-				continue;
-			if (setwa_f != NULL)
-				setwa_f(rnh, fibnum, i, arg);
-
-			RIB_WLOCK(rnh);
-			rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg);
-			RIB_WUNLOCK(rnh);
-		}
-	}
-}
-
-/*
- * Iterates over all existing fibs in system and deletes each element
- *  for which @filter_f function returns non-zero value.
- * If @family is not AF_UNSPEC, iterates over fibs in particular
- * address family.
- */
-void
-rt_foreach_fib_walk_del(int family, rt_filter_f_t *filter_f, void *arg)
-{
-	u_int fibnum;
-	int i, start, end;
-
-	for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
-		/* Do we want some specific family? */
-		if (family != AF_UNSPEC) {
-			start = family;
-			end = family;
-		} else {
-			start = 1;
-			end = AF_MAX;
-		}
-
-		for (i = start; i <= end; i++) {
-			if (rt_tables_get_rnh(fibnum, i) == NULL)
-				continue;
-
-			rib_walk_del(fibnum, i, filter_f, arg, 0);
-		}
-	}
-}
-
-/*
  * Delete Routes for a Network Interface
  *
  * Called for each routing entry via the rnh->rnh_walktree() call above
@@ -577,14 +502,14 @@ 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));
 
-	rt_foreach_fib_walk_del(af, rt_ifdelroute, ifp);
+	rib_foreach_table_walk_del(af, rt_ifdelroute, ifp);
 }
 
 void
 rt_flushifroutes(struct ifnet *ifp)
 {
 
-	rt_foreach_fib_walk_del(AF_UNSPEC, rt_ifdelroute, ifp);
+	rib_foreach_table_walk_del(AF_UNSPEC, rt_ifdelroute, ifp);
 }
 
 /*

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/net/route.h	Sun Nov 22 20:21:10 2020	(r367941)
@@ -342,7 +342,7 @@ struct rt_msghdr {
 
 struct rtentry;
 struct nhop_object;
-typedef int rt_filter_f_t(const struct rtentry *, const struct nhop_object *,
+typedef int rib_filter_f_t(const struct rtentry *, const struct nhop_object *,
     void *);
 
 struct rt_addrinfo {
@@ -351,7 +351,7 @@ struct rt_addrinfo {
 	struct	sockaddr *rti_info[RTAX_MAX];	/* Sockaddr data */
 	struct	ifaddr *rti_ifa;		/* value of rt_ifa addr */
 	struct	ifnet *rti_ifp;			/* route interface */
-	rt_filter_f_t	*rti_filter;		/* filter function */
+	rib_filter_f_t	*rti_filter;		/* filter function */
 	void	*rti_filterdata;		/* filter paramenters */
 	u_long	rti_mflags;			/* metrics RTV_ flags */
 	u_long	rti_spare;			/* Will be used for fib */

Modified: head/sys/net/route/route_ctl.c
==============================================================================
--- head/sys/net/route/route_ctl.c	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/net/route/route_ctl.c	Sun Nov 22 20:21:10 2020	(r367941)
@@ -1143,7 +1143,7 @@ rt_checkdelroute(struct radix_node *rn, void *arg)
  * @report: true if rtsock notification is needed.
  */
 void
-rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f, void *arg, bool report)
+rib_walk_del(u_int fibnum, int family, rib_filter_f_t *filter_f, void *arg, bool report)
 {
 	struct rib_head *rnh;
 	struct rt_delinfo di;

Modified: head/sys/net/route/route_ctl.h
==============================================================================
--- head/sys/net/route/route_ctl.h	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/net/route/route_ctl.h	Sun Nov 22 20:21:10 2020	(r367941)
@@ -61,14 +61,24 @@ int rib_add_redirect(u_int fibnum, struct sockaddr *ds
   struct sockaddr *gateway, struct sockaddr *author, struct ifnet *ifp,
   int flags, int expire_sec);
 
-typedef int rt_walktree_f_t(struct rtentry *, void *);
-void rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void *arg);
-void rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f,
+enum rib_walk_hook {
+	RIB_WALK_HOOK_PRE,	/* Hook is called before iteration */
+	RIB_WALK_HOOK_POST,	/* Hook is called after iteration */
+};
+typedef int rib_walktree_f_t(struct rtentry *, void *);
+typedef void rib_walk_hook_f_t(struct rib_head *rnh, enum rib_walk_hook stage,
+  void *arg);
+void rib_walk(uint32_t fibnum, int af, bool wlock, rib_walktree_f_t *wa_f,
+  void *arg);
+void rib_walk_ext(uint32_t fibnum, int af, bool wlock, rib_walktree_f_t *wa_f,
+  rib_walk_hook_f_t *hook_f, void *arg);
+
+void rib_walk_del(u_int fibnum, int family, rib_filter_f_t *filter_f,
   void *arg, bool report);
 
-typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
-void rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, void *);
-void rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg);
+void rib_foreach_table_walk(int family, bool wlock, rib_walktree_f_t *wa_f,
+  rib_walk_hook_f_t *hook_f, void *arg);
+void rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg);
 
 struct route_nhop_data;
 const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family,

Modified: head/sys/net/route/route_helpers.c
==============================================================================
--- head/sys/net/route/route_helpers.c	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/net/route/route_helpers.c	Sun Nov 22 20:21:10 2020	(r367941)
@@ -71,21 +71,96 @@ __FBSDID("$FreeBSD$");
  * Calls @wa_f with @arg for each entry in the table specified by
  * @af and @fibnum.
  *
- * Table is traversed under read lock.
+ * @ss_t callback is called before and after the tree traversal
+ *  while holding table lock.
+ *
+ * Table is traversed under read lock unless @wlock is set.
  */
 void
-rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void *arg)
+rib_walk_ext(uint32_t fibnum, int family, bool wlock, rib_walktree_f_t *wa_f,
+    rib_walk_hook_f_t *hook_f, void *arg)
 {
 	RIB_RLOCK_TRACKER;
 	struct rib_head *rnh;
 
-	if ((rnh = rt_tables_get_rnh(fibnum, af)) == NULL)
+	if ((rnh = rt_tables_get_rnh(fibnum, family)) == NULL)
 		return;
 
-	RIB_RLOCK(rnh);
+	if (wlock)
+		RIB_WLOCK(rnh);
+	else
+		RIB_RLOCK(rnh);
+	if (hook_f != NULL)
+		hook_f(rnh, RIB_WALK_HOOK_PRE, arg);
 	rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f, arg);
-	RIB_RUNLOCK(rnh);
+	if (hook_f != NULL)
+		hook_f(rnh, RIB_WALK_HOOK_POST, arg);
+	if (wlock)
+		RIB_WUNLOCK(rnh);
+	else
+		RIB_RUNLOCK(rnh);
 }
+
+/*
+ * Calls @wa_f with @arg for each entry in the table specified by
+ * @af and @fibnum.
+ *
+ * Table is traversed under read lock unless @wlock is set.
+ */
+void
+rib_walk(uint32_t fibnum, int family, bool wlock, rib_walktree_f_t *wa_f,
+    void *arg)
+{
+
+	rib_walk_ext(fibnum, family, wlock, wa_f, NULL, arg);
+}
+
+/*
+ * Iterates over all existing fibs in system calling
+ *  @hook_f function before/after traversing each fib.
+ *  Calls @wa_f function for each element in current fib.
+ * If af is not AF_UNSPEC, iterates over fibs in particular
+ * address family.
+ */
+void
+rib_foreach_table_walk(int family, bool wlock, rib_walktree_f_t *wa_f,
+    rib_walk_hook_f_t *hook_f, void *arg)
+{
+
+	for (uint32_t fibnum = 0; fibnum < rt_numfibs; fibnum++) {
+		/* Do we want some specific family? */
+		if (family != AF_UNSPEC) {
+			rib_walk_ext(fibnum, family, wlock, wa_f, hook_f, arg); 
+			continue;
+		}
+
+		for (int i = 1; i <= AF_MAX; i++)
+			rib_walk_ext(fibnum, i, wlock, wa_f, hook_f, arg);
+	}
+}
+
+/*
+ * Iterates over all existing fibs in system and deletes each element
+ *  for which @filter_f function returns non-zero value.
+ * If @family is not AF_UNSPEC, iterates over fibs in particular
+ * address family.
+ */
+void
+rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg)
+{
+
+	for (uint32_t fibnum = 0; fibnum < rt_numfibs; fibnum++) {
+		/* Do we want some specific family? */
+		if (family != AF_UNSPEC) {
+			rib_walk_del(fibnum, family, filter_f, arg, 0);
+			continue;
+		}
+
+		for (int i = 1; i <= AF_MAX; i++)
+			rib_walk_del(fibnum, i, filter_f, arg, 0);
+	}
+}
+
 
 /*
  * Wrapper for the control plane functions for performing af-agnostic

Modified: head/sys/netinet/in_rmx.c
==============================================================================
--- head/sys/netinet/in_rmx.c	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/netinet/in_rmx.c	Sun Nov 22 20:21:10 2020	(r367941)
@@ -178,6 +178,6 @@ in_ifadown(struct ifaddr *ifa, int delete)
 	arg.ifa = ifa;
 	arg.del = delete;
 
-	rt_foreach_fib_walk_del(AF_INET, in_ifadownkill, &arg);
+	rib_foreach_table_walk_del(AF_INET, in_ifadownkill, &arg);
 	ifa->ifa_flags &= ~IFA_ROUTE;		/* XXXlocking? */
 }

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c	Sun Nov 22 20:16:46 2020	(r367940)
+++ head/sys/netinet6/nd6_rtr.c	Sun Nov 22 20:21:10 2020	(r367941)
@@ -2460,7 +2460,7 @@ rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
 		return;
 
 	/* XXX Do we really need to walk any but the default FIB? */
-	rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
+	rib_foreach_table_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
 }
 
 int


More information about the svn-src-head mailing list