Skip to content

Commit 6fe0afd

Browse files
stepanblyschakyxieca
authored andcommitted
[portsorch] remove port OID from saiOidToAlias map on port deletion (#2483)
- What I did I fixed an issue that on port deletion (port breakout scenario), the port OID is not removed from saiOidToAlias map, resulting in getPort returns true when querying non-existing port OID but the Port structure is not filled with correct values. Also lowered the log level on receiving non-existing port operational status update - Why I did it To fix errors in the log during breakout: Oct 4 13:15:45.654396 r-bulldog-04 NOTICE swss#orchagent: :- updatePortOperStatus: Port oper state set from unknown to down Oct 4 13:15:45.654773 r-bulldog-04 ERR swss#orchagent: :- set: switch id oid:0x0 doesn't exist Oct 4 13:15:45.654773 r-bulldog-04 WARNING swss#orchagent: :- setHostIntfsOperStatus: Failed to set operation status DOWN to host interface Oct 4 13:15:45.654773 r-bulldog-04 ERR swss#orchagent: :- updatePortOperStatus: Failed to set host interface operational status down Oct 4 13:15:45.654773 r-bulldog-04 WARNING swss#orchagent: :- flushFDBEntries: Couldn't flush FDB. Bridge port OID: 0x0 bvid:0, - How I verified it Run UT, run manual port breakout tests. Signed-off-by: Stepan Blyschak <[email protected]>
1 parent 7290d66 commit 6fe0afd

File tree

2 files changed

+63
-19
lines changed

2 files changed

+63
-19
lines changed

orchagent/portsorch.cpp

+20-16
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,10 @@ bool PortsOrch::getPort(sai_object_id_t id, Port &port)
824824
}
825825
else
826826
{
827-
getPort(itr->second, port);
827+
if (!getPort(itr->second, port))
828+
{
829+
SWSS_LOG_THROW("Inconsistent saiOidToAlias map and m_portList map: oid=%" PRIx64, id);
830+
}
828831
return true;
829832
}
830833

@@ -1065,9 +1068,9 @@ void PortsOrch::getCpuPort(Port &port)
10651068
port = m_cpuPort;
10661069
}
10671070

1068-
/*
1069-
* Create host_tx_ready field in PORT_TABLE of STATE-DB
1070-
* and set the field to false by default for the
1071+
/*
1072+
* Create host_tx_ready field in PORT_TABLE of STATE-DB
1073+
* and set the field to false by default for the
10711074
* front<Ethernet> port.
10721075
*/
10731076
void PortsOrch::initHostTxReadyState(Port &port)
@@ -1092,7 +1095,7 @@ void PortsOrch::initHostTxReadyState(Port &port)
10921095
if (hostTxReady.empty())
10931096
{
10941097
m_portStateTable.hset(port.m_alias, "host_tx_ready", "false");
1095-
SWSS_LOG_INFO("initalize hostTxReady %s with status %s",
1098+
SWSS_LOG_INFO("initalize hostTxReady %s with status %s",
10961099
port.m_alias.c_str(), hostTxReady.c_str());
10971100
}
10981101
}
@@ -1106,13 +1109,13 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state)
11061109
attr.value.booldata = state;
11071110

11081111
/* Update the host_tx_ready to false before setting admin_state, when admin state is false */
1109-
if (!state)
1112+
if (!state)
11101113
{
11111114
m_portStateTable.hset(port.m_alias, "host_tx_ready", "false");
11121115
SWSS_LOG_INFO("Set admin status DOWN host_tx_ready to false to port pid:%" PRIx64,
11131116
port.m_port_id);
11141117
}
1115-
1118+
11161119
sai_status_t status = sai_port_api->set_port_attribute(port.m_port_id, &attr);
11171120
if (status != SAI_STATUS_SUCCESS)
11181121
{
@@ -1131,14 +1134,14 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state)
11311134
{
11321135
m_portStateTable.hset(port.m_alias, "host_tx_ready", "false");
11331136
}
1134-
1137+
11351138
/* Update the state table for host_tx_ready*/
11361139
if (state && (gbstatus == true) && (status == SAI_STATUS_SUCCESS) )
11371140
{
11381141
m_portStateTable.hset(port.m_alias, "host_tx_ready", "true");
11391142
SWSS_LOG_INFO("Set admin status UP host_tx_ready to true to port pid:%" PRIx64,
11401143
port.m_port_id);
1141-
}
1144+
}
11421145

11431146
return true;
11441147
}
@@ -1372,9 +1375,9 @@ bool PortsOrch::setPortPfcWatchdogStatus(sai_object_id_t portId, uint8_t pfcwd_b
13721375
SWSS_LOG_ERROR("Failed to get port object for port id 0x%" PRIx64, portId);
13731376
return false;
13741377
}
1375-
1378+
13761379
p.m_pfcwd_sw_bitmask = pfcwd_bitmask;
1377-
1380+
13781381
m_portList[p.m_alias] = p;
13791382

13801383
SWSS_LOG_INFO("Set PFC watchdog port id=0x%" PRIx64 ", bitmast=0x%x", portId, pfcwd_bitmask);
@@ -1392,9 +1395,9 @@ bool PortsOrch::getPortPfcWatchdogStatus(sai_object_id_t portId, uint8_t *pfcwd_
13921395
SWSS_LOG_ERROR("Failed to get port object for port id 0x%" PRIx64, portId);
13931396
return false;
13941397
}
1395-
1398+
13961399
*pfcwd_bitmask = p.m_pfcwd_sw_bitmask;
1397-
1400+
13981401
return true;
13991402
}
14001403

@@ -3745,10 +3748,10 @@ void PortsOrch::doPortTask(Consumer &consumer)
37453748
continue;
37463749
}
37473750
}
3748-
3751+
37493752
/* create host_tx_ready field in state-db */
37503753
initHostTxReadyState(p);
3751-
3754+
37523755
/* Last step set port admin status */
37533756
if (!admin_status.empty() && (p.m_admin_state_up != (admin_status == "up")))
37543757
{
@@ -3826,6 +3829,7 @@ void PortsOrch::doPortTask(Consumer &consumer)
38263829

38273830
/* Delete port from port list */
38283831
m_portList.erase(alias);
3832+
saiOidToAlias.erase(port_id);
38293833
}
38303834
else
38313835
{
@@ -6434,7 +6438,7 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
64346438

64356439
if (!getPort(id, port))
64366440
{
6437-
SWSS_LOG_ERROR("Failed to get port object for port id 0x%" PRIx64, id);
6441+
SWSS_LOG_NOTICE("Got port state change for port id 0x%" PRIx64 " which does not exist, possibly outdated event", id);
64386442
continue;
64396443
}
64406444

tests/mock_tests/portsorch_ut.cpp

+43-3
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,16 @@ namespace portsorch_test
8282
{
8383
sai_port_api = pold_sai_port_api;
8484
}
85-
85+
8686
sai_queue_api_t ut_sai_queue_api;
8787
sai_queue_api_t *pold_sai_queue_api;
8888
int _sai_set_queue_attr_count = 0;
89-
89+
9090
sai_status_t _ut_stub_sai_set_queue_attribute(sai_object_id_t queue_id, const sai_attribute_t *attr)
9191
{
9292
if(attr->id == SAI_QUEUE_ATTR_PFC_DLR_INIT)
9393
{
94-
if(attr->value.booldata == true)
94+
if(attr->value.booldata == true)
9595
{
9696
_sai_set_queue_attr_count++;
9797
}
@@ -270,6 +270,46 @@ namespace portsorch_test
270270

271271
};
272272

273+
/**
274+
* Test that verifies PortsOrch::getPort() on a port that has been deleted
275+
*/
276+
TEST_F(PortsOrchTest, GetPortTest)
277+
{
278+
Table portTable = Table(m_app_db.get(), APP_PORT_TABLE_NAME);
279+
std::deque<KeyOpFieldsValuesTuple> entries;
280+
281+
// Get SAI default ports to populate DB
282+
auto ports = ut_helper::getInitialSaiPorts();
283+
284+
for (const auto &it : ports)
285+
{
286+
portTable.set(it.first, it.second);
287+
}
288+
289+
// Set PortConfigDone
290+
portTable.set("PortConfigDone", { { "count", to_string(ports.size()) } });
291+
292+
// refill consumer
293+
gPortsOrch->addExistingData(&portTable);
294+
295+
// Apply configuration :
296+
// create ports
297+
static_cast<Orch *>(gPortsOrch)->doTask();
298+
299+
Port port;
300+
ASSERT_TRUE(gPortsOrch->getPort("Ethernet0", port));
301+
ASSERT_NE(port.m_port_id, SAI_NULL_OBJECT_ID);
302+
303+
// Delete port
304+
entries.push_back({"Ethernet0", "DEL", {}});
305+
auto consumer = dynamic_cast<Consumer *>(gPortsOrch->getExecutor(APP_PORT_TABLE_NAME));
306+
consumer->addToSync(entries);
307+
static_cast<Orch *>(gPortsOrch)->doTask();
308+
entries.clear();
309+
310+
ASSERT_FALSE(gPortsOrch->getPort(port.m_port_id, port));
311+
}
312+
273313
TEST_F(PortsOrchTest, PortSupportedFecModes)
274314
{
275315
_hook_sai_port_api();

0 commit comments

Comments
 (0)