Skip to content

Commit

Permalink
Egress Sflow Support (sonic-net#2731)
Browse files Browse the repository at this point in the history
* [sflow] Added Egress Sflow support.
  • Loading branch information
rajkumar38 authored May 30, 2023
1 parent 90b34d4 commit b2c03d1
Show file tree
Hide file tree
Showing 7 changed files with 405 additions and 52 deletions.
145 changes: 118 additions & 27 deletions cfgmgr/sflowmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ SflowMgr::SflowMgr(DBConnector *cfgDb, DBConnector *appDb, const vector<string>
{
m_intfAllConf = true;
m_gEnable = false;
m_gDirection = "rx";
m_intfAllDir = "rx";
}

void SflowMgr::sflowHandleService(bool enable)
Expand Down Expand Up @@ -85,9 +87,11 @@ void SflowMgr::sflowUpdatePortInfo(Consumer &consumer)
new_port = true;
port_info.local_rate_cfg = false;
port_info.local_admin_cfg = false;
port_info.local_dir_cfg = false;
port_info.speed = SFLOW_ERROR_SPEED_STR;
port_info.rate = "";
port_info.admin = "";
port_info.dir = "";
m_sflowPortConfMap[key] = port_info;
}

Expand All @@ -106,13 +110,19 @@ void SflowMgr::sflowUpdatePortInfo(Consumer &consumer)
speed_change = true;
}

string def_dir = "rx";
if (m_sflowPortConfMap[key].dir != def_dir && !m_sflowPortConfMap[key].local_dir_cfg)
{
m_sflowPortConfMap[key].dir = def_dir;
}

if (m_gEnable && m_intfAllConf)
{
// If the Local rate Conf is already present, dont't override it even though the speed is changed
if (new_port || (speed_change && !m_sflowPortConfMap[key].local_rate_cfg))
{
vector<FieldValueTuple> fvs;
sflowGetGlobalInfo(fvs, m_sflowPortConfMap[key].speed);
sflowGetGlobalInfo(fvs, m_sflowPortConfMap[key].speed, m_sflowPortConfMap[key].dir);
m_appSflowSessionTable.set(key, fvs);
}
}
Expand All @@ -123,7 +133,8 @@ void SflowMgr::sflowUpdatePortInfo(Consumer &consumer)
if (sflowPortConf != m_sflowPortConfMap.end())
{
bool local_cfg = m_sflowPortConfMap[key].local_rate_cfg ||
m_sflowPortConfMap[key].local_admin_cfg;
m_sflowPortConfMap[key].local_admin_cfg ||
m_sflowPortConfMap[key].local_dir_cfg;

m_sflowPortConfMap.erase(key);
if ((m_intfAllConf && m_gEnable) || local_cfg)
Expand All @@ -136,25 +147,31 @@ void SflowMgr::sflowUpdatePortInfo(Consumer &consumer)
}
}

void SflowMgr::sflowHandleSessionAll(bool enable)
void SflowMgr::sflowHandleSessionAll(bool enable, string direction)
{
for (auto it: m_sflowPortConfMap)
{
if (enable)
{
vector<FieldValueTuple> fvs;
if (it.second.local_rate_cfg || it.second.local_admin_cfg)
if (it.second.local_rate_cfg || it.second.local_admin_cfg || it.second.local_dir_cfg)
{
sflowGetPortInfo(fvs, it.second);
/* Use global admin state if there is not a local one */
if (!it.second.local_admin_cfg) {
FieldValueTuple fv1("admin_state", "up");
fvs.push_back(fv1);
}

/* Use global sample direction state if there is not a local one */
if (!it.second.local_dir_cfg) {
FieldValueTuple fv2("sample_direction", direction);
fvs.push_back(fv2);
}
}
else
{
sflowGetGlobalInfo(fvs, it.second.speed);
sflowGetGlobalInfo(fvs, it.second.speed, direction);
}
m_appSflowSessionTable.set(it.first, fvs);
}
Expand All @@ -169,7 +186,7 @@ void SflowMgr::sflowHandleSessionLocal(bool enable)
{
for (auto it: m_sflowPortConfMap)
{
if (it.second.local_admin_cfg || it.second.local_rate_cfg)
if (it.second.local_admin_cfg || it.second.local_rate_cfg || it.second.local_dir_cfg)
{
vector<FieldValueTuple> fvs;
sflowGetPortInfo(fvs, it.second);
Expand All @@ -185,7 +202,7 @@ void SflowMgr::sflowHandleSessionLocal(bool enable)
}
}

void SflowMgr::sflowGetGlobalInfo(vector<FieldValueTuple> &fvs, string speed)
void SflowMgr::sflowGetGlobalInfo(vector<FieldValueTuple> &fvs, string speed, string dir)
{
string rate;
FieldValueTuple fv1("admin_state", "up");
Expand All @@ -201,6 +218,9 @@ void SflowMgr::sflowGetGlobalInfo(vector<FieldValueTuple> &fvs, string speed)
}
FieldValueTuple fv2("sample_rate",rate);
fvs.push_back(fv2);

FieldValueTuple fv3("sample_direction",dir);
fvs.push_back(fv3);
}

void SflowMgr::sflowGetPortInfo(vector<FieldValueTuple> &fvs, SflowPortInfo &local_info)
Expand All @@ -213,6 +233,12 @@ void SflowMgr::sflowGetPortInfo(vector<FieldValueTuple> &fvs, SflowPortInfo &loc

FieldValueTuple fv2("sample_rate", local_info.rate);
fvs.push_back(fv2);

if (local_info.local_dir_cfg)
{
FieldValueTuple fv3("sample_direction", local_info.dir);
fvs.push_back(fv3);
}
}

void SflowMgr::sflowCheckAndFillValues(string alias, vector<FieldValueTuple> &values,
Expand All @@ -221,6 +247,7 @@ void SflowMgr::sflowCheckAndFillValues(string alias, vector<FieldValueTuple> &va
string rate;
bool admin_present = false;
bool rate_present = false;
bool dir_present = false;

for (auto i : values)
{
Expand All @@ -240,6 +267,14 @@ void SflowMgr::sflowCheckAndFillValues(string alias, vector<FieldValueTuple> &va
FieldValueTuple fv(fvField(i), fvValue(i));
fvs.push_back(fv);
}
if (fvField(i) == "sample_direction")
{
dir_present = true;
m_sflowPortConfMap[alias].dir = fvValue(i);
m_sflowPortConfMap[alias].local_dir_cfg = true;
FieldValueTuple fv(fvField(i), fvValue(i));
fvs.push_back(fv);
}
if (fvField(i) == "NULL")
{
continue;
Expand Down Expand Up @@ -282,6 +317,18 @@ void SflowMgr::sflowCheckAndFillValues(string alias, vector<FieldValueTuple> &va
FieldValueTuple fv("admin_state", m_sflowPortConfMap[alias].admin);
fvs.push_back(fv);
}

if (!dir_present)
{
if (m_sflowPortConfMap[alias].dir == "")
{
/* By default direction is set to global, if not set explicitly */
m_sflowPortConfMap[alias].dir = m_gDirection;
}
m_sflowPortConfMap[alias].local_dir_cfg = false;
FieldValueTuple fv("sample_direction", m_sflowPortConfMap[alias].dir);
fvs.push_back(fv);
}
}

void SflowMgr::doTask(Consumer &consumer)
Expand Down Expand Up @@ -309,51 +356,92 @@ void SflowMgr::doTask(Consumer &consumer)
{
if (table == CFG_SFLOW_TABLE_NAME)
{
SWSS_LOG_DEBUG("Current Cfg admin %d dir %s ", (unsigned int)m_gEnable, m_gDirection.c_str());
bool enable = false;
string direction = "rx";
for (auto i : values)
{
if (fvField(i) == "admin_state")
{
bool enable = false;
if (fvValue(i) == "up")
{
enable = true;
}
if (enable == m_gEnable)
{
break;
}
m_gEnable = enable;
sflowHandleService(enable);
if (m_intfAllConf)
{
sflowHandleSessionAll(enable);
}
sflowHandleSessionLocal(enable);
}
else if (fvField(i) == "sample_direction")
{
direction = fvValue(i);
}
}

if (direction != m_gDirection)
{
m_gDirection = direction;
}

if (m_gEnable != enable)
{
m_gEnable = enable;
sflowHandleService(enable);
}

if (m_intfAllConf)
{
sflowHandleSessionAll(m_gEnable, m_gDirection);
}

sflowHandleSessionLocal(m_gEnable);
m_appSflowTable.set(key, values);

SWSS_LOG_DEBUG("New config admin %d dir %s ", (unsigned int)m_gEnable, m_gDirection.c_str());
}
else if (table == CFG_SFLOW_SESSION_TABLE_NAME)
{
if (key == "all")
{
SWSS_LOG_DEBUG("current config gAdmin %d dir %s intfAllEna %d intfAllDir %s",
(unsigned int)m_gEnable, m_gDirection.c_str(),
(unsigned int)m_intfAllConf, m_intfAllDir.c_str());

string direction = m_intfAllDir;
bool enable = m_intfAllConf;
for (auto i : values)
{
if (fvField(i) == "admin_state")
{
bool enable = false;

if (fvValue(i) == "up")
{
enable = true;
}
if ((enable != m_intfAllConf) && (m_gEnable))
else if (fvValue(i) == "down")
{
sflowHandleSessionAll(enable);
enable = false;
}
m_intfAllConf = enable;
}
else if (fvField(i) == "sample_direction")
{
direction = fvValue(i);
}
}

if (m_intfAllDir != direction)
{
m_intfAllDir = direction;
}

if (enable != m_intfAllConf)
{
m_intfAllConf = enable;
}

if (m_gEnable)
{
sflowHandleSessionAll(m_intfAllConf, m_intfAllDir);
}

SWSS_LOG_DEBUG("New config gAdmin %d dir %s intfAllEna %d intfAllDir %s",
(unsigned int)m_gEnable, m_gDirection.c_str(),
(unsigned int)m_intfAllConf, m_intfAllDir.c_str());
}
else
{
Expand All @@ -380,10 +468,11 @@ void SflowMgr::doTask(Consumer &consumer)
if (m_gEnable)
{
sflowHandleService(false);
sflowHandleSessionAll(false);
sflowHandleSessionAll(false, "");
sflowHandleSessionLocal(false);
}
m_gEnable = false;
m_gDirection = "rx";
m_appSflowTable.del(key);
}
else if (table == CFG_SFLOW_SESSION_TABLE_NAME)
Expand All @@ -394,7 +483,7 @@ void SflowMgr::doTask(Consumer &consumer)
{
if (m_gEnable)
{
sflowHandleSessionAll(true);
sflowHandleSessionAll(true, m_gDirection);
}
}
m_intfAllConf = true;
Expand All @@ -404,14 +493,16 @@ void SflowMgr::doTask(Consumer &consumer)
m_appSflowSessionTable.del(key);
m_sflowPortConfMap[key].local_rate_cfg = false;
m_sflowPortConfMap[key].local_admin_cfg = false;
m_sflowPortConfMap[key].local_dir_cfg = false;
m_sflowPortConfMap[key].rate = "";
m_sflowPortConfMap[key].admin = "";
m_sflowPortConfMap[key].dir = "";

/* If Global configured, set global session on port after local config is deleted */
if (m_intfAllConf)
{
vector<FieldValueTuple> fvs;
sflowGetGlobalInfo(fvs, m_sflowPortConfMap[key].speed);
sflowGetGlobalInfo(fvs, m_sflowPortConfMap[key].speed, m_intfAllDir);
m_appSflowSessionTable.set(key,fvs);
}
}
Expand Down
8 changes: 6 additions & 2 deletions cfgmgr/sflowmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ struct SflowPortInfo
{
bool local_rate_cfg;
bool local_admin_cfg;
bool local_dir_cfg;
std::string speed;
std::string rate;
std::string admin;
std::string dir;
};

/* Port to Local config map */
Expand All @@ -56,15 +58,17 @@ class SflowMgr : public Orch
SflowPortConfMap m_sflowPortConfMap;
bool m_intfAllConf;
bool m_gEnable;
std::string m_intfAllDir;
std::string m_gDirection;

void doTask(Consumer &consumer);
void sflowHandleService(bool enable);
void sflowUpdatePortInfo(Consumer &consumer);
void sflowHandleSessionAll(bool enable);
void sflowHandleSessionAll(bool enable, std::string direction);
void sflowHandleSessionLocal(bool enable);
void sflowCheckAndFillValues(std::string alias, std::vector<FieldValueTuple> &values, std::vector<FieldValueTuple> &fvs);
void sflowGetPortInfo(std::vector<FieldValueTuple> &fvs, SflowPortInfo &local_info);
void sflowGetGlobalInfo(std::vector<FieldValueTuple> &fvs, std::string speed);
void sflowGetGlobalInfo(std::vector<FieldValueTuple> &fvs, std::string speed, std::string direction);
};

}
Loading

0 comments on commit b2c03d1

Please sign in to comment.