mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 22:30:43 +00:00
zebra: Refactor nexthop resolution in active funcs
Refactor/move around the code for nexthop resolution so that it occurs only when the nexthop actually changes. Further, provide a helper function to make the code more readable. Also, remove the check for NEXTHOPS_CHANGED as this flag is used specifcially for nexthop tracking and not an appropriate check here. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
parent
2f00094498
commit
df31a989ca
@ -918,6 +918,48 @@ static bool nexthop_valid_resolve(const struct nexthop *nexthop,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool zebra_nhg_set_resolved(struct nhg_hash_entry *nhe,
|
||||||
|
struct nhg_hash_entry *resolved)
|
||||||
|
{
|
||||||
|
bool new = true;
|
||||||
|
struct nhg_hash_entry *old_resolved = NULL;
|
||||||
|
struct nexthop *nh = NULL;
|
||||||
|
|
||||||
|
assert(!CHECK_FLAG(resolved->flags, NEXTHOP_GROUP_RECURSIVE));
|
||||||
|
|
||||||
|
/* If this was already resolved, get its resolved nhe */
|
||||||
|
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE))
|
||||||
|
old_resolved = zebra_nhg_resolve(nhe);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are going to do what is done in nexthop_active
|
||||||
|
* and clear whatever resolved nexthop may already be
|
||||||
|
* there.
|
||||||
|
*/
|
||||||
|
zebra_nhg_depends_release(nhe);
|
||||||
|
nhg_connected_head_free(&nhe->nhg_depends);
|
||||||
|
|
||||||
|
/* Add new resolved */
|
||||||
|
zebra_nhg_depends_add(nhe, resolved);
|
||||||
|
zebra_nhg_dependents_add(resolved, nhe);
|
||||||
|
|
||||||
|
if (old_resolved && resolved->id != old_resolved->id) {
|
||||||
|
resolved->refcnt += nhe->refcnt;
|
||||||
|
old_resolved->refcnt -= nhe->refcnt;
|
||||||
|
} else if (!old_resolved)
|
||||||
|
zebra_nhg_increment_ref(resolved);
|
||||||
|
else
|
||||||
|
new = false; /* Same one that was there */
|
||||||
|
|
||||||
|
for (nh = resolved->nhg->nexthop; nh; nh = nh->next)
|
||||||
|
nexthop_set_resolved(nhe->afi, nhe->nhg->nexthop, nh);
|
||||||
|
|
||||||
|
SET_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE);
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a nexthop we need to properly recursively resolve
|
* Given a nexthop we need to properly recursively resolve
|
||||||
* the route. As such, do a table lookup to find and match
|
* the route. As such, do a table lookup to find and match
|
||||||
@ -926,7 +968,7 @@ static bool nexthop_valid_resolve(const struct nexthop *nexthop,
|
|||||||
*/
|
*/
|
||||||
static int nexthop_active(afi_t afi, struct route_entry *re,
|
static int nexthop_active(afi_t afi, struct route_entry *re,
|
||||||
struct nexthop *nexthop, struct route_node *top,
|
struct nexthop *nexthop, struct route_node *top,
|
||||||
uint32_t *resolved_id)
|
struct nhg_hash_entry **resolved_nhe)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -1102,7 +1144,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
}
|
}
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
re->nexthop_mtu = match->mtu;
|
re->nexthop_mtu = match->mtu;
|
||||||
*resolved_id = match->nhe_id;
|
zebra_nhg_find_nexthop(resolved_nhe, 0,
|
||||||
|
nexthop->resolved, afi,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug("\t%s: Recursion failed to find",
|
zlog_debug("\t%s: Recursion failed to find",
|
||||||
@ -1124,7 +1168,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
}
|
}
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
re->nexthop_mtu = match->mtu;
|
re->nexthop_mtu = match->mtu;
|
||||||
*resolved_id = match->nhe_id;
|
zebra_nhg_find_nexthop(resolved_nhe, 0,
|
||||||
|
nexthop->resolved, afi,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (!resolved && IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -1165,7 +1211,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
static unsigned nexthop_active_check(struct route_node *rn,
|
static unsigned nexthop_active_check(struct route_node *rn,
|
||||||
struct route_entry *re,
|
struct route_entry *re,
|
||||||
struct nexthop *nexthop,
|
struct nexthop *nexthop,
|
||||||
uint32_t *resolved_id)
|
struct nhg_hash_entry **resolved_nhe)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
route_map_result_t ret = RMAP_PERMITMATCH;
|
route_map_result_t ret = RMAP_PERMITMATCH;
|
||||||
@ -1193,14 +1239,14 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
case NEXTHOP_TYPE_IPV4:
|
case NEXTHOP_TYPE_IPV4:
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
family = AFI_IP;
|
family = AFI_IP;
|
||||||
if (nexthop_active(AFI_IP, re, nexthop, rn, resolved_id))
|
if (nexthop_active(AFI_IP, re, nexthop, rn, resolved_nhe))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_IPV6:
|
case NEXTHOP_TYPE_IPV6:
|
||||||
family = AFI_IP6;
|
family = AFI_IP6;
|
||||||
if (nexthop_active(AFI_IP6, re, nexthop, rn, resolved_id))
|
if (nexthop_active(AFI_IP6, re, nexthop, rn, resolved_nhe))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -1218,7 +1264,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
} else {
|
} else {
|
||||||
if (nexthop_active(AFI_IP6, re, nexthop, rn,
|
if (nexthop_active(AFI_IP6, re, nexthop, rn,
|
||||||
resolved_id))
|
resolved_nhe))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -1298,6 +1344,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
unsigned int prev_active, new_active;
|
unsigned int prev_active, new_active;
|
||||||
ifindex_t prev_index;
|
ifindex_t prev_index;
|
||||||
uint8_t curr_active = 0;
|
uint8_t curr_active = 0;
|
||||||
|
bool new_resolve = false;
|
||||||
|
|
||||||
afi_t rt_afi = family2afi(rn->p.family);
|
afi_t rt_afi = family2afi(rn->p.family);
|
||||||
|
|
||||||
@ -1308,7 +1355,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
|
|
||||||
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
|
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
|
||||||
struct nhg_hash_entry *nhe = NULL;
|
struct nhg_hash_entry *nhe = NULL;
|
||||||
uint32_t resolved_id = 0;
|
struct nhg_hash_entry *resolved_nhe = NULL;
|
||||||
|
|
||||||
/* No protocol daemon provides src and so we're skipping
|
/* No protocol daemon provides src and so we're skipping
|
||||||
* tracking it */
|
* tracking it */
|
||||||
@ -1322,52 +1369,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
* decision point.
|
* decision point.
|
||||||
*/
|
*/
|
||||||
new_active =
|
new_active =
|
||||||
nexthop_active_check(rn, re, nexthop, &resolved_id);
|
nexthop_active_check(rn, re, nexthop, &resolved_nhe);
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the individual nexthop hash entries
|
|
||||||
* for the nexthops in the group
|
|
||||||
*/
|
|
||||||
|
|
||||||
nhe = depends_find(nexthop, rt_afi);
|
|
||||||
|
|
||||||
if (nhe && resolved_id) {
|
|
||||||
struct nhg_hash_entry *old_resolved = NULL;
|
|
||||||
struct nhg_hash_entry *new_resolved = NULL;
|
|
||||||
|
|
||||||
/* If this was already resolved, get its resolved nhe */
|
|
||||||
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE))
|
|
||||||
old_resolved = zebra_nhg_resolve(nhe);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We are going to do what is done in nexthop_active
|
|
||||||
* and clear whatever resolved nexthop may already be
|
|
||||||
* there.
|
|
||||||
*/
|
|
||||||
|
|
||||||
zebra_nhg_depends_release(nhe);
|
|
||||||
nhg_connected_head_free(&nhe->nhg_depends);
|
|
||||||
|
|
||||||
new_resolved = zebra_nhg_lookup_id(resolved_id);
|
|
||||||
|
|
||||||
if (new_resolved) {
|
|
||||||
/* Add new resolved */
|
|
||||||
zebra_nhg_depends_add(nhe, new_resolved);
|
|
||||||
zebra_nhg_dependents_add(new_resolved, nhe);
|
|
||||||
|
|
||||||
if (old_resolved && new_resolved->id != old_resolved->id) {
|
|
||||||
new_resolved->refcnt+=nhe->refcnt;
|
|
||||||
old_resolved->refcnt-=nhe->refcnt;
|
|
||||||
} else if (!old_resolved)
|
|
||||||
zebra_nhg_increment_ref(new_resolved);
|
|
||||||
|
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE);
|
|
||||||
} else
|
|
||||||
flog_err(
|
|
||||||
EC_ZEBRA_TABLE_LOOKUP_FAILED,
|
|
||||||
"Zebra failed to lookup a resolved nexthop hash entry id=%u",
|
|
||||||
resolved_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_active
|
if (new_active
|
||||||
&& nexthop_group_active_nexthop_num(&new_grp)
|
&& nexthop_group_active_nexthop_num(&new_grp)
|
||||||
@ -1376,15 +1378,9 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
new_active = 0;
|
new_active = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nhe && new_active) {
|
if (new_active)
|
||||||
curr_active++;
|
curr_active++;
|
||||||
|
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
|
||||||
if (!nhe->is_kernel_nh
|
|
||||||
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE))
|
|
||||||
zebra_nhg_install_kernel(nhe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't allow src setting on IPv6 addr for now */
|
/* Don't allow src setting on IPv6 addr for now */
|
||||||
if (prev_active != new_active || prev_index != nexthop->ifindex
|
if (prev_active != new_active || prev_index != nexthop->ifindex
|
||||||
|| ((nexthop->type >= NEXTHOP_TYPE_IFINDEX
|
|| ((nexthop->type >= NEXTHOP_TYPE_IFINDEX
|
||||||
@ -1395,11 +1391,26 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
|
|||||||
&& nexthop->type < NEXTHOP_TYPE_BLACKHOLE)
|
&& nexthop->type < NEXTHOP_TYPE_BLACKHOLE)
|
||||||
&& !(IPV6_ADDR_SAME(&prev_src.ipv6,
|
&& !(IPV6_ADDR_SAME(&prev_src.ipv6,
|
||||||
&nexthop->rmap_src.ipv6)))
|
&nexthop->rmap_src.ipv6)))
|
||||||
|| CHECK_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED))
|
|| CHECK_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED)) {
|
||||||
SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
|
SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the individual nexthop hash entries
|
||||||
|
* for the nexthops in the group
|
||||||
|
*/
|
||||||
|
|
||||||
|
nhe = depends_find(nexthop, rt_afi);
|
||||||
|
|
||||||
|
if (resolved_nhe)
|
||||||
|
new_resolve = zebra_nhg_set_resolved(
|
||||||
|
nhe, resolved_nhe);
|
||||||
|
|
||||||
|
if (nhe && new_active)
|
||||||
|
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED)) {
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) || new_resolve) {
|
||||||
struct nhg_hash_entry *new_nhe = NULL;
|
struct nhg_hash_entry *new_nhe = NULL;
|
||||||
// TODO: Add proto type here
|
// TODO: Add proto type here
|
||||||
|
|
||||||
@ -1477,8 +1488,8 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe)
|
|||||||
if (!depend) {
|
if (!depend) {
|
||||||
flog_err(
|
flog_err(
|
||||||
EC_ZEBRA_NHG_FIB_UPDATE,
|
EC_ZEBRA_NHG_FIB_UPDATE,
|
||||||
"Failed to recursively resolve Nexthop Hash Entry id=%u in the group id=%u",
|
"Failed to recursively resolve Nexthop Hash Entry in the group id=%u",
|
||||||
depend->id, nhe->id);
|
nhe->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user