diff options
| -rw-r--r-- | zebra/interface.c | 64 | ||||
| -rw-r--r-- | zebra/interface.h | 5 | ||||
| -rw-r--r-- | zebra/redistribute.c | 4 | ||||
| -rw-r--r-- | zebra/zebra_nhg.c | 88 | ||||
| -rw-r--r-- | zebra/zebra_nhg.h | 10 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 22 |
6 files changed, 80 insertions, 113 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 6624eb2591..8111863558 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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}; @@ -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); @@ -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); @@ -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) { @@ -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. diff --git a/zebra/interface.h b/zebra/interface.h index 7d633f32d2..8d19c1838f 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -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); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 70ace35a86..11c1330398 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -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. */ diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index dc403b8111..934b8ba0db 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -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 @@ -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) @@ -1071,10 +1067,7 @@ 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) @@ -1082,8 +1075,11 @@ 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) @@ -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) @@ -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: @@ -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; } } @@ -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); @@ -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, @@ -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; } } } @@ -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); } } } diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 4eddecb73d..3bb697aa75 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -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; @@ -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 */ diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 70b71fe707..da6e2069ff 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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"); @@ -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); } } |
