@@ -8,6 +8,7 @@ static std::map<std::string, std::shared_ptr<FlexCounter>> g_flex_counters_map;
8
8
static std::set<sai_port_stat_t > supportedPortCounters;
9
9
static std::set<sai_queue_stat_t > supportedQueueCounters;
10
10
static std::set<sai_ingress_priority_group_stat_t > supportedPriorityGroupCounters;
11
+ static std::set<sai_router_interface_stat_t > supportedRifCounters;
11
12
12
13
FlexCounter::PortCounterIds::PortCounterIds (
13
14
_In_ sai_object_id_t port,
@@ -49,6 +50,14 @@ FlexCounter::IngressPriorityGroupCounterIds::IngressPriorityGroupCounterIds(
49
50
SWSS_LOG_ENTER ();
50
51
}
51
52
53
+ FlexCounter::RifCounterIds::RifCounterIds (
54
+ _In_ sai_object_id_t rif,
55
+ _In_ const std::vector<sai_router_interface_stat_t > &rifIds):
56
+ rifId(rif), rifCounterIds(rifIds)
57
+ {
58
+ SWSS_LOG_ENTER ();
59
+ }
60
+
52
61
void FlexCounter::setPollInterval (
53
62
_In_ uint32_t pollInterval,
54
63
_In_ std::string instanceId)
@@ -364,6 +373,62 @@ void FlexCounter::setPriorityGroupAttrList(
364
373
}
365
374
}
366
375
376
+ void FlexCounter::setRifCounterList (
377
+ _In_ sai_object_id_t rifVid,
378
+ _In_ sai_object_id_t rifId,
379
+ _In_ std::string instanceId,
380
+ _In_ const std::vector<sai_router_interface_stat_t > &counterIds)
381
+ {
382
+ SWSS_LOG_ENTER ();
383
+
384
+ FlexCounter &fc = getInstance (instanceId);
385
+
386
+ // Initialize the supported counters list before setting
387
+ if (supportedRifCounters.empty ())
388
+ {
389
+ fc.saiUpdateSupportedRifCounters (rifId);
390
+ }
391
+
392
+ // Remove unsupported counters
393
+ std::vector<sai_router_interface_stat_t > supportedIds;
394
+ for (auto &counter : counterIds)
395
+ {
396
+ if (fc.isRifCounterSupported (counter))
397
+ {
398
+ supportedIds.push_back (counter);
399
+ }
400
+ }
401
+
402
+ if (supportedIds.empty ())
403
+ {
404
+ SWSS_LOG_ERROR (" Router interface %s does not have supported counters" , sai_serialize_object_id (rifId).c_str ());
405
+
406
+ // Remove flex counter if all counter IDs and plugins are unregistered
407
+ if (fc.isEmpty ())
408
+ {
409
+ removeInstance (instanceId);
410
+ }
411
+
412
+ return ;
413
+ }
414
+
415
+ auto it = fc.m_rifCounterIdsMap .find (rifVid);
416
+ if (it != fc.m_rifCounterIdsMap .end ())
417
+ {
418
+ (*it).second ->rifCounterIds = supportedIds;
419
+ return ;
420
+ }
421
+
422
+ auto rifCounterIds = std::make_shared<RifCounterIds>(rifId, supportedIds);
423
+ fc.m_rifCounterIdsMap .emplace (rifVid, rifCounterIds);
424
+
425
+ // Start flex counter thread in case it was not running due to empty counter IDs map
426
+ if (fc.m_pollInterval > 0 )
427
+ {
428
+ fc.startFlexCounterThread ();
429
+ }
430
+ }
431
+
367
432
void FlexCounter::removePort (
368
433
_In_ sai_object_id_t portVid,
369
434
_In_ std::string instanceId)
@@ -465,6 +530,35 @@ void FlexCounter::removePriorityGroup(
465
530
}
466
531
}
467
532
533
+ void FlexCounter::removeRif (
534
+ _In_ sai_object_id_t rifVid,
535
+ _In_ std::string instanceId)
536
+ {
537
+ SWSS_LOG_ENTER ();
538
+
539
+ FlexCounter &fc = getInstance (instanceId);
540
+
541
+ auto it = fc.m_rifCounterIdsMap .find (rifVid);
542
+ if (it == fc.m_rifCounterIdsMap .end ())
543
+ {
544
+ SWSS_LOG_NOTICE (" Trying to remove nonexisting router interface counter from Id 0x%lx" , rifVid);
545
+ // Remove flex counter if all counter IDs and plugins are unregistered
546
+ if (fc.isEmpty ())
547
+ {
548
+ removeInstance (instanceId);
549
+ }
550
+ return ;
551
+ }
552
+
553
+ fc.m_rifCounterIdsMap .erase (it);
554
+
555
+ // Remove flex counter if all counter IDs and plugins are unregistered
556
+ if (fc.isEmpty ())
557
+ {
558
+ removeInstance (instanceId);
559
+ }
560
+ }
561
+
468
562
void FlexCounter::addPortCounterPlugin (
469
563
_In_ std::string sha,
470
564
_In_ std::string instanceId)
@@ -609,6 +703,13 @@ bool FlexCounter::isPriorityGroupCounterSupported(sai_ingress_priority_group_sta
609
703
return supportedPriorityGroupCounters.count (counter) != 0 ;
610
704
}
611
705
706
+ bool FlexCounter::isRifCounterSupported (sai_router_interface_stat_t counter) const
707
+ {
708
+ SWSS_LOG_ENTER ();
709
+
710
+ return supportedRifCounters.count (counter) != 0 ;
711
+ }
712
+
612
713
FlexCounter::FlexCounter (std::string instanceId) : m_instanceId(instanceId)
613
714
{
614
715
SWSS_LOG_ENTER ();
@@ -644,6 +745,7 @@ void FlexCounter::collectCounters(
644
745
std::map<sai_object_id_t , std::shared_ptr<QueueAttrIds>> queueAttrIdsMap;
645
746
std::map<sai_object_id_t , std::shared_ptr<IngressPriorityGroupCounterIds>> priorityGroupCounterIdsMap;
646
747
std::map<sai_object_id_t , std::shared_ptr<IngressPriorityGroupAttrIds>> priorityGroupAttrIdsMap;
748
+ std::map<sai_object_id_t , std::shared_ptr<RifCounterIds>> rifCounterIdsMap;
647
749
648
750
{
649
751
std::lock_guard<std::mutex> lock (g_mutex);
@@ -652,6 +754,7 @@ void FlexCounter::collectCounters(
652
754
queueAttrIdsMap = m_queueAttrIdsMap;
653
755
priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap;
654
756
priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap;
757
+ rifCounterIdsMap = m_rifCounterIdsMap;
655
758
}
656
759
657
760
// Collect stats for every registered port
@@ -870,6 +973,41 @@ void FlexCounter::collectCounters(
870
973
871
974
countersTable.set (priorityGroupVidStr, values, " " );
872
975
}
976
+ // Collect stats for every registered router interface
977
+ for (const auto &kv: rifCounterIdsMap)
978
+ {
979
+ const auto &rifVid = kv.first ;
980
+ const auto &rifId = kv.second ->rifId ;
981
+ const auto &rifCounterIds = kv.second ->rifCounterIds ;
982
+
983
+ std::vector<uint64_t > rifStats (rifCounterIds.size ());
984
+
985
+ // Get rif stats
986
+ sai_status_t status = sai_metadata_sai_router_interface_api->get_router_interface_stats (
987
+ rifId,
988
+ static_cast <uint32_t >(rifCounterIds.size ()),
989
+ (const sai_stat_id_t *)rifCounterIds.data (),
990
+ rifStats.data ());
991
+ if (status != SAI_STATUS_SUCCESS)
992
+ {
993
+ SWSS_LOG_ERROR (" Failed to get stats of router interface 0x%lx: %d" , rifId, status);
994
+ continue ;
995
+ }
996
+
997
+ // Push all counter values to a single vector
998
+ std::vector<swss::FieldValueTuple> values;
999
+
1000
+ for (size_t i = 0 ; i != rifCounterIds.size (); i++)
1001
+ {
1002
+ const std::string &counterName = sai_serialize_router_interface_stat (rifCounterIds[i]);
1003
+ values.emplace_back (counterName, std::to_string (rifStats[i]));
1004
+ }
1005
+
1006
+ // Write counters to DB
1007
+ std::string rifVidStr = sai_serialize_object_id (rifVid);
1008
+
1009
+ countersTable.set (rifVidStr, values, " " );
1010
+ }
873
1011
874
1012
countersTable.flush ();
875
1013
}
@@ -1094,3 +1232,28 @@ void FlexCounter::saiUpdateSupportedPriorityGroupCounters(
1094
1232
}
1095
1233
}
1096
1234
}
1235
+
1236
+ void FlexCounter::saiUpdateSupportedRifCounters (sai_object_id_t rifId)
1237
+ {
1238
+ SWSS_LOG_ENTER ();
1239
+
1240
+ uint64_t value;
1241
+ for (int cntr_id = SAI_ROUTER_INTERFACE_STAT_IN_OCTETS; cntr_id <= SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS; ++cntr_id)
1242
+ {
1243
+ sai_router_interface_stat_t counter = static_cast <sai_router_interface_stat_t >(cntr_id);
1244
+
1245
+ sai_status_t status = sai_metadata_sai_router_interface_api->get_router_interface_stats (rifId, 1 , (const sai_stat_id_t *)&counter, &value);
1246
+
1247
+ if (status != SAI_STATUS_SUCCESS)
1248
+ {
1249
+ SWSS_LOG_INFO (" Counter %s is not supported on router interface RID %s: %s" ,
1250
+ sai_serialize_router_interface_stat (counter).c_str (),
1251
+ sai_serialize_object_id (rifId).c_str (),
1252
+ sai_serialize_status (status).c_str ());
1253
+
1254
+ continue ;
1255
+ }
1256
+
1257
+ supportedRifCounters.insert (counter);
1258
+ }
1259
+ }
0 commit comments