@@ -73,6 +73,10 @@ extern struct trkr_client *g_infovlay_trkr;
7373int g_inf_nhcntr_read_success = 0 ;
7474extern int g_inf_is_controller ;
7575extern 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
7882static 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)
0 commit comments