Skip to content

Commit a464729

Browse files
[portsorch] process only updated APP_DB fields when port is already created (#3025)
* [portsorch] process only updated APP_DB fields when port is already created What I did Fixing an issue when setting some port attribute in APPL_DB triggers serdes parameters to be re-programmed with port toggling. Made portsorch to handle only those attributes that were pushed to APPL_DB, so that serdes programming happens only by xcvrd's request to do so.
1 parent 91bacca commit a464729

File tree

4 files changed

+86
-18
lines changed

4 files changed

+86
-18
lines changed

orchagent/port/porthlpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,7 @@ bool PortHelper::parsePortConfig(PortConfig &port) const
10011001
}
10021002
}
10031003

1004-
return this->validatePortConfig(port);
1004+
return true;
10051005
}
10061006

10071007
bool PortHelper::validatePortConfig(PortConfig &port) const

orchagent/port/porthlpr.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class PortHelper final
2828
std::string getAdminStatusStr(const PortConfig &port) const;
2929

3030
bool parsePortConfig(PortConfig &port) const;
31+
bool validatePortConfig(PortConfig &port) const;
3132

3233
private:
3334
std::string getFieldValueStr(const PortConfig &port, const std::string &field) const;
@@ -52,6 +53,4 @@ class PortHelper final
5253
bool parsePortRole(PortConfig &port, const std::string &field, const std::string &value) const;
5354
bool parsePortAdminStatus(PortConfig &port, const std::string &field, const std::string &value) const;
5455
bool parsePortDescription(PortConfig &port, const std::string &field, const std::string &value) const;
55-
56-
bool validatePortConfig(PortConfig &port) const;
5756
};

orchagent/portsorch.cpp

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3572,28 +3572,59 @@ void PortsOrch::doPortTask(Consumer &consumer)
35723572

35733573
if (op == SET_COMMAND)
35743574
{
3575-
auto &fvMap = m_portConfigMap[key];
3576-
3577-
for (const auto &cit : kfvFieldsValues(keyOpFieldsValues))
3575+
auto parsePortFvs = [&](auto& fvMap) -> bool
35783576
{
3579-
auto fieldName = fvField(cit);
3580-
auto fieldValue = fvValue(cit);
3577+
for (const auto &cit : kfvFieldsValues(keyOpFieldsValues))
3578+
{
3579+
auto fieldName = fvField(cit);
3580+
auto fieldValue = fvValue(cit);
35813581

3582-
SWSS_LOG_INFO("FIELD: %s, VALUE: %s", fieldName.c_str(), fieldValue.c_str());
3582+
SWSS_LOG_INFO("FIELD: %s, VALUE: %s", fieldName.c_str(), fieldValue.c_str());
35833583

3584-
fvMap[fieldName] = fieldValue;
3585-
}
3584+
fvMap[fieldName] = fieldValue;
3585+
}
35863586

3587-
pCfg.fieldValueMap = fvMap;
3587+
pCfg.fieldValueMap = fvMap;
3588+
3589+
if (!m_portHlpr.parsePortConfig(pCfg))
3590+
{
3591+
return false;
3592+
}
35883593

3589-
if (!m_portHlpr.parsePortConfig(pCfg))
3594+
return true;
3595+
};
3596+
3597+
if (m_portList.find(key) == m_portList.end())
35903598
{
3591-
it = taskMap.erase(it);
3592-
continue;
3599+
// Aggregate configuration while the port is not created.
3600+
auto &fvMap = m_portConfigMap[key];
3601+
3602+
if (!parsePortFvs(fvMap))
3603+
{
3604+
it = taskMap.erase(it);
3605+
continue;
3606+
}
3607+
3608+
if (!m_portHlpr.validatePortConfig(pCfg))
3609+
{
3610+
it = taskMap.erase(it);
3611+
continue;
3612+
}
3613+
3614+
/* Collect information about all received ports */
3615+
m_lanesAliasSpeedMap[pCfg.lanes.value] = pCfg;
35933616
}
3617+
else
3618+
{
3619+
// Port is already created, gather updated field-values.
3620+
std::unordered_map<std::string, std::string> fvMap;
35943621

3595-
/* Collect information about all received ports */
3596-
m_lanesAliasSpeedMap[pCfg.lanes.value] = pCfg;
3622+
if (!parsePortFvs(fvMap))
3623+
{
3624+
it = taskMap.erase(it);
3625+
continue;
3626+
}
3627+
}
35973628

35983629
// TODO:
35993630
// Fix the issue below
@@ -3709,6 +3740,9 @@ void PortsOrch::doPortTask(Consumer &consumer)
37093740
PortSerdesAttrMap_t serdes_attr;
37103741
getPortSerdesAttr(serdes_attr, pCfg);
37113742

3743+
// Saved configured admin status
3744+
bool admin_status = p.m_admin_state_up;
3745+
37123746
if (pCfg.autoneg.is_set)
37133747
{
37143748
if (!p.m_an_cfg || p.m_autoneg != pCfg.autoneg.value)
@@ -4269,6 +4303,13 @@ void PortsOrch::doPortTask(Consumer &consumer)
42694303
/* create host_tx_ready field in state-db */
42704304
initHostTxReadyState(p);
42714305

4306+
// Restore admin status if the port was brought down
4307+
if (admin_status != p.m_admin_state_up)
4308+
{
4309+
pCfg.admin_status.is_set = true;
4310+
pCfg.admin_status.value = admin_status;
4311+
}
4312+
42724313
/* Last step set port admin status */
42734314
if (pCfg.admin_status.is_set)
42744315
{

tests/mock_tests/portsorch_ut.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,6 @@ namespace portsorch_test
926926
std::deque<KeyOpFieldsValuesTuple> kfvSerdes = {{
927927
"Ethernet0",
928928
SET_COMMAND, {
929-
{ "admin_status", "up" },
930929
{ "idriver" , "0x6,0x6,0x6,0x6" }
931930
}
932931
}};
@@ -953,6 +952,35 @@ namespace portsorch_test
953952
ASSERT_EQ(_sai_set_admin_state_down_count, ++current_sai_api_call_count);
954953
ASSERT_EQ(_sai_set_admin_state_up_count, current_sai_api_call_count);
955954

955+
// Configure non-serdes attribute that does not trigger admin state change
956+
std::deque<KeyOpFieldsValuesTuple> kfvMtu = {{
957+
"Ethernet0",
958+
SET_COMMAND, {
959+
{ "mtu", "1234" },
960+
}
961+
}};
962+
963+
// Refill consumer
964+
consumer->addToSync(kfvMtu);
965+
966+
_hook_sai_port_api();
967+
current_sai_api_call_count = _sai_set_admin_state_down_count;
968+
969+
// Apply configuration
970+
static_cast<Orch*>(gPortsOrch)->doTask();
971+
972+
_unhook_sai_port_api();
973+
974+
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", p));
975+
ASSERT_TRUE(p.m_admin_state_up);
976+
977+
// Verify mtu is set
978+
ASSERT_EQ(p.m_mtu, 1234);
979+
980+
// Verify no admin-disable then admin-enable
981+
ASSERT_EQ(_sai_set_admin_state_down_count, current_sai_api_call_count);
982+
ASSERT_EQ(_sai_set_admin_state_up_count, current_sai_api_call_count);
983+
956984
// Dump pending tasks
957985
std::vector<std::string> taskList;
958986
gPortsOrch->dumpPendingTasks(taskList);

0 commit comments

Comments
 (0)