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
This commit is contained in:
parent
5e38d9e483
commit
7511a63825
@ -457,81 +457,6 @@ rib_free_info(struct rt_addrinfo *info)
|
||||
if_rele(info->rti_ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -61,14 +61,24 @@ int rib_add_redirect(u_int fibnum, struct sockaddr *dst,
|
||||
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,
|
||||
|
@ -71,22 +71,97 @@ __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
|
||||
* lookups.
|
||||
|
@ -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? */
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user