Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Flex Counters support for tunnel counters #886

Merged
merged 12 commits into from
Nov 2, 2021
217 changes: 214 additions & 3 deletions syncd/FlexCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ FlexCounter::MACsecSAAttrIds::MACsecSAAttrIds(
// empty intentionally
}

FlexCounter::TunnelCounterIds::TunnelCounterIds(
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &tunnelIds):
m_tunnelId(tunnelRid),
m_tunnelCounterIds(tunnelIds)
{
SWSS_LOG_ENTER();
// empty intentionally
}
kcudnik marked this conversation as resolved.
Show resolved Hide resolved

void FlexCounter::setPollInterval(
_In_ uint32_t pollInterval)
{
Expand Down Expand Up @@ -567,6 +577,47 @@ void FlexCounter::setBufferPoolCounterList(
addCollectCountersHandler(BUFFER_POOL_COUNTER_ID_LIST, &FlexCounter::collectBufferPoolCounters);
}

void FlexCounter::setTunnelCounterList(
_In_ sai_object_id_t tunnelVid,
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
{
SWSS_LOG_ENTER();

updateSupportedTunnelCounters(tunnelRid, counterIds);

// Remove unsupported counters
std::vector<sai_tunnel_stat_t> supportedIds;

for (auto &counter : counterIds)
{
if (isTunnelCounterSupported(counter))
{
supportedIds.push_back(counter);
}
}

if (supportedIds.empty())
{
SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str());
return;
}

auto it = m_tunnelCounterIdsMap.find(tunnelVid);

if (it != m_tunnelCounterIdsMap.end())
{
it->second->m_tunnelCounterIds = supportedIds;
return;
}

auto tunnelCounterIds = std::make_shared<TunnelCounterIds>(tunnelRid, supportedIds);

m_tunnelCounterIdsMap.emplace(tunnelVid, tunnelCounterIds);

addCollectCountersHandler(TUNNEL_COUNTER_ID_LIST, &FlexCounter::collectTunnelCounters);
}

void FlexCounter::removePort(
_In_ sai_object_id_t portVid)
{
Expand Down Expand Up @@ -787,6 +838,27 @@ void FlexCounter::removeSwitchDebugCounters(
}
}

void FlexCounter::removeTunnel(
_In_ sai_object_id_t tunnelVid)
{
SWSS_LOG_ENTER();

auto it = m_tunnelCounterIdsMap.find(tunnelVid);

if (it == m_tunnelCounterIdsMap.end())
{
SWSS_LOG_NOTICE("Trying to remove nonexisting tunnel counter from Id 0x%" PRIx64, tunnelVid);
return;
}

m_tunnelCounterIdsMap.erase(it);

if (m_tunnelCounterIdsMap.empty())
{
removeCollectCountersHandler(TUNNEL_COUNTER_ID_LIST);
}
}

void FlexCounter::checkPluginRegistered(
_In_ const std::string& sha) const
{
Expand All @@ -797,7 +869,8 @@ void FlexCounter::checkPluginRegistered(
m_rifPlugins.find(sha) != m_rifPlugins.end() ||
m_queuePlugins.find(sha) != m_queuePlugins.end() ||
m_priorityGroupPlugins.find(sha) != m_priorityGroupPlugins.end() ||
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end()
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end() ||
m_tunnelPlugins.find(sha) != m_tunnelPlugins.end()
)
{
SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str());
Expand Down Expand Up @@ -864,6 +937,18 @@ void FlexCounter::addBufferPoolCounterPlugin(
SWSS_LOG_NOTICE("Buffer pool counters plugin %s registered", sha.c_str());
}

void FlexCounter::addTunnelCounterPlugin(
_In_ const std::string& sha)
{
SWSS_LOG_ENTER();

checkPluginRegistered(sha);

m_tunnelPlugins.insert(sha);

SWSS_LOG_NOTICE("Tunnel counters plugin %s registered", sha.c_str());
}

void FlexCounter::removeCounterPlugins()
{
MUTEX;
Expand All @@ -875,6 +960,7 @@ void FlexCounter::removeCounterPlugins()
m_rifPlugins.clear();
m_priorityGroupPlugins.clear();
m_bufferPoolPlugins.clear();
m_tunnelPlugins.clear();

m_isDiscarded = true;
}
Expand Down Expand Up @@ -942,6 +1028,13 @@ void FlexCounter::addCounterPlugin(
addBufferPoolCounterPlugin(sha);
}
}
else if (field == TUNNEL_PLUGIN_FIELD)
{
for (auto& sha: shaStrings)
{
addTunnelCounterPlugin(sha);
}
}
else
{
SWSS_LOG_ERROR("Field is not supported %s", field.c_str());
Expand Down Expand Up @@ -981,7 +1074,8 @@ bool FlexCounter::allIdsEmpty() const
m_rifCounterIdsMap.empty() &&
m_bufferPoolCounterIdsMap.empty() &&
m_switchDebugCounterIdsMap.empty() &&
m_macsecSAAttrIdsMap.empty();
m_macsecSAAttrIdsMap.empty() &&
m_tunnelCounterIdsMap.empty();
}

bool FlexCounter::allPluginsEmpty() const
Expand All @@ -992,7 +1086,8 @@ bool FlexCounter::allPluginsEmpty() const
m_queuePlugins.empty() &&
m_portPlugins.empty() &&
m_rifPlugins.empty() &&
m_bufferPoolPlugins.empty();
m_bufferPoolPlugins.empty() &&
m_tunnelPlugins.empty();
}

bool FlexCounter::isPortCounterSupported(sai_port_stat_t counter) const
Expand Down Expand Up @@ -1034,6 +1129,14 @@ bool FlexCounter::isBufferPoolCounterSupported(
return m_supportedBufferPoolCounters.count(counter) != 0;
}

bool FlexCounter::isTunnelCounterSupported(
_In_ sai_tunnel_stat_t counter) const
{
SWSS_LOG_ENTER();

return m_supportedTunnelCounters.count(counter) != 0;
}

bool FlexCounter::isStatsModeSupported(
_In_ uint32_t statsMode,
_In_ sai_stats_mode_t statCapability)
Expand Down Expand Up @@ -1597,6 +1700,51 @@ void FlexCounter::collectBufferPoolCounters(
}
}

void FlexCounter::collectTunnelCounters(
_In_ swss::Table &countersTable)
{
SWSS_LOG_ENTER();

// Collect stats for every registered tunnel
for (const auto &kv: m_tunnelCounterIdsMap)
{
const auto &tunnelVid = kv.first;
const auto &tunnelId = kv.second->m_tunnelId;
const auto &tunnelCounterIds = kv.second->m_tunnelCounterIds;

std::vector<uint64_t> tunnelStats(tunnelCounterIds.size());

// Get tunnel stats
sai_status_t status = m_vendorSai->getStats(
SAI_OBJECT_TYPE_TUNNEL,
tunnelId,
static_cast<uint32_t>(tunnelCounterIds.size()),
(const sai_stat_id_t *)tunnelCounterIds.data(),
tunnelStats.data());

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get stats of tunnel 0x%" PRIx64 ": %d", tunnelId, status);
continue;
}

// Push all counter values to a single vector
std::vector<swss::FieldValueTuple> values;

for (size_t i = 0; i != tunnelCounterIds.size(); i++)
{
const std::string &counterName = sai_serialize_tunnel_stat(tunnelCounterIds[i]);

values.emplace_back(counterName, std::to_string(tunnelStats[i]));
}

// Write counters to DB
std::string tunnelVidStr = sai_serialize_object_id(tunnelVid);

countersTable.set(tunnelVidStr, values, "");
}
}

void FlexCounter::runPlugins(
_In_ swss::DBConnector& counters_db)
{
Expand Down Expand Up @@ -1675,6 +1823,17 @@ void FlexCounter::runPlugins(
{
runRedisScript(counters_db, sha, bufferPoolVids, argv);
}

std::vector<std::string> tunnelList;
tunnelList.reserve(m_tunnelCounterIdsMap.size());
for (const auto& kv : m_tunnelCounterIdsMap)
{
tunnelList.push_back(sai_serialize_object_id(kv.first));
}
for (const auto& sha : m_tunnelPlugins)
{
runRedisScript(counters_db, sha, tunnelList, argv);
}
}

void FlexCounter::flexCounterThreadRunFunction()
Expand Down Expand Up @@ -2318,6 +2477,41 @@ void FlexCounter::getSupportedBufferPoolCounters(
}
}

void FlexCounter::updateSupportedTunnelCounters(
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
{
SWSS_LOG_ENTER();

if (m_supportedTunnelCounters.size())
{
return;
}

uint64_t value;
for (auto &counter: counterIds)
{
sai_status_t status = m_vendorSai->getStats(
SAI_OBJECT_TYPE_TUNNEL,
tunnelRid,
1,
(const sai_stat_id_t *)&counter,
&value);

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_INFO("Counter %s is not supported on tunnel RID %s: %s",
sai_serialize_tunnel_stat(counter).c_str(),
sai_serialize_object_id(tunnelRid).c_str(),
sai_serialize_status(status).c_str());

continue;
}

m_supportedTunnelCounters.insert(counter);
}
}

void FlexCounter::updateSupportedBufferPoolCounters(
_In_ sai_object_id_t bufferPoolId,
_In_ const std::vector<sai_buffer_pool_stat_t> &counterIds,
Expand Down Expand Up @@ -2413,6 +2607,10 @@ void FlexCounter::removeCounter(
{
removeMACsecSA(vid);
}
else if (objectType == SAI_OBJECT_TYPE_TUNNEL)
{
removeTunnel(vid);
}
else
{
SWSS_LOG_ERROR("Object type for removal not supported, %s",
Expand Down Expand Up @@ -2568,6 +2766,19 @@ void FlexCounter::addCounter(
{
statsMode = value;
}
else if (objectType == SAI_OBJECT_TYPE_TUNNEL && field == TUNNEL_COUNTER_ID_LIST)
{
std::vector<sai_tunnel_stat_t> tunnelCounterIds;

for (const auto &str : idStrings)
{
sai_tunnel_stat_t stat;
sai_deserialize_tunnel_stat(str.c_str(), &stat);
tunnelCounterIds.push_back(stat);
}

setTunnelCounterList(vid, rid, tunnelCounterIds);
}
else
{
SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s",
Expand Down
Loading