summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/interface.c64
-rw-r--r--zebra/interface.h5
-rw-r--r--zebra/redistribute.c4
-rw-r--r--zebra/zebra_nhg.c88
-rw-r--r--zebra/zebra_nhg.h10
-rw-r--r--zebra/zebra_vty.c22
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);
}
}