Skip to content

Commit c66df2d

Browse files
BWAN-16636: On non-overlay route change, don't evaluate overlay rnh
1 parent 38f8a6c commit c66df2d

4 files changed

Lines changed: 89 additions & 0 deletions

File tree

zebra/rib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ struct rnh {
8484
#ifdef ZEBRA_INFIOT_CUSTOM_NEXTHOP_CHECK
8585
int dest_trkr_index;
8686
int nh_trkr_index;
87+
/* Epoch cache: stores the g_overlay_trkr_eval_seq value at which the
88+
* last SHM lookup was performed and its result, so that repeated calls
89+
* within the same route-change batch are free. This avoid liner lookup
90+
* into trkr_client_get_trkr_by_index case unsuccesful lookup*/
91+
uint32_t overlay_trkr_seq;
92+
uint8_t overlay_trkr_reachable;
8793
#endif
8894
struct rnh_list_item rnh_list_item;
8995
};

zebra/zebra_rib.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,30 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
838838
{
839839
rib_dest_t *dest = rib_dest_from_rnode(rn);
840840
struct rnh *rnh;
841+
#ifdef ZEBRA_INFIOT_CUSTOM_NEXTHOP_CHECK
842+
struct route_node *trigger_rn = rn;
843+
/* Determine whether this route change can affect overlay reachability.
844+
* Only the default route (which all unreachable overlay RNHs park on)
845+
* or a route within the overlay supernet (169.254.0.0/16) can change
846+
* overlay NHT state.
847+
*/
848+
const bool overlay_relevant =
849+
is_default_prefix(&rn->p)
850+
|| prefix_match(&g_infovlay_prefix, &rn->p);
851+
if (overlay_relevant) {
852+
g_overlay_trkr_eval_seq++;
853+
}
854+
855+
if (overlay_relevant && dest) {
856+
struct zebra_vrf *zvrf = rib_dest_vrf(dest);
857+
struct rib_table_info *info = srcdest_rnode_table_info(trigger_rn);
841858

859+
if (zvrf && info) {
860+
zebra_rnh_prescan_overlay_nht(
861+
zvrf, info->afi, 0, &trigger_rn->p, info->safi);
862+
}
863+
}
864+
#endif
842865
/*
843866
* We are storing the rnh's associated withb
844867
* the tracked nexthop as a list of the rn's.
@@ -904,6 +927,22 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
904927
}
905928

906929
rnh->seqno = seq;
930+
#ifdef ZEBRA_INFIOT_CUSTOM_NEXTHOP_CHECK
931+
/* Skip overlay RNH evaluations for non-overlay-relevant
932+
* route changes. All unreachable overlay RNHs park at
933+
* 0.0.0.0/0's nht list; the while(rn) walk always reaches
934+
* 0.0.0.0/0, so without this guard every route install
935+
* triggers full RNH evaluations. Overlay reachability is
936+
* independent of non-overlay routes so skipping is safe. */
937+
if (!overlay_relevant
938+
&& p->family == AF_INET
939+
&& prefix_match(&g_infovlay_prefix, p)) {
940+
if (IS_ZEBRA_DEBUG_NHT) {
941+
zlog_debug("skip overlay RNH %pFX non-overlay route change", p);
942+
}
943+
continue;
944+
}
945+
#endif
907946
zebra_evaluate_rnh(zvrf, family2afi(p->family), 0, p,
908947
rnh->safi);
909948
}

zebra/zebra_rnh.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ extern struct trkr_client *g_infovlay_trkr;
7373
int g_inf_nhcntr_read_success = 0;
7474
extern int g_inf_is_controller;
7575
extern struct list *g_inf_ctrl_overlay_ips;
76+
/* Epoch counter: incremented once per overlay/default route-change event in
77+
* zebra_rib_evaluate_rn_nexthops(). Per-RNH cache in check_overlay_nexthop()
78+
* uses this to skip redundant SHM lookups within the same batch. */
79+
uint32_t g_overlay_trkr_eval_seq = 1;
7680
#endif
7781

7882
static bool compare_state(struct route_entry *r1, struct route_entry *r2);
@@ -574,6 +578,17 @@ static int check_overlay_nexthop(struct prefix *pp, uint8_t *isreachable, struct
574578
}
575579
}
576580

581+
/* Epoch cache hit: result already computed for this route-change.
582+
* Return immediately without touching SHM. */
583+
if (rnh->overlay_trkr_seq == g_overlay_trkr_eval_seq) {
584+
*isreachable = rnh->overlay_trkr_reachable;
585+
if (IS_ZEBRA_DEBUG_NHT) {
586+
zlog_debug("Overlay cache HIT for %s: reachable=%d seq=%u",
587+
via, *isreachable, g_overlay_trkr_eval_seq);
588+
}
589+
return *isreachable;
590+
}
591+
577592
// It is possible that when zebra starts, click has not created the
578593
// SHM in which case the client initialization will fail in infnh_init.
579594
// retry here
@@ -618,6 +633,9 @@ static int check_overlay_nexthop(struct prefix *pp, uint8_t *isreachable, struct
618633
zlog_debug("Infiot via: %s, cntrname %s val %llu reachable %d nhindex %d destindex %d", via, cntrname,
619634
trkr == NULL ? 1 : trkr->val, *isreachable, rnh->nh_trkr_index, rnh->dest_trkr_index);
620635
}
636+
/* Store SHM result in per-RNH epoch cache for future hits this batch. */
637+
rnh->overlay_trkr_seq = g_overlay_trkr_eval_seq;
638+
rnh->overlay_trkr_reachable = *isreachable;
621639
return *isreachable;
622640
}
623641
#endif
@@ -961,6 +979,26 @@ static void zebra_rnh_evaluate_overlay_prefixes(struct zebra_vrf *zvrf, afi_t af
961979
zebra_rnh_evaluate_entry(zvrf, afi, force, nrn);
962980
}
963981
}
982+
983+
void zebra_rnh_prescan_overlay_nht(struct zebra_vrf *zvrf, afi_t afi,
984+
int force, const struct prefix *p,
985+
safi_t safi)
986+
{
987+
/* Guard against re-entrant invocation while pre-scan is in progress. */
988+
static bool overlay_prescan_active = false;
989+
990+
if (!overlay_prescan_active && p != NULL
991+
&& p->family == g_infovlay_prefix.family
992+
&& (prefix_match(&g_infovlay_prefix, p) ||
993+
prefix_match(&g_infovlay_prefix, p))) {
994+
overlay_prescan_active = true;
995+
if (IS_ZEBRA_DEBUG_NHT)
996+
zlog_debug("overlay pre-scan seq=%u skip_p=%pFX",
997+
g_overlay_trkr_eval_seq, p);
998+
zebra_rnh_evaluate_overlay_prefixes(zvrf, afi, force, p, safi);
999+
overlay_prescan_active = false;
1000+
}
1001+
}
9641002
#endif
9651003

9661004
/* Evaluate all tracked entries (nexthops or routes for import into BGP)

zebra/zebra_rnh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *);
4545
extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client);
4646
extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
4747
const struct prefix *p, safi_t safi);
48+
#ifdef ZEBRA_INFIOT_CUSTOM_NEXTHOP_CHECK
49+
extern void zebra_rnh_prescan_overlay_nht(struct zebra_vrf *zvrf, afi_t afi,
50+
int force, const struct prefix *p, safi_t safi);
51+
#endif
4852
extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi,
4953
struct vty *vty, const struct prefix *p,
5054
json_object *json);
@@ -66,6 +70,8 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re,
6670

6771
extern struct prefix g_infovlay_prefix;
6872
extern struct list *g_inf_ctrl_overlay_ips;
73+
/* Epoch counter shared with zebra_rib.c for per-RNH SHM result caching. */
74+
extern uint32_t g_overlay_trkr_eval_seq;
6975
#ifdef __cplusplus
7076
}
7177
#endif

0 commit comments

Comments
 (0)