@@ -8,6 +8,7 @@ static std::map<std::string, std::shared_ptr<FlexCounter>> g_flex_counters_map;
88static std::set<sai_port_stat_t > supportedPortCounters;
99static std::set<sai_queue_stat_t > supportedQueueCounters;
1010static std::set<sai_ingress_priority_group_stat_t > supportedPriorityGroupCounters;
11+ static std::set<sai_router_interface_stat_t > supportedRifCounters;
1112
1213FlexCounter::PortCounterIds::PortCounterIds (
1314 _In_ sai_object_id_t port,
@@ -49,6 +50,14 @@ FlexCounter::IngressPriorityGroupCounterIds::IngressPriorityGroupCounterIds(
4950 SWSS_LOG_ENTER ();
5051}
5152
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+
5261void FlexCounter::setPollInterval (
5362 _In_ uint32_t pollInterval,
5463 _In_ std::string instanceId)
@@ -364,6 +373,62 @@ void FlexCounter::setPriorityGroupAttrList(
364373 }
365374}
366375
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+
367432void FlexCounter::removePort (
368433 _In_ sai_object_id_t portVid,
369434 _In_ std::string instanceId)
@@ -465,6 +530,35 @@ void FlexCounter::removePriorityGroup(
465530 }
466531}
467532
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+
468562void FlexCounter::addPortCounterPlugin (
469563 _In_ std::string sha,
470564 _In_ std::string instanceId)
@@ -609,6 +703,13 @@ bool FlexCounter::isPriorityGroupCounterSupported(sai_ingress_priority_group_sta
609703 return supportedPriorityGroupCounters.count (counter) != 0 ;
610704}
611705
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+
612713FlexCounter::FlexCounter (std::string instanceId) : m_instanceId(instanceId)
613714{
614715 SWSS_LOG_ENTER ();
@@ -644,6 +745,7 @@ void FlexCounter::collectCounters(
644745 std::map<sai_object_id_t , std::shared_ptr<QueueAttrIds>> queueAttrIdsMap;
645746 std::map<sai_object_id_t , std::shared_ptr<IngressPriorityGroupCounterIds>> priorityGroupCounterIdsMap;
646747 std::map<sai_object_id_t , std::shared_ptr<IngressPriorityGroupAttrIds>> priorityGroupAttrIdsMap;
748+ std::map<sai_object_id_t , std::shared_ptr<RifCounterIds>> rifCounterIdsMap;
647749
648750 {
649751 std::lock_guard<std::mutex> lock (g_mutex);
@@ -652,6 +754,7 @@ void FlexCounter::collectCounters(
652754 queueAttrIdsMap = m_queueAttrIdsMap;
653755 priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap;
654756 priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap;
757+ rifCounterIdsMap = m_rifCounterIdsMap;
655758 }
656759
657760 // Collect stats for every registered port
@@ -870,6 +973,41 @@ void FlexCounter::collectCounters(
870973
871974 countersTable.set (priorityGroupVidStr, values, " " );
872975 }
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+ }
8731011
8741012 countersTable.flush ();
8751013}
@@ -1094,3 +1232,28 @@ void FlexCounter::saiUpdateSupportedPriorityGroupCounters(
10941232 }
10951233 }
10961234}
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