3030#include "printfrr.h"
3131#include "frrscript.h"
3232#include "frrdistance.h"
33+ #include "lib/termtable.h"
3334
3435#include "zebra/zebra_router.h"
3536#include "zebra/connected.h"
@@ -273,6 +274,63 @@ static const char *subqueue2str(enum meta_queue_indexes index)
273274 return "Unknown" ;
274275}
275276
277+ /* Handler for 'show zebra metaq' */
278+ int zebra_show_metaq_counter (struct vty * vty , bool uj )
279+ {
280+ struct meta_queue * mq = zrouter .mq ;
281+ struct ttable * tt = NULL ;
282+ char * table = NULL ;
283+ json_object * json = NULL ;
284+ json_object * json_table = NULL ;
285+
286+ if (!mq )
287+ return CMD_WARNING ;
288+
289+ /* Create a table for subqueue details */
290+ tt = ttable_new (& ttable_styles [TTSTYLE_ASCII ]);
291+ ttable_add_row (tt , "SubQ|Current|Max Size|Total" );
292+
293+ /* Add rows for each subqueue */
294+ for (uint8_t i = 0 ; i < MQ_SIZE ; i ++ ) {
295+ ttable_add_row (tt , "%s|%u|%u|%u" , subqueue2str (i ), mq -> subq [i ]-> count ,
296+ mq -> max_subq [i ], mq -> total_subq [i ]);
297+ }
298+
299+ /* For a better formatting between the content and separator */
300+ tt -> style .cell .rpad = 2 ;
301+ tt -> style .cell .lpad = 1 ;
302+ ttable_restyle (tt );
303+
304+ if (uj ) {
305+ json = json_object_new_object ();
306+ /* Add MetaQ summary to the JSON object */
307+ json_object_int_add (json , "currentSize" , mq -> size );
308+ json_object_int_add (json , "maxSize" , mq -> max_metaq );
309+ json_object_int_add (json , "total" , mq -> total_metaq );
310+
311+ /* Convert the table to JSON and add it to the main JSON object */
312+ /* n = name/string, u = unsigned int */
313+ json_table = ttable_json (tt , "sddd" );
314+ json_object_object_add (json , "subqueues" , json_table );
315+ vty_json (vty , json );
316+ } else {
317+ vty_out (vty , "MetaQ Summary\n" );
318+ vty_out (vty , "Current Size\t: %u\n" , mq -> size );
319+ vty_out (vty , "Max Size\t: %u\n" , mq -> max_metaq );
320+ vty_out (vty , "Total\t\t: %u\n" , mq -> total_metaq );
321+
322+ /* Dump the table */
323+ table = ttable_dump (tt , "\n" );
324+ vty_out (vty , "%s\n" , table );
325+ XFREE (MTYPE_TMP_TTABLE , table );
326+ }
327+
328+ /* Clean up the table */
329+ ttable_del (tt );
330+
331+ return CMD_SUCCESS ;
332+ }
333+
276334printfrr_ext_autoreg_p ("ZN" , printfrr_zebra_node );
277335static ssize_t printfrr_zebra_node (struct fbuf * buf , struct printfrr_eargs * ea ,
278336 const void * ptr )
@@ -3257,6 +3315,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
32573315 struct route_node * rn = NULL ;
32583316 struct route_entry * re = NULL , * curr_re = NULL ;
32593317 uint8_t qindex = MQ_SIZE , curr_qindex = MQ_SIZE ;
3318+ uint64_t curr , high ;
32603319
32613320 rn = (struct route_node * )data ;
32623321
@@ -3300,6 +3359,15 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
33003359 listnode_add (mq -> subq [qindex ], rn );
33013360 route_lock_node (rn );
33023361 mq -> size ++ ;
3362+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
3363+ atomic_fetch_add_explicit (& mq -> total_subq [qindex ], 1 , memory_order_relaxed );
3364+ curr = listcount (mq -> subq [qindex ]);
3365+ high = atomic_load_explicit (& mq -> max_subq [qindex ], memory_order_relaxed );
3366+ if (curr > high )
3367+ atomic_store_explicit (& mq -> max_subq [qindex ], curr , memory_order_relaxed );
3368+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
3369+ if (mq -> size > high )
3370+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
33033371
33043372 if (IS_ZEBRA_DEBUG_RIB_DETAILED )
33053373 rnode_debug (rn , re -> vrf_id , "queued rn %p into sub-queue %s" ,
@@ -3310,8 +3378,21 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
33103378
33113379static int early_label_meta_queue_add (struct meta_queue * mq , void * data )
33123380{
3381+ uint64_t curr , high ;
3382+
33133383 listnode_add (mq -> subq [META_QUEUE_EARLY_LABEL ], data );
33143384 mq -> size ++ ;
3385+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
3386+ atomic_fetch_add_explicit (& mq -> total_subq [META_QUEUE_EARLY_LABEL ], 1 , memory_order_relaxed );
3387+ curr = listcount (mq -> subq [META_QUEUE_EARLY_LABEL ]);
3388+ high = atomic_load_explicit (& mq -> max_subq [META_QUEUE_EARLY_LABEL ], memory_order_relaxed );
3389+ if (curr > high )
3390+ atomic_store_explicit (& mq -> max_subq [META_QUEUE_EARLY_LABEL ], curr ,
3391+ memory_order_relaxed );
3392+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
3393+ if (mq -> size > high )
3394+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
3395+
33153396 return 0 ;
33163397}
33173398
@@ -3320,6 +3401,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
33203401 struct nhg_ctx * ctx = NULL ;
33213402 uint8_t qindex = META_QUEUE_NHG ;
33223403 struct wq_nhg_wrapper * w ;
3404+ uint64_t curr , high ;
33233405
33243406 ctx = (struct nhg_ctx * )data ;
33253407
@@ -3333,6 +3415,15 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
33333415
33343416 listnode_add (mq -> subq [qindex ], w );
33353417 mq -> size ++ ;
3418+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
3419+ atomic_fetch_add_explicit (& mq -> total_subq [qindex ], 1 , memory_order_relaxed );
3420+ curr = listcount (mq -> subq [qindex ]);
3421+ high = atomic_load_explicit (& mq -> max_subq [qindex ], memory_order_relaxed );
3422+ if (curr > high )
3423+ atomic_store_explicit (& mq -> max_subq [qindex ], curr , memory_order_relaxed );
3424+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
3425+ if (mq -> size > high )
3426+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
33363427
33373428 if (IS_ZEBRA_DEBUG_RIB_DETAILED )
33383429 zlog_debug ("NHG Context id=%u queued into sub-queue %s" ,
@@ -3347,6 +3438,7 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
33473438 struct nhg_hash_entry * nhe = NULL ;
33483439 uint8_t qindex = META_QUEUE_NHG ;
33493440 struct wq_nhg_wrapper * w ;
3441+ uint64_t curr , high ;
33503442
33513443 nhe = (struct nhg_hash_entry * )data ;
33523444
@@ -3361,6 +3453,15 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
33613453
33623454 listnode_add (mq -> subq [qindex ], w );
33633455 mq -> size ++ ;
3456+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
3457+ atomic_fetch_add_explicit (& mq -> total_subq [qindex ], 1 , memory_order_relaxed );
3458+ curr = listcount (mq -> subq [qindex ]);
3459+ high = atomic_load_explicit (& mq -> max_subq [qindex ], memory_order_relaxed );
3460+ if (curr > high )
3461+ atomic_store_explicit (& mq -> max_subq [qindex ], curr , memory_order_relaxed );
3462+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
3463+ if (mq -> size > high )
3464+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
33643465
33653466 if (IS_ZEBRA_DEBUG_RIB_DETAILED )
33663467 zlog_debug ("NHG id=%u queued into sub-queue %s" , nhe -> id ,
@@ -3381,8 +3482,19 @@ static int rib_meta_queue_nhg_del(struct meta_queue *mq, void *data)
33813482
33823483static int rib_meta_queue_evpn_add (struct meta_queue * mq , void * data )
33833484{
3485+ uint64_t curr , high ;
3486+
33843487 listnode_add (mq -> subq [META_QUEUE_EVPN ], data );
33853488 mq -> size ++ ;
3489+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
3490+ atomic_fetch_add_explicit (& mq -> total_subq [META_QUEUE_EVPN ], 1 , memory_order_relaxed );
3491+ curr = listcount (mq -> subq [META_QUEUE_EVPN ]);
3492+ high = atomic_load_explicit (& mq -> max_subq [META_QUEUE_EVPN ], memory_order_relaxed );
3493+ if (curr > high )
3494+ atomic_store_explicit (& mq -> max_subq [META_QUEUE_EVPN ], curr , memory_order_relaxed );
3495+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
3496+ if (mq -> size > high )
3497+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
33863498
33873499 return 0 ;
33883500}
@@ -4222,8 +4334,19 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
42224334
42234335static int rib_meta_queue_gr_run_add (struct meta_queue * mq , void * data )
42244336{
4337+ uint64_t curr , high ;
4338+
42254339 listnode_add (mq -> subq [META_QUEUE_GR_RUN ], data );
42264340 mq -> size ++ ;
4341+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
4342+ atomic_fetch_add_explicit (& mq -> total_subq [META_QUEUE_GR_RUN ], 1 , memory_order_relaxed );
4343+ curr = listcount (mq -> subq [META_QUEUE_GR_RUN ]);
4344+ high = atomic_load_explicit (& mq -> max_subq [META_QUEUE_GR_RUN ], memory_order_relaxed );
4345+ if (curr > high )
4346+ atomic_store_explicit (& mq -> max_subq [META_QUEUE_GR_RUN ], curr , memory_order_relaxed );
4347+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
4348+ if (mq -> size > high )
4349+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
42274350
42284351 if (IS_ZEBRA_DEBUG_RIB_DETAILED )
42294352 zlog_debug ("Graceful Run adding" );
@@ -4234,9 +4357,20 @@ static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
42344357static int rib_meta_queue_early_route_add (struct meta_queue * mq , void * data )
42354358{
42364359 struct zebra_early_route * ere = data ;
4360+ uint64_t curr , high ;
42374361
42384362 listnode_add (mq -> subq [META_QUEUE_EARLY_ROUTE ], data );
42394363 mq -> size ++ ;
4364+ atomic_fetch_add_explicit (& mq -> total_metaq , 1 , memory_order_relaxed );
4365+ atomic_fetch_add_explicit (& mq -> total_subq [META_QUEUE_EARLY_ROUTE ], 1 , memory_order_relaxed );
4366+ curr = listcount (mq -> subq [META_QUEUE_EARLY_ROUTE ]);
4367+ high = atomic_load_explicit (& mq -> max_subq [META_QUEUE_EARLY_ROUTE ], memory_order_relaxed );
4368+ if (curr > high )
4369+ atomic_store_explicit (& mq -> max_subq [META_QUEUE_EARLY_ROUTE ], curr ,
4370+ memory_order_relaxed );
4371+ high = atomic_load_explicit (& mq -> max_metaq , memory_order_relaxed );
4372+ if (mq -> size > high )
4373+ atomic_store_explicit (& mq -> max_metaq , mq -> size , memory_order_relaxed );
42404374
42414375 if (IS_ZEBRA_DEBUG_RIB_DETAILED ) {
42424376 struct vrf * vrf = vrf_lookup_by_id (ere -> re -> vrf_id );
0 commit comments