Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nhg stuffs #15332

Merged
merged 10 commits into from
Feb 14, 2024
64 changes: 10 additions & 54 deletions zebra/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,6 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate,
route_node_destroy(delegate, table, node);
}

static void zebra_if_nhg_dependents_free(struct zebra_if *zebra_if)
{
nhg_connected_tree_free(&zebra_if->nhg_dependents);
}

static void zebra_if_nhg_dependents_init(struct zebra_if *zebra_if)
{
nhg_connected_tree_init(&zebra_if->nhg_dependents);
}


route_table_delegate_t zebra_if_table_delegate = {
.create_node = route_node_create,
.destroy_node = zebra_if_node_destroy};
Expand All @@ -137,7 +126,7 @@ static int if_zebra_new_hook(struct interface *ifp)

zebra_if->link_nsid = NS_UNKNOWN;

zebra_if_nhg_dependents_init(zebra_if);
nhg_connected_tree_init(&zebra_if->nhg_dependents);

zebra_ptm_if_init(zebra_if);

Expand Down Expand Up @@ -221,7 +210,7 @@ static int if_zebra_delete_hook(struct interface *ifp)
zebra_evpn_mac_ifp_del(ifp);

if_nhg_dependents_release(ifp);
zebra_if_nhg_dependents_free(zebra_if);
nhg_connected_tree_free(&zebra_if->nhg_dependents);

XFREE(MTYPE_ZIF_DESC, zebra_if->desc);

Expand Down Expand Up @@ -954,47 +943,6 @@ static void if_down_del_nbr_connected(struct interface *ifp)
}
}

void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe)
{
if (ifp->info) {
struct zebra_if *zif = (struct zebra_if *)ifp->info;

nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
}
}

void if_nhg_dependents_del(struct interface *ifp, struct nhg_hash_entry *nhe)
{
if (ifp->info) {
struct zebra_if *zif = (struct zebra_if *)ifp->info;

nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
}
}

unsigned int if_nhg_dependents_count(const struct interface *ifp)
{
if (ifp->info) {
struct zebra_if *zif = (struct zebra_if *)ifp->info;

return nhg_connected_tree_count(&zif->nhg_dependents);
}

return 0;
}


bool if_nhg_dependents_is_empty(const struct interface *ifp)
{
if (ifp->info) {
struct zebra_if *zif = (struct zebra_if *)ifp->info;

return nhg_connected_tree_is_empty(&zif->nhg_dependents);
}

return false;
}

/* Interface is up. */
void if_up(struct interface *ifp, bool install_connected)
{
Expand Down Expand Up @@ -1022,6 +970,14 @@ void if_up(struct interface *ifp, bool install_connected)
if (install_connected)
if_install_connected(ifp);

/*
* Interface associated NHG's have been deleted on
* interface down events, now that this interface
* is coming back up, let's resync the zebra -> dplane
* nhg's so that they can be continued to be used.
*/
zebra_interface_nhg_reinstall(ifp);

/* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
* are checked to see if (remote) neighbor entries need to be installed
* on them for ARP suppression.
Expand Down
5 changes: 0 additions & 5 deletions zebra/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,6 @@ void link_param_cmd_set_float(struct interface *ifp, float *field,
void link_param_cmd_unset(struct interface *ifp, uint32_t type);

/* Nexthop group connected functions */
extern void if_nhg_dependents_add(struct interface *ifp,
struct nhg_hash_entry *nhe);
extern void if_nhg_dependents_del(struct interface *ifp,
struct nhg_hash_entry *nhe);
extern unsigned int if_nhg_dependents_count(const struct interface *ifp);
extern bool if_nhg_dependents_is_empty(const struct interface *ifp);

extern void vrf_add_update(struct vrf *vrfp);
Expand Down
4 changes: 0 additions & 4 deletions zebra/redistribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,10 +605,6 @@ void zebra_interface_address_add_update(struct interface *ifp,
client, ifp, ifc);
}
}
/* interface associated NHGs may have been deleted,
* re-sync zebra -> dplane NHGs
*/
zebra_interface_nhg_reinstall(ifp);
}

/* Interface address deletion. */
Expand Down
88 changes: 47 additions & 41 deletions zebra/zebra_nhg.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,10 @@ static int zebra_nhg_insert_id(struct nhg_hash_entry *nhe)

static void zebra_nhg_set_if(struct nhg_hash_entry *nhe, struct interface *ifp)
{
struct zebra_if *zif = (struct zebra_if *)ifp->info;

nhe->ifp = ifp;
if_nhg_dependents_add(ifp, nhe);
nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
}

static void
Expand Down Expand Up @@ -1031,31 +1033,25 @@ static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh,
return ctx;
}

static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe)
{
struct nhg_connected *rb_node_dep;

SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);

frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep)
zebra_nhg_set_valid(rb_node_dep->nhe);
}

static void zebra_nhg_set_invalid(struct nhg_hash_entry *nhe)
static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
{
struct nhg_connected *rb_node_dep;

UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
if (valid)
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
else {
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);

/* If we're in shutdown, this interface event needs to clean
* up installed NHGs, so don't clear that flag directly.
*/
if (!zebra_router_in_shutdown())
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
/* If we're in shutdown, this interface event needs to clean
* up installed NHGs, so don't clear that flag directly.
*/
if (!zebra_router_in_shutdown())
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
}

/* Update validity of nexthops depending on it */
frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep)
zebra_nhg_check_valid(rb_node_dep->nhe);
zebra_nhg_set_valid(rb_node_dep->nhe, valid);
}

void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
Expand All @@ -1071,19 +1067,19 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe)
}
}

if (valid)
zebra_nhg_set_valid(nhe);
else
zebra_nhg_set_invalid(nhe);
zebra_nhg_set_valid(nhe, valid);
}

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);
if (nhe->ifp) {
struct zebra_if *zif = nhe->ifp->info;

nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
}
}

static void zebra_nhg_release(struct nhg_hash_entry *nhe)
Expand Down Expand Up @@ -1115,7 +1111,7 @@ static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install)
struct nhg_connected *rb_node_dep;

frr_each_safe (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
zebra_nhg_set_valid(rb_node_dep->nhe);
zebra_nhg_set_valid(rb_node_dep->nhe, true);
/* install dependent NHG into kernel */
if (install) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
Expand Down Expand Up @@ -3094,14 +3090,15 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
zebra_nhg_install_kernel(rb_node_dep->nhe);
}

if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID) &&
(!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED) ||
CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL)) &&
!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED)) {
/* Change its type to us since we are installing it */
if (!ZEBRA_NHG_CREATED(nhe))
nhe->type = ZEBRA_ROUTE_NHG;

int ret = dplane_nexthop_add(nhe);
enum zebra_dplane_result ret = dplane_nexthop_add(nhe);

switch (ret) {
case ZEBRA_DPLANE_REQUEST_QUEUED:
Expand All @@ -3114,8 +3111,9 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
nhe);
break;
case ZEBRA_DPLANE_REQUEST_SUCCESS:
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
zebra_nhg_handle_install(nhe, false);
flog_err(EC_ZEBRA_DP_INVALID_RC,
"DPlane returned an invalid result code for attempt of installation of %pNG into the kernel",
nhe);
break;
}
}
Expand Down Expand Up @@ -3182,8 +3180,9 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
}

UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED);
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL);
switch (status) {
case ZEBRA_DPLANE_REQUEST_SUCCESS:
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
zebra_nhg_handle_install(nhe, true);

Expand All @@ -3192,7 +3191,9 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
zsend_nhg_notify(nhe->type, nhe->zapi_instance,
nhe->zapi_session, nhe->id,
ZAPI_NHG_INSTALLED);
} else {
break;
case ZEBRA_DPLANE_REQUEST_FAILURE:
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
/* If daemon nhg, send it an update */
if (PROTO_OWNED(nhe))
zsend_nhg_notify(nhe->type, nhe->zapi_instance,
Expand All @@ -3205,6 +3206,12 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
EC_ZEBRA_DP_INSTALL_FAIL,
"Failed to install Nexthop (%pNG) into the kernel",
nhe);
break;
case ZEBRA_DPLANE_REQUEST_QUEUED:
flog_err(EC_ZEBRA_DP_INVALID_RC,
"Dplane returned an invalid result code for a result from the dplane for %pNG into the kernel",
nhe);
break;
}
}
}
Expand Down Expand Up @@ -3681,12 +3688,11 @@ void zebra_interface_nhg_reinstall(struct interface *ifp)
&rb_node_dep->nhe->nhg_dependents,
rb_node_dependent) {
if (IS_ZEBRA_DEBUG_NHG)
zlog_debug(
"%s dependent nhe %pNG unset installed flag",
__func__,
rb_node_dependent->nhe);
UNSET_FLAG(rb_node_dependent->nhe->flags,
NEXTHOP_GROUP_INSTALLED);
zlog_debug("%s dependent nhe %pNG Setting Reinstall flag",
__func__,
rb_node_dependent->nhe);
SET_FLAG(rb_node_dependent->nhe->flags,
NEXTHOP_GROUP_REINSTALL);
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion zebra/zebra_nhg.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct nhg_hash_entry {
* nhg(1)->nhg_dependents is 3 in the tree
*
* nhg(2)->nhg_depends is empty
* nhg(3)->nhg_dependents is 3 in the tree
* nhg(2)->nhg_dependents is 3 in the tree
*/
struct nhg_connected_tree_head nhg_depends, nhg_dependents;

Expand Down Expand Up @@ -144,6 +144,14 @@ struct nhg_hash_entry {
* Track FPM installation status..
*/
#define NEXTHOP_GROUP_FPM (1 << 7)

/*
* When an interface comes up install the
* singleton's and schedule the NHG's that
* are using this nhg to be reinstalled
* when installation is successful.
*/
#define NEXTHOP_GROUP_REINSTALL (1 << 8)
};

/* Upper 4 bits of the NHG are reserved for indicating the NHG type */
Expand Down
22 changes: 14 additions & 8 deletions zebra/zebra_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,12 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
json_object_boolean_true_add(json, "valid");
else
vty_out(vty, " Valid");

if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL)) {
if (json)
json_object_boolean_true_add(json, "reInstall");
else
vty_out(vty, ", Reinstall");
}
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)) {
if (json)
json_object_boolean_true_add(json, "installed");
Expand Down Expand Up @@ -1476,17 +1481,18 @@ static void if_nexthop_group_dump_vty(struct vty *vty, struct interface *ifp)
{
struct zebra_if *zebra_if = NULL;
struct nhg_connected *rb_node_dep = NULL;
bool first = true;

zebra_if = ifp->info;

if (!if_nhg_dependents_is_empty(ifp)) {
vty_out(vty, "Interface %s:\n", ifp->name);

frr_each(nhg_connected_tree, &zebra_if->nhg_dependents,
rb_node_dep) {
vty_out(vty, " ");
show_nexthop_group_out(vty, rb_node_dep->nhe, NULL);
frr_each (nhg_connected_tree, &zebra_if->nhg_dependents, rb_node_dep) {
if (first) {
vty_out(vty, "Interface %s:\n", ifp->name);
first = false;
}

vty_out(vty, " ");
show_nexthop_group_out(vty, rb_node_dep->nhe, NULL);
}
}

Expand Down
Loading