Add tracking for rib/nhops/nhgrp objects and provide cumulative number accessors.
The resulting KPI can be used by routing table consumers to estimate the required scale for route table export. * Add tracking for rib routes * Add accessors for number of nexthops/nexthop objects * Simplify rib_unsubscribe: store rnh we're attached to instead of requiring it up again on destruction. This helps in the cases when rnh is not linked yet/already unlinked. Differential Revision: https://reviews.freebsd.org/D27404
This commit is contained in:
parent
3c48106aaa
commit
98d5c4e5c8
@ -762,6 +762,21 @@ nhgrp_get_idx(const struct nhgrp_object *nhg)
|
||||
return (nhg_priv->nhg_idx);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nhgrp_get_count(struct rib_head *rh)
|
||||
{
|
||||
struct nh_control *ctl;
|
||||
uint32_t count;
|
||||
|
||||
ctl = rh->nh_control;
|
||||
|
||||
NHOPS_RLOCK(ctl);
|
||||
count = ctl->gr_head.items_count;
|
||||
NHOPS_RUNLOCK(ctl);
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
int
|
||||
nhgrp_dump_sysctl(struct rib_head *rh, struct sysctl_req *w)
|
||||
{
|
||||
|
@ -852,6 +852,21 @@ dump_nhop_entry(struct rib_head *rh, struct nhop_object *nh, struct sysctl_req *
|
||||
return (error);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nhops_get_count(struct rib_head *rh)
|
||||
{
|
||||
struct nh_control *ctl;
|
||||
uint32_t count;
|
||||
|
||||
ctl = rh->nh_control;
|
||||
|
||||
NHOPS_RLOCK(ctl);
|
||||
count = ctl->nh_head.items_count;
|
||||
NHOPS_RUNLOCK(ctl);
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
int
|
||||
nhops_dump_sysctl(struct rib_head *rh, struct sysctl_req *w)
|
||||
{
|
||||
|
@ -70,6 +70,7 @@ struct rib_subscription {
|
||||
CK_STAILQ_ENTRY(rib_subscription) next;
|
||||
rib_subscription_cb_t *func;
|
||||
void *arg;
|
||||
struct rib_head *rnh;
|
||||
enum rib_subscription_type type;
|
||||
struct epoch_context epoch_ctx;
|
||||
};
|
||||
@ -669,6 +670,8 @@ rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, struct rib_cmd_info
|
||||
|
||||
/* Finalize notification */
|
||||
rnh->rnh_gen++;
|
||||
rnh->rnh_prefixes--;
|
||||
|
||||
rc->rc_cmd = RTM_DELETE;
|
||||
rc->rc_rt = rt;
|
||||
rc->rc_nh_old = rt->rt_nhop;
|
||||
@ -929,6 +932,7 @@ add_route_nhop(struct rib_head *rnh, struct rtentry *rt,
|
||||
|
||||
/* Finalize notification */
|
||||
rnh->rnh_gen++;
|
||||
rnh->rnh_prefixes++;
|
||||
|
||||
rc->rc_cmd = RTM_ADD;
|
||||
rc->rc_rt = rt;
|
||||
@ -984,6 +988,8 @@ change_route_nhop(struct rib_head *rnh, struct rtentry *rt,
|
||||
|
||||
/* Finalize notification */
|
||||
rnh->rnh_gen++;
|
||||
if (rnd->rnd_nhop == NULL)
|
||||
rnh->rnh_prefixes--;
|
||||
|
||||
rc->rc_cmd = (rnd->rnd_nhop != NULL) ? RTM_CHANGE : RTM_DELETE;
|
||||
rc->rc_rt = rt;
|
||||
@ -1222,7 +1228,7 @@ allocate_subscription(rib_subscription_cb_t *f, void *arg,
|
||||
enum rib_subscription_type type, bool waitok)
|
||||
{
|
||||
struct rib_subscription *rs;
|
||||
int flags = M_ZERO | (waitok ? M_WAITOK : 0);
|
||||
int flags = M_ZERO | (waitok ? M_WAITOK : M_NOWAIT);
|
||||
|
||||
rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
|
||||
if (rs == NULL)
|
||||
@ -1246,22 +1252,14 @@ rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg,
|
||||
enum rib_subscription_type type, bool waitok)
|
||||
{
|
||||
struct rib_head *rnh;
|
||||
struct rib_subscription *rs;
|
||||
struct epoch_tracker et;
|
||||
|
||||
if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
|
||||
rnh = rt_tables_get_rnh(fibnum, family);
|
||||
|
||||
RIB_WLOCK(rnh);
|
||||
CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
|
||||
RIB_WUNLOCK(rnh);
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
||||
return (rs);
|
||||
return (rib_subscribe_internal(rnh, f, arg, type, waitok));
|
||||
}
|
||||
|
||||
struct rib_subscription *
|
||||
@ -1273,6 +1271,7 @@ rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg
|
||||
|
||||
if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL)
|
||||
return (NULL);
|
||||
rs->rnh = rnh;
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
RIB_WLOCK(rnh);
|
||||
@ -1284,23 +1283,15 @@ rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove rtable subscription @rs from the table specified by @fibnum
|
||||
* and @family.
|
||||
* Remove rtable subscription @rs from the routing table.
|
||||
* Needs to be run in network epoch.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int
|
||||
rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs)
|
||||
void
|
||||
rib_unsibscribe(struct rib_subscription *rs)
|
||||
{
|
||||
struct rib_head *rnh;
|
||||
struct rib_head *rnh = rs->rnh;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
|
||||
rnh = rt_tables_get_rnh(fibnum, family);
|
||||
|
||||
if (rnh == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
RIB_WLOCK(rnh);
|
||||
CK_STAILQ_REMOVE(&rnh->rnh_subscribers, rs, rib_subscription, next);
|
||||
@ -1308,8 +1299,6 @@ rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs)
|
||||
|
||||
epoch_call(net_epoch_preempt, destroy_subscription_epoch,
|
||||
&rs->epoch_ctx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -87,13 +87,18 @@ const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family,
|
||||
const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family,
|
||||
const struct sockaddr *dst, struct route_nhop_data *rnd);
|
||||
|
||||
/* Nexthops */
|
||||
uint32_t nhops_get_count(struct rib_head *rh);
|
||||
|
||||
/* Multipath */
|
||||
struct nhgrp_object;
|
||||
struct weightened_nhop;
|
||||
|
||||
struct weightened_nhop *nhgrp_get_nhops(struct nhgrp_object *nhg,
|
||||
uint32_t *pnum_nhops);
|
||||
uint32_t nhgrp_get_count(struct rib_head *rh);
|
||||
|
||||
/* Route subscriptions */
|
||||
enum rib_subscription_type {
|
||||
RIB_NOTIFY_IMMEDIATE,
|
||||
RIB_NOTIFY_DELAYED
|
||||
@ -109,6 +114,6 @@ struct rib_subscription *rib_subscribe(uint32_t fibnum, int family,
|
||||
struct rib_subscription *rib_subscribe_internal(struct rib_head *rnh,
|
||||
rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
|
||||
bool waitok);
|
||||
int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs);
|
||||
void rib_unsibscribe(struct rib_subscription *rs);
|
||||
|
||||
#endif
|
||||
|
@ -70,6 +70,7 @@ struct rib_head {
|
||||
u_int rib_fibnum; /* fib number */
|
||||
struct callout expire_callout; /* Callout for expiring dynamic routes */
|
||||
time_t next_expire; /* Next expire run ts */
|
||||
uint32_t rnh_prefixes; /* Number of prefixes */
|
||||
struct nh_control *nh_control; /* nexthop subsystem data */
|
||||
CK_STAILQ_HEAD(, rib_subscription) rnh_subscribers;/* notification subscribers */
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user