From f99f1ff50a56c0402a30fd44c3e2451fa1bf6038 Mon Sep 17 00:00:00 2001 From: Sarita Patra Date: Sun, 13 Jun 2021 18:48:35 -0700 Subject: [PATCH] zebra: Fix for route node having no tracking NHT Topology: IXIA-----(ens192)FRR(ens224)------iXIA Configuration: 1. Create 8 sub-interfaces on ens192 under Default VRF and configure 8 EBGP session between FRR and IXIA. 2. Create 1000 sub-interfaces on ens224 under Default VRF and configure 1000 EBGP session between FRR and IXIA. 3. 2M prefixes distributed from Left side Ixia each with 8 ECMP path. 4. So in total, there are 2M prefixes * 8 ECMP = 16M prefixes entries in RIB and FIB. Issue: Shut ens192 and ens224, this is taking 1hr 15 mins to clean up the routes. Root Cause: In the case of route deletion, if the particular route node is having nht count = 0, we are going to the parent and doing nht evaluation, which is not needed. Fix: If the deleted the route node is having nht count > 0, then do a nht evaluation on the parent node. Shut ens192 and ens224, it is taking 1 min to clean up the routes with the fix. Signed-off-by: Sarita Patra --- zebra/rib.h | 3 ++- zebra/zebra_rib.c | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h index fa8193bedf..b7416322f9 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -490,7 +490,8 @@ extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter); extern uint8_t route_distance(int type); -extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq); +extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq, + bool rt_delete); /* * Inline functions. diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 625c966301..1279c7c9a9 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -698,7 +698,8 @@ static int rib_can_delete_dest(rib_dest_t *dest) return 1; } -void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) +void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq, + bool rt_delete) { rib_dest_t *dest = rib_dest_from_rnode(rn); struct rnh *rnh; @@ -719,6 +720,12 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) __func__, rn, dest ? rnh_list_count(&dest->nht) : 0); + if (rt_delete && (!dest || !rnh_list_count(&dest->nht))) { + if (IS_ZEBRA_DEBUG_NHT_DETAILED) + zlog_debug("%pRN has no tracking NHTs. Bailing", + rn); + break; + } if (!dest) { rn = rn->parent; if (rn) @@ -798,7 +805,8 @@ int rib_gc_dest(struct route_node *rn) rnode_debug(rn, zvrf_id(zvrf), "removing dest from table"); } - zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence()); + zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence(), + true); dest->rnode = NULL; rnh_list_fini(&dest->nht); @@ -1803,6 +1811,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) rib_dest_t *dest; bool fib_changed = false; struct rib_table_info *info; + bool rt_delete = false; zvrf = vrf_info_lookup(dplane_ctx_get_vrf(ctx)); vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); @@ -1990,6 +1999,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) } break; case DPLANE_OP_ROUTE_DELETE: + rt_delete = true; if (re) SET_FLAG(re->status, ROUTE_ENTRY_FAILED); /* @@ -2032,7 +2042,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) break; } - zebra_rib_evaluate_rn_nexthops(rn, seq); + zebra_rib_evaluate_rn_nexthops(rn, seq, rt_delete); zebra_rib_evaluate_mpls(rn); done: @@ -2268,8 +2278,8 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) } /* Make any changes visible for lsp and nexthop-tracking processing */ - zebra_rib_evaluate_rn_nexthops( - rn, zebra_router_get_next_sequence()); + zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence(), + false); zebra_rib_evaluate_mpls(rn); -- 2.39.5