summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Stapp <mstapp@nvidia.com>2021-10-05 15:32:23 -0400
committerMark Stapp <mstapp@nvidia.com>2021-11-23 11:23:26 -0500
commit002930f7bb68850dbff4e4d71b54ca7814f4cb86 (patch)
tree36a4c303ae2a33b31a00f16f7ae5190ab103022b
parent6e5532187f9e11d10f364fdac9f8e4efb16ff9be (diff)
zebra: add installed nexthop-group id value
In some cases, zebra may install a nexthop-group id that is different from the id of the nhe struct attached to a route-entry. This happens for a singleton recursive nexthop, for example, where a route is installed with the resolving nexthop's id. The installed value is the most useful value - that corresponds to information in the kernel on linux/netlink platforms that support nhgs. Display both values if they differ in ascii output, and include both values in the json form. Signed-off-by: Mark Stapp <mstapp@nvidia.com>
-rw-r--r--zebra/rib.h5
-rw-r--r--zebra/zebra_dplane.c2
-rw-r--r--zebra/zebra_rib.c23
-rw-r--r--zebra/zebra_vty.c13
4 files changed, 33 insertions, 10 deletions
diff --git a/zebra/rib.h b/zebra/rib.h
index 076608bb0f..fa8193bedf 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -108,8 +108,11 @@ struct route_entry {
struct nexthop_group fib_ng;
struct nexthop_group fib_backup_ng;
- /* Nexthop group hash entry ID */
+ /* Nexthop group hash entry IDs. The "installed" id is the id
+ * used in linux/netlink, if available.
+ */
uint32_t nhe_id;
+ uint32_t nhe_installed_id;
/* Tag */
route_tag_t tag;
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 4000272544..bf34fb54a9 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -2448,6 +2448,8 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
ret = ENOENT;
goto done;
}
+
+ re->nhe_installed_id = nhe->id;
}
#endif /* HAVE_NETLINK */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 3df70a3b56..625c966301 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -305,35 +305,41 @@ static void route_entry_attach_ref(struct route_entry *re,
{
re->nhe = new;
re->nhe_id = new->id;
+ re->nhe_installed_id = 0;
zebra_nhg_increment_ref(new);
}
+/* Replace (if 'new_nhghe') or clear (if that's NULL) an re's nhe. */
int route_entry_update_nhe(struct route_entry *re,
struct nhg_hash_entry *new_nhghe)
{
- struct nhg_hash_entry *old;
int ret = 0;
+ struct nhg_hash_entry *old_nhg = NULL;
if (new_nhghe == NULL) {
- if (re->nhe)
- zebra_nhg_decrement_ref(re->nhe);
+ old_nhg = re->nhe;
+
+ re->nhe_id = 0;
+ re->nhe_installed_id = 0;
re->nhe = NULL;
goto done;
}
if ((re->nhe_id != 0) && re->nhe && (re->nhe != new_nhghe)) {
- old = re->nhe;
+ /* Capture previous nhg, if any */
+ old_nhg = re->nhe;
route_entry_attach_ref(re, new_nhghe);
-
- if (old)
- zebra_nhg_decrement_ref(old);
} else if (!re->nhe)
/* This is the first time it's being attached */
route_entry_attach_ref(re, new_nhghe);
done:
+ /* Detach / deref previous nhg */
+ if (old_nhg)
+ zebra_nhg_decrement_ref(old_nhg);
+
return ret;
}
@@ -3093,7 +3099,8 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
if (re->nhe && re->nhe_id) {
assert(re->nhe->id == re->nhe_id);
- zebra_nhg_decrement_ref(re->nhe);
+
+ route_entry_update_nhe(re, NULL);
} else if (re->nhe && re->nhe->nhg.nexthop)
nexthops_free(re->nhe->nhg.nexthop);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index a3faa3d3e2..298697907b 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -540,8 +540,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
vty_out(vty, " Last update %s ago\n", buf);
- if (show_ng)
+ if (show_ng) {
vty_out(vty, " Nexthop Group ID: %u\n", re->nhe_id);
+ if (re->nhe_installed_id != 0
+ && re->nhe_id != re->nhe_installed_id)
+ vty_out(vty,
+ " Installed Nexthop Group ID: %u\n",
+ re->nhe_installed_id);
+ }
for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
/* Use helper to format each nexthop */
@@ -977,6 +983,11 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
&(re->nhe->nhg)));
json_object_int_add(json_route, "nexthopGroupId", re->nhe_id);
+ if (re->nhe_installed_id != 0)
+ json_object_int_add(json_route,
+ "installedNexthopGroupId",
+ re->nhe_installed_id);
+
json_object_string_add(json_route, "uptime", up_str);
for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {