Skip to content

Commit 8c6478d

Browse files
committed
zebra: clear route INSTALLED state on NHG reinstall triggers
When an NHG is reprogrammed to the kernel after events like quick interface flaps or kernel nexthop changes (ip nexthop del / flush), zebra clears NEXTHOP_GROUP_INSTALLED on the NHG but leaves ROUTE_ENTRY_INSTALLED set on the routes using it. rib_process then treats those routes as already installed and skips reprogramming them, leaving stale FIB state that no longer matches the freshly reinstalled NHG. Signed-off-by: Krishnasamy R <krishnasamyr@nvidia.com>
1 parent be464d5 commit 8c6478d

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

zebra/zebra_nhg.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,41 @@ static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh, struct nh_g
10731073
return ctx;
10741074
}
10751075

1076+
/* Unset all the re's INSTALLED flag which uses the nhe */
1077+
static void zebra_nhg_unset_installed_for_routes(struct nhg_hash_entry *nhe, const char *caller)
1078+
{
1079+
struct route_entry *re = NULL;
1080+
struct route_entry *re_dep = NULL;
1081+
struct nhg_connected *rb_node_dep = NULL;
1082+
1083+
frr_each (nhe_re_tree, &nhe->re_head, re) {
1084+
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1085+
if (IS_ZEBRA_DEBUG_NHG_DETAIL && re->rn)
1086+
zlog_debug("Caller %s: Unsetting INSTALLED flag for route %p (%pFX) using NHG %p (%pNG)",
1087+
caller, re, &re->rn->p, nhe, nhe);
1088+
1089+
UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
1090+
}
1091+
}
1092+
1093+
frr_each (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
1094+
/* Only unset INSTALLED flag if the dependent NHG is invalid */
1095+
if (!CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) {
1096+
frr_each (nhe_re_tree, &rb_node_dep->nhe->re_head, re_dep) {
1097+
if (CHECK_FLAG(re_dep->status, ROUTE_ENTRY_INSTALLED)) {
1098+
if (IS_ZEBRA_DEBUG_NHG_DETAIL && re_dep->rn)
1099+
zlog_debug("Caller %s: Unsetting INSTALLED flag for route %p (%pFX) using Dependent NHG %p (%pNG) of %p (%pNG)",
1100+
caller, re_dep, &re_dep->rn->p,
1101+
rb_node_dep->nhe, rb_node_dep->nhe, nhe,
1102+
nhe);
1103+
1104+
UNSET_FLAG(re_dep->status, ROUTE_ENTRY_INSTALLED);
1105+
}
1106+
}
1107+
}
1108+
}
1109+
}
1110+
10761111
static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
10771112
{
10781113
struct nhg_connected *rb_node_dep;
@@ -1086,8 +1121,11 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
10861121
/* If we're in shutdown, this interface event needs to clean
10871122
* up installed NHGs, so don't clear that flag directly.
10881123
*/
1089-
if (!zebra_router_in_shutdown())
1124+
if (!zebra_router_in_shutdown()) {
10901125
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
1126+
/* Handles route re-install for quick interface flaps */
1127+
zebra_nhg_unset_installed_for_routes(nhe, __func__);
1128+
}
10911129
}
10921130

10931131
/* Update validity of nexthops depending on it */
@@ -1715,6 +1753,9 @@ static void zebra_nhg_handle_kernel_state_change(struct nhg_hash_entry *nhe,
17151753
"Kernel %s a nexthop group with ID (%pNG) that we are still using for a route, sending it back down",
17161754
(is_delete ? "deleted" : "updated"), nhe);
17171755

1756+
/* Handles route re-install for ip nexthop del <id>/flush */
1757+
zebra_nhg_unset_installed_for_routes(nhe, __func__);
1758+
17181759
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
17191760
zebra_nhg_install_kernel(nhe, ZEBRA_ROUTE_MAX);
17201761
} else

0 commit comments

Comments
 (0)