Skip to content

Commit 88b62ce

Browse files
authored
Added Flex Counters support for tunnel counters (#886)
Added Flex counter support for tunnel counters and rates implementation
1 parent a718226 commit 88b62ce

File tree

2 files changed

+245
-3
lines changed

2 files changed

+245
-3
lines changed

syncd/FlexCounter.cpp

+214-3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ FlexCounter::MACsecSAAttrIds::MACsecSAAttrIds(
114114
// empty intentionally
115115
}
116116

117+
FlexCounter::TunnelCounterIds::TunnelCounterIds(
118+
_In_ sai_object_id_t tunnelRid,
119+
_In_ const std::vector<sai_tunnel_stat_t> &tunnelIds):
120+
m_tunnelId(tunnelRid),
121+
m_tunnelCounterIds(tunnelIds)
122+
{
123+
SWSS_LOG_ENTER();
124+
// empty intentionally
125+
}
126+
117127
void FlexCounter::setPollInterval(
118128
_In_ uint32_t pollInterval)
119129
{
@@ -567,6 +577,47 @@ void FlexCounter::setBufferPoolCounterList(
567577
addCollectCountersHandler(BUFFER_POOL_COUNTER_ID_LIST, &FlexCounter::collectBufferPoolCounters);
568578
}
569579

580+
void FlexCounter::setTunnelCounterList(
581+
_In_ sai_object_id_t tunnelVid,
582+
_In_ sai_object_id_t tunnelRid,
583+
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
584+
{
585+
SWSS_LOG_ENTER();
586+
587+
updateSupportedTunnelCounters(tunnelRid, counterIds);
588+
589+
// Remove unsupported counters
590+
std::vector<sai_tunnel_stat_t> supportedIds;
591+
592+
for (auto &counter : counterIds)
593+
{
594+
if (isTunnelCounterSupported(counter))
595+
{
596+
supportedIds.push_back(counter);
597+
}
598+
}
599+
600+
if (supportedIds.empty())
601+
{
602+
SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str());
603+
return;
604+
}
605+
606+
auto it = m_tunnelCounterIdsMap.find(tunnelVid);
607+
608+
if (it != m_tunnelCounterIdsMap.end())
609+
{
610+
it->second->m_tunnelCounterIds = supportedIds;
611+
return;
612+
}
613+
614+
auto tunnelCounterIds = std::make_shared<TunnelCounterIds>(tunnelRid, supportedIds);
615+
616+
m_tunnelCounterIdsMap.emplace(tunnelVid, tunnelCounterIds);
617+
618+
addCollectCountersHandler(TUNNEL_COUNTER_ID_LIST, &FlexCounter::collectTunnelCounters);
619+
}
620+
570621
void FlexCounter::removePort(
571622
_In_ sai_object_id_t portVid)
572623
{
@@ -787,6 +838,27 @@ void FlexCounter::removeSwitchDebugCounters(
787838
}
788839
}
789840

841+
void FlexCounter::removeTunnel(
842+
_In_ sai_object_id_t tunnelVid)
843+
{
844+
SWSS_LOG_ENTER();
845+
846+
auto it = m_tunnelCounterIdsMap.find(tunnelVid);
847+
848+
if (it == m_tunnelCounterIdsMap.end())
849+
{
850+
SWSS_LOG_NOTICE("Trying to remove nonexisting tunnel counter from Id 0x%" PRIx64, tunnelVid);
851+
return;
852+
}
853+
854+
m_tunnelCounterIdsMap.erase(it);
855+
856+
if (m_tunnelCounterIdsMap.empty())
857+
{
858+
removeCollectCountersHandler(TUNNEL_COUNTER_ID_LIST);
859+
}
860+
}
861+
790862
void FlexCounter::checkPluginRegistered(
791863
_In_ const std::string& sha) const
792864
{
@@ -797,7 +869,8 @@ void FlexCounter::checkPluginRegistered(
797869
m_rifPlugins.find(sha) != m_rifPlugins.end() ||
798870
m_queuePlugins.find(sha) != m_queuePlugins.end() ||
799871
m_priorityGroupPlugins.find(sha) != m_priorityGroupPlugins.end() ||
800-
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end()
872+
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end() ||
873+
m_tunnelPlugins.find(sha) != m_tunnelPlugins.end()
801874
)
802875
{
803876
SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str());
@@ -864,6 +937,18 @@ void FlexCounter::addBufferPoolCounterPlugin(
864937
SWSS_LOG_NOTICE("Buffer pool counters plugin %s registered", sha.c_str());
865938
}
866939

940+
void FlexCounter::addTunnelCounterPlugin(
941+
_In_ const std::string& sha)
942+
{
943+
SWSS_LOG_ENTER();
944+
945+
checkPluginRegistered(sha);
946+
947+
m_tunnelPlugins.insert(sha);
948+
949+
SWSS_LOG_NOTICE("Tunnel counters plugin %s registered", sha.c_str());
950+
}
951+
867952
void FlexCounter::removeCounterPlugins()
868953
{
869954
MUTEX;
@@ -875,6 +960,7 @@ void FlexCounter::removeCounterPlugins()
875960
m_rifPlugins.clear();
876961
m_priorityGroupPlugins.clear();
877962
m_bufferPoolPlugins.clear();
963+
m_tunnelPlugins.clear();
878964

879965
m_isDiscarded = true;
880966
}
@@ -942,6 +1028,13 @@ void FlexCounter::addCounterPlugin(
9421028
addBufferPoolCounterPlugin(sha);
9431029
}
9441030
}
1031+
else if (field == TUNNEL_PLUGIN_FIELD)
1032+
{
1033+
for (auto& sha: shaStrings)
1034+
{
1035+
addTunnelCounterPlugin(sha);
1036+
}
1037+
}
9451038
else
9461039
{
9471040
SWSS_LOG_ERROR("Field is not supported %s", field.c_str());
@@ -981,7 +1074,8 @@ bool FlexCounter::allIdsEmpty() const
9811074
m_rifCounterIdsMap.empty() &&
9821075
m_bufferPoolCounterIdsMap.empty() &&
9831076
m_switchDebugCounterIdsMap.empty() &&
984-
m_macsecSAAttrIdsMap.empty();
1077+
m_macsecSAAttrIdsMap.empty() &&
1078+
m_tunnelCounterIdsMap.empty();
9851079
}
9861080

9871081
bool FlexCounter::allPluginsEmpty() const
@@ -992,7 +1086,8 @@ bool FlexCounter::allPluginsEmpty() const
9921086
m_queuePlugins.empty() &&
9931087
m_portPlugins.empty() &&
9941088
m_rifPlugins.empty() &&
995-
m_bufferPoolPlugins.empty();
1089+
m_bufferPoolPlugins.empty() &&
1090+
m_tunnelPlugins.empty();
9961091
}
9971092

9981093
bool FlexCounter::isPortCounterSupported(sai_port_stat_t counter) const
@@ -1034,6 +1129,14 @@ bool FlexCounter::isBufferPoolCounterSupported(
10341129
return m_supportedBufferPoolCounters.count(counter) != 0;
10351130
}
10361131

1132+
bool FlexCounter::isTunnelCounterSupported(
1133+
_In_ sai_tunnel_stat_t counter) const
1134+
{
1135+
SWSS_LOG_ENTER();
1136+
1137+
return m_supportedTunnelCounters.count(counter) != 0;
1138+
}
1139+
10371140
bool FlexCounter::isStatsModeSupported(
10381141
_In_ uint32_t statsMode,
10391142
_In_ sai_stats_mode_t statCapability)
@@ -1597,6 +1700,51 @@ void FlexCounter::collectBufferPoolCounters(
15971700
}
15981701
}
15991702

1703+
void FlexCounter::collectTunnelCounters(
1704+
_In_ swss::Table &countersTable)
1705+
{
1706+
SWSS_LOG_ENTER();
1707+
1708+
// Collect stats for every registered tunnel
1709+
for (const auto &kv: m_tunnelCounterIdsMap)
1710+
{
1711+
const auto &tunnelVid = kv.first;
1712+
const auto &tunnelId = kv.second->m_tunnelId;
1713+
const auto &tunnelCounterIds = kv.second->m_tunnelCounterIds;
1714+
1715+
std::vector<uint64_t> tunnelStats(tunnelCounterIds.size());
1716+
1717+
// Get tunnel stats
1718+
sai_status_t status = m_vendorSai->getStats(
1719+
SAI_OBJECT_TYPE_TUNNEL,
1720+
tunnelId,
1721+
static_cast<uint32_t>(tunnelCounterIds.size()),
1722+
(const sai_stat_id_t *)tunnelCounterIds.data(),
1723+
tunnelStats.data());
1724+
1725+
if (status != SAI_STATUS_SUCCESS)
1726+
{
1727+
SWSS_LOG_ERROR("Failed to get stats of tunnel 0x%" PRIx64 ": %d", tunnelId, status);
1728+
continue;
1729+
}
1730+
1731+
// Push all counter values to a single vector
1732+
std::vector<swss::FieldValueTuple> values;
1733+
1734+
for (size_t i = 0; i != tunnelCounterIds.size(); i++)
1735+
{
1736+
const std::string &counterName = sai_serialize_tunnel_stat(tunnelCounterIds[i]);
1737+
1738+
values.emplace_back(counterName, std::to_string(tunnelStats[i]));
1739+
}
1740+
1741+
// Write counters to DB
1742+
std::string tunnelVidStr = sai_serialize_object_id(tunnelVid);
1743+
1744+
countersTable.set(tunnelVidStr, values, "");
1745+
}
1746+
}
1747+
16001748
void FlexCounter::runPlugins(
16011749
_In_ swss::DBConnector& counters_db)
16021750
{
@@ -1675,6 +1823,17 @@ void FlexCounter::runPlugins(
16751823
{
16761824
runRedisScript(counters_db, sha, bufferPoolVids, argv);
16771825
}
1826+
1827+
std::vector<std::string> tunnelList;
1828+
tunnelList.reserve(m_tunnelCounterIdsMap.size());
1829+
for (const auto& kv : m_tunnelCounterIdsMap)
1830+
{
1831+
tunnelList.push_back(sai_serialize_object_id(kv.first));
1832+
}
1833+
for (const auto& sha : m_tunnelPlugins)
1834+
{
1835+
runRedisScript(counters_db, sha, tunnelList, argv);
1836+
}
16781837
}
16791838

16801839
void FlexCounter::flexCounterThreadRunFunction()
@@ -2318,6 +2477,41 @@ void FlexCounter::getSupportedBufferPoolCounters(
23182477
}
23192478
}
23202479

2480+
void FlexCounter::updateSupportedTunnelCounters(
2481+
_In_ sai_object_id_t tunnelRid,
2482+
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
2483+
{
2484+
SWSS_LOG_ENTER();
2485+
2486+
if (m_supportedTunnelCounters.size())
2487+
{
2488+
return;
2489+
}
2490+
2491+
uint64_t value;
2492+
for (auto &counter: counterIds)
2493+
{
2494+
sai_status_t status = m_vendorSai->getStats(
2495+
SAI_OBJECT_TYPE_TUNNEL,
2496+
tunnelRid,
2497+
1,
2498+
(const sai_stat_id_t *)&counter,
2499+
&value);
2500+
2501+
if (status != SAI_STATUS_SUCCESS)
2502+
{
2503+
SWSS_LOG_INFO("Counter %s is not supported on tunnel RID %s: %s",
2504+
sai_serialize_tunnel_stat(counter).c_str(),
2505+
sai_serialize_object_id(tunnelRid).c_str(),
2506+
sai_serialize_status(status).c_str());
2507+
2508+
continue;
2509+
}
2510+
2511+
m_supportedTunnelCounters.insert(counter);
2512+
}
2513+
}
2514+
23212515
void FlexCounter::updateSupportedBufferPoolCounters(
23222516
_In_ sai_object_id_t bufferPoolId,
23232517
_In_ const std::vector<sai_buffer_pool_stat_t> &counterIds,
@@ -2413,6 +2607,10 @@ void FlexCounter::removeCounter(
24132607
{
24142608
removeMACsecSA(vid);
24152609
}
2610+
else if (objectType == SAI_OBJECT_TYPE_TUNNEL)
2611+
{
2612+
removeTunnel(vid);
2613+
}
24162614
else
24172615
{
24182616
SWSS_LOG_ERROR("Object type for removal not supported, %s",
@@ -2568,6 +2766,19 @@ void FlexCounter::addCounter(
25682766
{
25692767
statsMode = value;
25702768
}
2769+
else if (objectType == SAI_OBJECT_TYPE_TUNNEL && field == TUNNEL_COUNTER_ID_LIST)
2770+
{
2771+
std::vector<sai_tunnel_stat_t> tunnelCounterIds;
2772+
2773+
for (const auto &str : idStrings)
2774+
{
2775+
sai_tunnel_stat_t stat;
2776+
sai_deserialize_tunnel_stat(str.c_str(), &stat);
2777+
tunnelCounterIds.push_back(stat);
2778+
}
2779+
2780+
setTunnelCounterList(vid, rid, tunnelCounterIds);
2781+
}
25712782
else
25722783
{
25732784
SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s",

0 commit comments

Comments
 (0)