routing: provide dedicated function for nhgrp creation and linking.

There is a need to store client metadata in nexthops and nexthop groups.
This metadata is immutable and participate in nhop/nhg comparison.

Nexthops KPI already supports its: nexthop creation pattern is
```
nhop_alloc()
nhop_set_...()
...
nhop_get_nhop()
```

This change provides a similar pattern for the nexthop groups.
Specifically, it adds nhgrp_alloc(), nhgrp_get_nhgrp() and
nhgrp_set_uidx().

MFC after:	2 weeks
This commit is contained in:
Alexander V. Chernikov 2022-12-02 17:58:03 +00:00
parent da5d0a1dbc
commit 42f8123a4f
2 changed files with 77 additions and 11 deletions

View File

@ -459,15 +459,24 @@ free_nhgrp_nhops(struct nhgrp_priv *nhg_priv)
}
/*
* Creates or looks up an existing nexthop group based on @wn and @num_nhops.
*
* Returns referenced nhop group or NULL, passing error code in @perror.
* Allocate nexthop group of size @num_nhops with nexthops specified by
* @wn. Nexthops have to be unique and match the fibnum/family of the group.
* Returns unlinked nhgrp object on success or NULL and non-zero perror.
*/
struct nhgrp_priv *
get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
uint32_t uidx, int *perror)
struct nhgrp_object *
nhgrp_alloc(uint32_t fibnum, int family, struct weightened_nhop *wn, int num_nhops,
int *perror)
{
struct nhgrp_priv *key, *nhg_priv;
struct rib_head *rh = rt_tables_get_rnh(fibnum, family);
struct nhgrp_priv *nhg_priv;
struct nh_control *ctl;
if (rh == NULL) {
*perror = E2BIG;
return (NULL);
}
ctl = rh->nh_control;
if (num_nhops > RIB_MAX_MPATH_WIDTH) {
*perror = E2BIG;
@ -486,6 +495,10 @@ get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
sort_weightened_nhops(wn, num_nhops);
uint32_t last_id = 0;
for (int i = 0; i < num_nhops; i++) {
if (wn[i].nh->nh_priv->nh_control != ctl) {
*perror = EINVAL;
return (NULL);
}
if (wn[i].nh->nh_priv->nh_idx == last_id) {
*perror = EEXIST;
return (NULL);
@ -493,11 +506,25 @@ get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
last_id = wn[i].nh->nh_priv->nh_idx;
}
if ((key = alloc_nhgrp(wn, num_nhops)) == NULL) {
if ((nhg_priv = alloc_nhgrp(wn, num_nhops)) == NULL) {
*perror = ENOMEM;
return (NULL);
}
key->nhg_uidx = uidx;
nhg_priv->nh_control = ctl;
*perror = 0;
return (nhg_priv->nhg);
}
/*
* Finds an existing group matching @nhg or links @nhg to the tree.
* Returns the referenced group or NULL and non-zero @perror.
*/
struct nhgrp_object *
nhgrp_get_nhgrp(struct nhgrp_object *nhg, int *perror)
{
struct nhgrp_priv *nhg_priv, *key = NHGRP_PRIV(nhg);
struct nh_control *ctl = key->nh_control;
nhg_priv = find_nhgrp(ctl, key);
if (nhg_priv != NULL) {
@ -508,7 +535,7 @@ get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
*/
destroy_nhgrp_int(key);
*perror = 0;
return (nhg_priv);
return (nhg_priv->nhg);
} else {
/* No existing group, try to link the new one */
if (!ref_nhgrp_nhops(key)) {
@ -529,12 +556,35 @@ get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
return (NULL);
}
*perror = 0;
return (key);
return (nhg);
}
/* NOTREACHED */
}
/*
* Creates or looks up an existing nexthop group based on @wn and @num_nhops.
*
* Returns referenced nhop group or NULL, passing error code in @perror.
*/
struct nhgrp_priv *
get_nhgrp(struct nh_control *ctl, struct weightened_nhop *wn, int num_nhops,
uint32_t uidx, int *perror)
{
struct nhgrp_object *nhg;
nhg = nhgrp_alloc(ctl->ctl_rh->rib_fibnum, ctl->ctl_rh->rib_family,
wn, num_nhops, perror);
if (nhg == NULL)
return (NULL);
nhgrp_set_uidx(nhg, uidx);
nhg = nhgrp_get_nhgrp(nhg, perror);
if (nhg != NULL)
return (NHGRP_PRIV(nhg));
return (NULL);
}
/*
* Appends one or more nexthops denoted by @wm to the nexthop group @gr_orig.
*
@ -732,6 +782,18 @@ nhgrp_get_nhops(const struct nhgrp_object *nhg, uint32_t *pnum_nhops)
return (nhg_priv->nhg_nh_weights);
}
void
nhgrp_set_uidx(struct nhgrp_object *nhg, uint32_t uidx)
{
struct nhgrp_priv *nhg_priv;
KASSERT(((nhg->nhg_flags & MPF_MULTIPATH) != 0), ("nhop is not mpath"));
nhg_priv = NHGRP_PRIV(nhg);
nhg_priv->nhg_uidx = uidx;
}
uint32_t
nhgrp_get_uidx(const struct nhgrp_object *nhg)
{

View File

@ -224,6 +224,10 @@ void nhop_set_expire(struct nhop_object *nh, uint32_t expire);
struct rib_head *nhop_get_rh(const struct nhop_object *nh);
struct nhgrp_object;
struct nhgrp_object *nhgrp_alloc(uint32_t fibnum, int family,
struct weightened_nhop *wn, int num_nhops, int *perror);
struct nhgrp_object *nhgrp_get_nhgrp(struct nhgrp_object *nhg, int *perror);
void nhgrp_set_uidx(struct nhgrp_object *nhg, uint32_t uidx);
uint32_t nhgrp_get_uidx(const struct nhgrp_object *nhg);
uint8_t nhgrp_get_origin(const struct nhgrp_object *nhg);
void nhgrp_set_origin(struct nhgrp_object *nhg, uint8_t origin);