-
Notifications
You must be signed in to change notification settings - Fork 539
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
Sflow orchagent changes #1012
Conversation
d45786b
to
b8f1a9b
Compare
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
cfgmgr/sflowmgr.cpp
Outdated
{ | ||
vector<FieldValueTuple> fieldValues; | ||
|
||
fieldValues.emplace_back(SFLOW_SAMPLE_RATE_KEY_400G, SFLOW_SAMPLE_RATE_VALUE_400G); |
There was a problem hiding this comment.
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.
cfgmgr/sflowmgr.cpp
Outdated
} | ||
else if(op == DEL_COMMAND) | ||
{ | ||
m_appSflowTable.del(key); |
There was a problem hiding this comment.
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?
cfgmgr/sflowmgr.cpp
Outdated
|
||
auto table = consumer.getTableName(); | ||
|
||
if(table == CFG_SFLOW_TABLE_NAME) |
There was a problem hiding this comment.
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.h
Outdated
private: | ||
Table m_cfgSflowTable; | ||
Table m_cfgSflowSessionTable; | ||
Table m_appSflowSpeedRateTable; |
There was a problem hiding this comment.
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.
orchagent/sfloworch.cpp
Outdated
Orch(db, tableNames) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
m_sflowSampleRateTable = unique_ptr<Table>(new Table(db, APP_SFLOW_SAMPLE_RATE_TABLE_NAME)); |
There was a problem hiding this comment.
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?
orchagent/sfloworch.cpp
Outdated
sai_attribute_t attr; | ||
sai_status_t sai_rc; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove extra line
orchagent/sfloworch.cpp
Outdated
for(auto& pair: gPortsOrch->getAllPorts()) | ||
{ | ||
auto& port = pair.second; | ||
if (port.m_type != Port::PHY) continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use braces {
orchagent/sfloworch.cpp
Outdated
auto sflowInfo = m_sflowPortSessionMap.find(port.m_port_id); | ||
if(sflowInfo == m_sflowPortSessionMap.end()) | ||
{ | ||
if(!enable) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
orchagent/sfloworch.cpp
Outdated
if (port.m_type != Port::PHY) continue; | ||
|
||
auto sflowInfo = m_sflowPortSessionMap.find(port.m_port_id); | ||
if(sflowInfo == m_sflowPortSessionMap.end()) |
There was a problem hiding this comment.
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
Please provide a control flow diagram in the sFlow HLD for |
There was a problem hiding this 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.
orchagent/sfloworch.cpp
Outdated
while (it != consumer.m_toSync.end()) | ||
{ | ||
auto tuple = it->second; | ||
string op = kfvOp(tuple); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op
is not used
orchagent/sfloworch.cpp
Outdated
SflowSession session; | ||
uint32_t rate = 0; | ||
|
||
sflowGetDefaultSampleRate(port, rate); |
There was a problem hiding this comment.
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?
orchagent/sfloworch.cpp
Outdated
} | ||
} | ||
} | ||
else |
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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?
retest this please |
cfgmgr/sflowmgr.h
Outdated
ProducerStateTable m_appSflowTable; | ||
ProducerStateTable m_appSflowSessionTable; | ||
SflowPortLocalConfMap m_sflowPortLocalConfMap; | ||
bool intf_all_conf; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
cfgmgr/sflowmgr.h
Outdated
{ | ||
bool local_conf; | ||
std::string speed; | ||
std::string local_rate; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
cfgmgr/sflowmgr.h
Outdated
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sflowGetLocalPortInfo
, similar to sflowUpdateLocalPortInfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
cfgmgr/sflowmgr.h
Outdated
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sflowGetGlobalInfo
?
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
orchagent/sfloworch.h
Outdated
private: | ||
SflowPortInfoMap m_sflowPortInfoMap; | ||
SflowRateSampleMap m_sflowRateSampleMap; | ||
bool sflowStatus; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
orchagent/sfloworch.cpp
Outdated
{ | ||
if (!sflowDestroySession(m_sflowRateSampleMap[old_rate])) | ||
{ | ||
SWSS_LOG_ERROR("Failed to clean old session %lx", |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
orchagent/sfloworch.cpp
Outdated
|
||
if (op == SET_COMMAND) | ||
{ | ||
sflowExtractFvs (kfvFieldsValues(tuple), sflowStatus, rate); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
orchagent/sfloworch.cpp
Outdated
admin_state = sflowInfo->second.admin_state; | ||
} | ||
|
||
sflowExtractFvs(kfvFieldsValues(tuple), admin_state, rate); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
retest this please |
* Change admin_state from enable/disable to up/down to match SONiC YANG. Signed-off-by: Garrick He <garrick_he@dell.com>
retest this please |
retest this please |
retest this please |
3 similar comments
retest this please |
retest this please |
retest this please |
sflowHandleSessionAll(enable); | ||
} | ||
sflowHandleSessionLocal(enable); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
- 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).
- 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.
- 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); |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
@dgsudharsan , @padmanarayana, can you please check? |
…ng() (sonic-net#1012) Fix typo and enable test for tablesWithOutYang() Signed-off-by: Praveen Chaudhary pchaudhary@linkedin.com
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