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

Sflow orchagent changes #1012

Merged
merged 10 commits into from
Oct 28, 2019
Merged

Sflow orchagent changes #1012

merged 10 commits into from
Oct 28, 2019

Conversation

dgsudharsan
Copy link
Collaborator

@dgsudharsan dgsudharsan commented Jul 31, 2019

What I did
Added support in swss for SFLOW. It includes sfloworch and sflowmgr changes.

Why I did it
To support SFLOW in SONIC

How I verified it
The verification is done using the vs tests which are part of these pull request.

Details if related
sflow_swss.txt

Mgr changes

Mgr changes 2

Test cases

Changing Global to global

optimizations

Reverting copp changes

clean up

UT Fixes

Addressing code review comments

Updating UT

Build fix

Adding mgr changes
{
vector<FieldValueTuple> fieldValues;

fieldValues.emplace_back(SFLOW_SAMPLE_RATE_KEY_400G, SFLOW_SAMPLE_RATE_VALUE_400G);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a map with enum values. You can refer vxlanorch.cpp/crmorch.cpp.

}
else if(op == DEL_COMMAND)
{
m_appSflowTable.del(key);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to stop hsflowd if it is running during delete case?


auto table = consumer.getTableName();

if(table == CFG_SFLOW_TABLE_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after if

cfgmgr/sflowmgr.cpp Show resolved Hide resolved
private:
Table m_cfgSflowTable;
Table m_cfgSflowSessionTable;
Table m_appSflowSpeedRateTable;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a Table?. It is m_app and must be ProducerStateTable . If it is not used, please delete this and the references.

Orch(db, tableNames)
{
SWSS_LOG_ENTER();
m_sflowSampleRateTable = unique_ptr<Table>(new Table(db, APP_SFLOW_SAMPLE_RATE_TABLE_NAME));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not fully understanding this sflowSampleRateTable . Does orchagent subscribe to this and get the info? Why to query the table directly?

sai_attribute_t attr;
sai_status_t sai_rc;


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove extra line

for(auto& pair: gPortsOrch->getAllPorts())
{
auto& port = pair.second;
if (port.m_type != Port::PHY) continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use braces {

auto sflowInfo = m_sflowPortSessionMap.find(port.m_port_id);
if(sflowInfo == m_sflowPortSessionMap.end())
{
if(!enable)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be checked above and returned - Why to do inside loop?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inside another if condition inside for loop. Only when there is no session available for port and when global is enabled, the session needs to be created. When enable is set to false when there is no session on port already it can be skipped.

if (port.m_type != Port::PHY) continue;

auto sflowInfo = m_sflowPortSessionMap.find(port.m_port_id);
if(sflowInfo == m_sflowPortSessionMap.end())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space after if - Please check other places as well

@prsunny
Copy link
Collaborator

prsunny commented Sep 5, 2019

Please provide a control flow diagram in the sFlow HLD for orchagent code flow.

Copy link
Collaborator

@prsunny prsunny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgsudharsan , Can we schedule a meeting to go over the implementation. The design is simple but the implementation has been found to be complex and I think we can find some areas to optimize.

cfgmgr/sflowmgr.cpp Show resolved Hide resolved
while (it != consumer.m_toSync.end())
{
auto tuple = it->second;
string op = kfvOp(tuple);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

op is not used

SflowSession session;
uint32_t rate = 0;

sflowGetDefaultSampleRate(port, rate);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we handle the error case here?

}
}
}
else
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if and else is long that its hard to find which is the matching if. Can you add a one line comment here?

}

auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has become so long. Can you revisit this?

@dgsudharsan
Copy link
Collaborator Author

retest this please

ProducerStateTable m_appSflowTable;
ProducerStateTable m_appSflowSessionTable;
SflowPortLocalConfMap m_sflowPortLocalConfMap;
bool intf_all_conf;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please follow the same coding style - m_intfAllConf, m_gEnable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
bool local_conf;
std::string speed;
std::string local_rate;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to use just rate instead of local_rate, same for other params

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

void sflowHandleSessionAll(bool enable);
void sflowHandleSessionLocal(bool enable);
void sflowCheckAndFillRate(std::string alias, std::vector<FieldValueTuple> &fvs);
void sflowGetLocalFvs(std::vector<FieldValueTuple> &fvs, SflowLocalPortInfo &local_info);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sflowGetLocalPortInfo, similar to sflowUpdateLocalPortInfo

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

void sflowHandleSessionLocal(bool enable);
void sflowCheckAndFillRate(std::string alias, std::vector<FieldValueTuple> &fvs);
void sflowGetLocalFvs(std::vector<FieldValueTuple> &fvs, SflowLocalPortInfo &local_info);
void sflowGetGlobalFvs(std::vector<FieldValueTuple> &fvs, std::string speed);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sflowGetGlobalInfo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
else
{
SWSS_LOG_INFO("Command '%s' succeeded", cmd.str().c_str());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to put is as NOTICE stating "Starting hsflowd service"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

orchagent/sfloworch.h Show resolved Hide resolved
private:
SflowPortInfoMap m_sflowPortInfoMap;
SflowRateSampleMap m_sflowRateSampleMap;
bool sflowStatus;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls rename to m_sflowStatus

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
if (!sflowDestroySession(m_sflowRateSampleMap[old_rate]))
{
SWSS_LOG_ERROR("Failed to clean old session %lx",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please print the old_rate value also?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


if (op == SET_COMMAND)
{
sflowExtractFvs (kfvFieldsValues(tuple), sflowStatus, rate);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant space before (. Set the rate param to default as 0 in declaration so that you don't have to specify here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

admin_state = sflowInfo->second.admin_state;
}

sflowExtractFvs(kfvFieldsValues(tuple), admin_state, rate);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it just overwrites the admin_state and rate retrieved from above. I'm not fully understanding the case here. Do you intend else here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is an already existing session, then the current admin and rate are initialized from it. Then based on key value pair parsing, we fill the admin_state and rate and override it.
In the logic below, the existing session admin state and rate are compared with the above values. If there is difference, then the session is updated, else it is ignored.
if (admin_state != sflowInfo->second.admin_state)

if (rate != sflowSessionGetRate(sflowInfo->second.m_sample_id))
For e.g current session has admin=true and rate=100
User configured new rate as 200
The in above logic first the admin is initialized to "true" and rate to 100
in key value parsing, admin is not re-initialized while rate is set to 200
In the checks below, admin state is not changed so no reprogramming is done, while rate is changed it is updated.

@dgsudharsan
Copy link
Collaborator Author

retest this please

* Change admin_state from enable/disable to up/down to match SONiC YANG.

Signed-off-by: Garrick He <[email protected]>
@prsunny
Copy link
Collaborator

prsunny commented Oct 22, 2019

retest this please

@prsunny
Copy link
Collaborator

prsunny commented Oct 22, 2019

retest this please

@prsunny
Copy link
Collaborator

prsunny commented Oct 22, 2019

retest this please

3 similar comments
@dgsudharsan
Copy link
Collaborator Author

retest this please

@prsunny
Copy link
Collaborator

prsunny commented Oct 23, 2019

retest this please

@dgsudharsan
Copy link
Collaborator Author

retest this please

@prsunny prsunny merged commit 20747fa into sonic-net:master Oct 28, 2019
Comment on lines +291 to +293
sflowHandleSessionAll(enable);
}
sflowHandleSessionLocal(enable);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typical practice for admin_state toggle is just to propagate the field-value tuple change to APPL_DB. Here, when looking into these two function internals, admin_state: down triggers deleting the entire key, say Ethernet1, in APPL_DB SFLOW_SESSION table instead of an update to field admin_state under the key. This is consistent with the HLD. But quite curious about the design thought behind it.

Copy link
Collaborator Author

@dgsudharsan dgsudharsan Sep 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wendani : Sflow has the following commands

  1. config sflow enable ------------> Enable/disable feature as a whole. When this is disabled, it means all sflow configurations need to be removed (Feature level disable).
  2. config sflow interface all enable/disable ----> Global level sflow command to control the enabling/disabling sflow globally. By default when sflow feature is enabled, all ports will have flow enabled. The main usage of this command is in 'disable' configuration. When users need to enable sflow on only one interface or very few interfaces, without global interface disable command, the user has to configure individual interface disable on the rest of the interfaces except for the interfaces of interest. Thus to avoid this, users can have sflow global interface all disable and then do individual sflow enable on interested interfaces which would override the global setting.
  3. config sflow interface Ethernetx enable/disable ------> Local interface level command which would override global interface all command when configured on specific interfaces

if (m_gEnable)
{
sflowHandleService(false);
sflowHandleSessionAll(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also call sflowHandleSessionLocal(false); here to disable individually configured port(s); otherwise redis-cli -n 4 del "SFLOW|global" command will not remove APPL_DB SFLOW_SESSION_TABLE:EthernetX for individually configured port EthernetX.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This needs to be fixed.

{
if (!intf_all_conf)
{
sflowHandleSessionAll(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should feed m_gEnable instead of true. Consider the following sequence of CLIs:

$ sudo config sflow interface disable all

m_intfAllConf is false

$ redis-cli -n 4 del "SFLOW|global"

m_gEnable is false

$ redis-cli -n 4 del "SFLOW_SESSION|all"

APPL_DB SFLOW_SESSION_TABLE:EthernetX will show up for non-individually configured port EthernetX under the condition that m_gEnable is false

@prsunny
Copy link
Collaborator

prsunny commented Aug 31, 2020

@dgsudharsan , @padmanarayana, can you please check?

EdenGri pushed a commit to EdenGri/sonic-swss that referenced this pull request Feb 28, 2022
…ng() (sonic-net#1012)

Fix typo and enable test for tablesWithOutYang()

Signed-off-by: Praveen Chaudhary [email protected]
@dgsudharsan dgsudharsan deleted the sfloworch branch March 9, 2023 02:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants