mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 13:58:24 +00:00
zebra: implement NHG proto replace
Implement the ability to replace an NHG sent down from an upper level proto. With proto-owned NHGs, we make the assumption they are ecmp and always treat them as a group to make the replace from 1 -> 2 and 2 -> 1 quite a bit easier. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
parent
08da8bbc22
commit
dd1e105fe3
@ -730,7 +730,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
|
|||||||
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE))
|
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE))
|
||||||
SET_FLAG(newnhe->flags, NEXTHOP_GROUP_VALID);
|
SET_FLAG(newnhe->flags, NEXTHOP_GROUP_VALID);
|
||||||
|
|
||||||
if (nh->next == NULL) {
|
if (nh->next == NULL && newnhe->id < zclient_get_nhg_lower_bound()) {
|
||||||
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) {
|
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) {
|
||||||
/* Single recursive nexthop */
|
/* Single recursive nexthop */
|
||||||
handle_recursive_depend(&newnhe->nhg_depends,
|
handle_recursive_depend(&newnhe->nhg_depends,
|
||||||
@ -739,6 +739,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
|
|||||||
recursive = true;
|
recursive = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* Proto-owned are groups by default */
|
||||||
/* List of nexthops */
|
/* List of nexthops */
|
||||||
for (nh = newnhe->nhg.nexthop; nh; nh = nh->next) {
|
for (nh = newnhe->nhg.nexthop; nh; nh = nh->next) {
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
@ -1024,17 +1025,21 @@ done:
|
|||||||
zebra_nhg_set_invalid(nhe);
|
zebra_nhg_set_invalid(nhe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void zebra_nhg_release_all_deps(struct nhg_hash_entry *nhe)
|
||||||
|
{
|
||||||
|
/* Remove it from any lists it may be on */
|
||||||
|
zebra_nhg_depends_release(nhe);
|
||||||
|
zebra_nhg_dependents_release(nhe);
|
||||||
|
if (nhe->ifp)
|
||||||
|
if_nhg_dependents_del(nhe->ifp, nhe);
|
||||||
|
}
|
||||||
|
|
||||||
static void zebra_nhg_release(struct nhg_hash_entry *nhe)
|
static void zebra_nhg_release(struct nhg_hash_entry *nhe)
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
zlog_debug("%s: nhe %p (%u)", __func__, nhe, nhe->id);
|
zlog_debug("%s: nhe %p (%u)", __func__, nhe, nhe->id);
|
||||||
|
|
||||||
/* Remove it from any lists it may be on */
|
zebra_nhg_release_all_deps(nhe);
|
||||||
zebra_nhg_depends_release(nhe);
|
|
||||||
zebra_nhg_dependents_release(nhe);
|
|
||||||
if (nhe->ifp)
|
|
||||||
if_nhg_dependents_del(nhe->ifp, nhe);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If its not zebra owned, we didn't store it here and have to be
|
* If its not zebra owned, we didn't store it here and have to be
|
||||||
@ -2500,7 +2505,8 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
|
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
|
||||||
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
|
&& (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
|
||||||
|
|| nhe->id >= zclient_get_nhg_lower_bound())
|
||||||
&& !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 */
|
||||||
if (!ZEBRA_NHG_CREATED(nhe))
|
if (!ZEBRA_NHG_CREATED(nhe))
|
||||||
@ -2685,7 +2691,7 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
|
|||||||
struct nexthop_group *nhg, afi_t afi)
|
struct nexthop_group *nhg, afi_t afi)
|
||||||
{
|
{
|
||||||
struct nhg_hash_entry lookup;
|
struct nhg_hash_entry lookup;
|
||||||
struct nhg_hash_entry *new;
|
struct nhg_hash_entry *new, *old;
|
||||||
struct nhg_connected *rb_node_dep = NULL;
|
struct nhg_connected *rb_node_dep = NULL;
|
||||||
|
|
||||||
zebra_nhe_init(&lookup, afi, nhg->nexthop);
|
zebra_nhe_init(&lookup, afi, nhg->nexthop);
|
||||||
@ -2693,8 +2699,23 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
|
|||||||
lookup.id = id;
|
lookup.id = id;
|
||||||
lookup.type = type;
|
lookup.type = type;
|
||||||
|
|
||||||
|
old = zebra_nhg_lookup_id(id);
|
||||||
|
|
||||||
|
if (old) {
|
||||||
|
/*
|
||||||
|
* This is a replace, just release NHE from ID for now, The
|
||||||
|
* depends/dependents may still be used in the replacement.
|
||||||
|
*/
|
||||||
|
hash_release(zrouter.nhgs_id, old);
|
||||||
|
}
|
||||||
|
|
||||||
new = zebra_nhg_rib_find_nhe(&lookup, afi);
|
new = zebra_nhg_rib_find_nhe(&lookup, afi);
|
||||||
|
|
||||||
|
if (old) {
|
||||||
|
/* Now release depends/dependents in old one */
|
||||||
|
zebra_nhg_release_all_deps(old);
|
||||||
|
}
|
||||||
|
|
||||||
if (!new)
|
if (!new)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -2707,9 +2728,9 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
zlog_debug("%s: added nhe %p (%u), vrf %d, type %s", __func__,
|
zlog_debug("%s: %s nhe %p (%u), vrf %d, type %s", __func__,
|
||||||
new, new->id, new->vrf_id,
|
(old ? "replaced" : "added"), new, new->id,
|
||||||
zebra_route_string(new->type));
|
new->vrf_id, zebra_route_string(new->type));
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user