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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to