mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-27 10:04:18 +00:00
Merge pull request #5740 from sworleys/NHG-2Grp-Fixes
zebra: NHG fixes in the dataplane conversion function
This commit is contained in:
commit
ee8606ee39
@ -1737,6 +1737,36 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function called after resolution to walk nhg rb trees
|
||||||
|
* and toggle the NEXTHOP_GROUP_VALID flag if the nexthop
|
||||||
|
* is active on singleton NHEs.
|
||||||
|
*/
|
||||||
|
static bool zebra_nhg_set_valid_if_active(struct nhg_hash_entry *nhe)
|
||||||
|
{
|
||||||
|
struct nhg_connected *rb_node_dep = NULL;
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
if (!zebra_nhg_depends_is_empty(nhe)) {
|
||||||
|
/* Is at least one depend valid? */
|
||||||
|
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
|
||||||
|
if (zebra_nhg_set_valid_if_active(rb_node_dep->nhe))
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should be fully resolved singleton at this point */
|
||||||
|
if (CHECK_FLAG(nhe->nhg.nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (valid)
|
||||||
|
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over all nexthops of the given RIB entry and refresh their
|
* Iterate over all nexthops of the given RIB entry and refresh their
|
||||||
* ACTIVE flag. If any nexthop is found to toggle the ACTIVE flag,
|
* ACTIVE flag. If any nexthop is found to toggle the ACTIVE flag,
|
||||||
@ -1811,19 +1841,11 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
route_entry_update_nhe(re, new_nhe);
|
route_entry_update_nhe(re, new_nhe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curr_active) {
|
/* Walk the NHE depends tree and toggle NEXTHOP_GROUP_VALID
|
||||||
struct nhg_hash_entry *nhe = NULL;
|
* flag where appropriate.
|
||||||
|
*/
|
||||||
nhe = zebra_nhg_lookup_id(re->nhe_id);
|
if (curr_active)
|
||||||
|
zebra_nhg_set_valid_if_active(re->nhe);
|
||||||
if (nhe)
|
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
|
||||||
else
|
|
||||||
flog_err(
|
|
||||||
EC_ZEBRA_TABLE_LOOKUP_FAILED,
|
|
||||||
"Active update on NHE id=%u that we do not have in our tables",
|
|
||||||
re->nhe_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not need these nexthops anymore since they
|
* Do not need these nexthops anymore since they
|
||||||
@ -1834,17 +1856,34 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
return curr_active;
|
return curr_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a nhe into a group array */
|
/* Recursively construct a grp array of fully resolved IDs.
|
||||||
uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
|
*
|
||||||
|
* This function allows us to account for groups within groups,
|
||||||
|
* by converting them into a flat array of IDs.
|
||||||
|
*
|
||||||
|
* nh_grp is modified at every level of recursion to append
|
||||||
|
* to it the next unique, fully resolved ID from the entire tree.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* I'm pretty sure we only allow ONE level of group within group currently.
|
||||||
|
* But making this recursive just in case that ever changes.
|
||||||
|
*/
|
||||||
|
static uint8_t zebra_nhg_nhe2grp_internal(struct nh_grp *grp,
|
||||||
|
uint8_t curr_index,
|
||||||
|
struct nhg_hash_entry *nhe,
|
||||||
int max_num)
|
int max_num)
|
||||||
{
|
{
|
||||||
struct nhg_connected *rb_node_dep = NULL;
|
struct nhg_connected *rb_node_dep = NULL;
|
||||||
struct nhg_hash_entry *depend = NULL;
|
struct nhg_hash_entry *depend = NULL;
|
||||||
uint8_t i = 0;
|
uint8_t i = curr_index;
|
||||||
|
|
||||||
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
|
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
|
||||||
bool duplicate = false;
|
bool duplicate = false;
|
||||||
|
|
||||||
|
if (i >= max_num)
|
||||||
|
goto done;
|
||||||
|
|
||||||
depend = rb_node_dep->nhe;
|
depend = rb_node_dep->nhe;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1861,27 +1900,68 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for duplicate IDs, kernel doesn't like that */
|
if (!zebra_nhg_depends_is_empty(depend)) {
|
||||||
for (int j = 0; j < i; j++) {
|
/* This is a group within a group */
|
||||||
if (depend->id == grp[j].id)
|
i = zebra_nhg_nhe2grp_internal(grp, i, depend, max_num);
|
||||||
duplicate = true;
|
} else {
|
||||||
|
if (!CHECK_FLAG(depend->flags, NEXTHOP_GROUP_VALID)) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED
|
||||||
|
|| IS_ZEBRA_DEBUG_NHG)
|
||||||
|
zlog_debug(
|
||||||
|
"%s: Nexthop ID (%u) not valid, not appending to dataplane install group",
|
||||||
|
__func__, depend->id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the nexthop not installed/queued for install don't
|
||||||
|
* put in the ID array.
|
||||||
|
*/
|
||||||
|
if (!(CHECK_FLAG(depend->flags, NEXTHOP_GROUP_INSTALLED)
|
||||||
|
|| CHECK_FLAG(depend->flags,
|
||||||
|
NEXTHOP_GROUP_QUEUED))) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED
|
||||||
|
|| IS_ZEBRA_DEBUG_NHG)
|
||||||
|
zlog_debug(
|
||||||
|
"%s: Nexthop ID (%u) not installed or queued for install, not appending to dataplane install group",
|
||||||
|
__func__, depend->id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for duplicate IDs, ignore if found. */
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
if (depend->id == grp[j].id) {
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicate) {
|
||||||
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED
|
||||||
|
|| IS_ZEBRA_DEBUG_NHG)
|
||||||
|
zlog_debug(
|
||||||
|
"%s: Nexthop ID (%u) is duplicate, not appending to dataplane install group",
|
||||||
|
__func__, depend->id);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!duplicate) {
|
|
||||||
grp[i].id = depend->id;
|
grp[i].id = depend->id;
|
||||||
/* We aren't using weights for anything right now */
|
|
||||||
grp[i].weight = depend->nhg.nexthop->weight;
|
grp[i].weight = depend->nhg.nexthop->weight;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= max_num)
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a nhe into a group array */
|
||||||
|
uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
|
||||||
|
int max_num)
|
||||||
|
{
|
||||||
|
/* Call into the recursive function */
|
||||||
|
return zebra_nhg_nhe2grp_internal(grp, 0, nhe, max_num);
|
||||||
|
}
|
||||||
|
|
||||||
void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
||||||
{
|
{
|
||||||
struct nhg_connected *rb_node_dep = NULL;
|
struct nhg_connected *rb_node_dep = NULL;
|
||||||
@ -1894,7 +1974,8 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
|||||||
zebra_nhg_install_kernel(rb_node_dep->nhe);
|
zebra_nhg_install_kernel(rb_node_dep->nhe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
|
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
|
||||||
|
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
|
||||||
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
|
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
|
||||||
/* Change its type to us since we are installing it */
|
/* Change its type to us since we are installing it */
|
||||||
nhe->type = ZEBRA_ROUTE_NHG;
|
nhe->type = ZEBRA_ROUTE_NHG;
|
||||||
|
Loading…
Reference in New Issue
Block a user