Skip to content

Commit baa302e

Browse files
authored
Do not allow to add port to .1Q bridge while router port deletion is not completed (sonic-net#2669)
* Do not set port to be a bridge port while it is still a router port
1 parent f66abed commit baa302e

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

orchagent/portsorch.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -4886,6 +4886,12 @@ bool PortsOrch::addBridgePort(Port &port)
48864886
return true;
48874887
}
48884888

4889+
if (port.m_rif_id != 0)
4890+
{
4891+
SWSS_LOG_NOTICE("Cannot create bridge port, interface %s is a router port", port.m_alias.c_str());
4892+
return false;
4893+
}
4894+
48894895
sai_attribute_t attr;
48904896
vector<sai_attribute_t> attrs;
48914897

tests/mock_tests/mock_sai_bridge.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Define classes and functions to mock SAI bridge functions.
2+
#pragma once
3+
4+
#include <gmock/gmock.h>
5+
6+
extern "C"
7+
{
8+
#include "sai.h"
9+
}
10+
11+
// Mock class including mock functions mapping to SAI bridge functions.
12+
class MockSaiBridge
13+
{
14+
public:
15+
MOCK_METHOD4(create_bridge_port, sai_status_t(sai_object_id_t *bridge_port_id,
16+
sai_object_id_t switch_id,
17+
uint32_t attr_count,
18+
const sai_attribute_t *attr_list));
19+
};
20+
21+
// Note that before mock functions below are used, mock_sai_bridge must be
22+
// initialized to point to an instance of MockSaiBridge.
23+
MockSaiBridge *mock_sai_bridge;
24+
25+
sai_status_t mock_create_bridge_port(sai_object_id_t *bridge_port_id,
26+
sai_object_id_t switch_id,
27+
uint32_t attr_count,
28+
const sai_attribute_t *attr_list)
29+
{
30+
return mock_sai_bridge->create_bridge_port(bridge_port_id, switch_id, attr_count, attr_list);
31+
}
32+
33+
34+

tests/mock_tests/portsorch_ut.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "mock_orchagent_main.h"
88
#include "mock_table.h"
99
#include "notifier.h"
10+
#include "mock_sai_bridge.h"
1011
#define private public
1112
#include "pfcactionhandler.h"
1213
#include <sys/mman.h>
@@ -15,6 +16,8 @@
1516
#include <sstream>
1617

1718
extern redisReply *mockReply;
19+
using ::testing::_;
20+
using ::testing::StrictMock;
1821

1922
namespace portsorch_test
2023
{
@@ -151,6 +154,21 @@ namespace portsorch_test
151154
sai_queue_api = pold_sai_queue_api;
152155
}
153156

157+
sai_bridge_api_t ut_sai_bridge_api;
158+
sai_bridge_api_t *org_sai_bridge_api;
159+
160+
void _hook_sai_bridge_api()
161+
{
162+
ut_sai_bridge_api = *sai_bridge_api;
163+
org_sai_bridge_api = sai_bridge_api;
164+
sai_bridge_api = &ut_sai_bridge_api;
165+
}
166+
167+
void _unhook_sai_bridge_api()
168+
{
169+
sai_bridge_api = org_sai_bridge_api;
170+
}
171+
154172
struct PortsOrchTest : public ::testing::Test
155173
{
156174
shared_ptr<swss::DBConnector> m_app_db;
@@ -345,6 +363,48 @@ namespace portsorch_test
345363
ASSERT_FALSE(gPortsOrch->getPort(port.m_port_id, port));
346364
}
347365

366+
/**
367+
* Test case: PortsOrch::addBridgePort() does not add router port to .1Q bridge
368+
*/
369+
TEST_F(PortsOrchTest, addBridgePortOnRouterPort)
370+
{
371+
_hook_sai_bridge_api();
372+
373+
StrictMock<MockSaiBridge> mock_sai_bridge_;
374+
mock_sai_bridge = &mock_sai_bridge_;
375+
sai_bridge_api->create_bridge_port = mock_create_bridge_port;
376+
377+
Table portTable = Table(m_app_db.get(), APP_PORT_TABLE_NAME);
378+
379+
// Get SAI default ports to populate DB
380+
auto ports = ut_helper::getInitialSaiPorts();
381+
382+
// Populate port table with SAI ports
383+
for (const auto &it : ports)
384+
{
385+
portTable.set(it.first, it.second);
386+
}
387+
388+
// Set PortConfigDone, PortInitDone
389+
portTable.set("PortConfigDone", { { "count", to_string(ports.size()) } });
390+
portTable.set("PortInitDone", { { "lanes", "0" } });
391+
392+
// refill consumer
393+
gPortsOrch->addExistingData(&portTable);
394+
// Apply configuration : create ports
395+
static_cast<Orch *>(gPortsOrch)->doTask();
396+
397+
// Get first port and set its rif id to simulate it is router port
398+
Port port;
399+
gPortsOrch->getPort("Ethernet0", port);
400+
port.m_rif_id = 1;
401+
402+
ASSERT_FALSE(gPortsOrch->addBridgePort(port));
403+
EXPECT_CALL(mock_sai_bridge_, create_bridge_port(_, _, _, _)).Times(0);
404+
405+
_unhook_sai_bridge_api();
406+
}
407+
348408
TEST_F(PortsOrchTest, PortSupportedFecModes)
349409
{
350410
_hook_sai_port_api();

0 commit comments

Comments
 (0)