Skip to content

Commit b91d8ba

Browse files
authored
[swss] L2 Forwarding Enhancements (sonic-net#1716)
* L2 Forwarding Enhancements
1 parent 797dab4 commit b91d8ba

File tree

4 files changed

+77
-48
lines changed

4 files changed

+77
-48
lines changed

orchagent/fdborch.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -874,10 +874,6 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
874874
{
875875
if (op == "ALL")
876876
{
877-
/*
878-
* so far only support flush all the FDB entries
879-
* flush per port and flush per vlan will be added later.
880-
*/
881877
status = sai_fdb_api->flush_fdb_entries(gSwitchId, 0, NULL);
882878
if (status != SAI_STATUS_SUCCESS)
883879
{
@@ -1080,7 +1076,9 @@ void FdbOrch::updatePortOperState(const PortOperStateUpdate& update)
10801076

10811077
// Get BVID of each VLAN that this port is a member of
10821078
// and call notifyObserversFDBFlush
1083-
for (const auto& vlan_member: p.m_vlan_members)
1079+
vlan_members_t vlan_members;
1080+
m_portsOrch->getPortVlanMembers(p, vlan_members);
1081+
for (const auto& vlan_member: vlan_members)
10841082
{
10851083
swss::Port vlan;
10861084
string vlan_alias = VLAN_PREFIX + to_string(vlan_member.first);

orchagent/port.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class Port
121121
VlanInfo m_vlan_info;
122122
MacAddress m_mac;
123123
sai_object_id_t m_bridge_port_id = 0; // TODO: port could have multiple bridge port IDs
124+
sai_object_id_t m_bridge_port_admin_state = 0; // TODO: port could have multiple bridge port IDs
124125
sai_vlan_id_t m_port_vlan_id = DEFAULT_PORT_VLAN_ID; // Port VLAN ID
125126
sai_object_id_t m_rif_id = 0;
126127
sai_object_id_t m_vr_id = 0;
@@ -130,7 +131,6 @@ class Port
130131
sai_object_id_t m_tunnel_id = 0;
131132
sai_object_id_t m_ingress_acl_table_group_id = 0;
132133
sai_object_id_t m_egress_acl_table_group_id = 0;
133-
vlan_members_t m_vlan_members;
134134
sai_object_id_t m_parent_port_id = 0;
135135
uint32_t m_dependency_bitmap = 0;
136136
sai_port_oper_status_t m_oper_status = SAI_PORT_OPER_STATUS_UNKNOWN;

orchagent/portsorch.cpp

+66-42
Original file line numberDiff line numberDiff line change
@@ -745,35 +745,15 @@ bool PortsOrch::getPort(sai_object_id_t id, Port &port)
745745
{
746746
SWSS_LOG_ENTER();
747747

748-
for (const auto& portIter: m_portList)
748+
auto itr = saiOidToAlias.find(id);
749+
if (itr == saiOidToAlias.end())
749750
{
750-
switch (portIter.second.m_type)
751-
{
752-
case Port::PHY:
753-
case Port::SYSTEM:
754-
if(portIter.second.m_port_id == id)
755-
{
756-
port = portIter.second;
757-
return true;
758-
}
759-
break;
760-
case Port::LAG:
761-
if(portIter.second.m_lag_id == id)
762-
{
763-
port = portIter.second;
764-
return true;
765-
}
766-
break;
767-
case Port::VLAN:
768-
if (portIter.second.m_vlan_info.vlan_oid == id)
769-
{
770-
port = portIter.second;
771-
return true;
772-
}
773-
break;
774-
default:
775-
continue;
776-
}
751+
return false;
752+
}
753+
else
754+
{
755+
getPort(itr->second, port);
756+
return true;
777757
}
778758

779759
return false;
@@ -813,13 +793,15 @@ bool PortsOrch::getPortByBridgePortId(sai_object_id_t bridge_port_id, Port &port
813793
{
814794
SWSS_LOG_ENTER();
815795

816-
for (auto &it: m_portList)
796+
auto itr = saiOidToAlias.find(bridge_port_id);
797+
if (itr == saiOidToAlias.end())
817798
{
818-
if (it.second.m_bridge_port_id == bridge_port_id)
819-
{
820-
port = it.second;
821-
return true;
822-
}
799+
return false;
800+
}
801+
else
802+
{
803+
getPort(itr->second, port);
804+
return true;
823805
}
824806

825807
return false;
@@ -2358,6 +2340,7 @@ bool PortsOrch::initPort(const string &alias, const string &role, const int inde
23582340

23592341
/* Add port to port list */
23602342
m_portList[alias] = p;
2343+
saiOidToAlias[id] = alias;
23612344
m_port_ref_count[alias] = 0;
23622345
m_portOidToIndex[id] = index;
23632346

@@ -3558,7 +3541,7 @@ void PortsOrch::doVlanMemberTask(Consumer &consumer)
35583541
{
35593542
if (removeVlanMember(vlan, port))
35603543
{
3561-
if (port.m_vlan_members.empty())
3544+
if (m_portVlanMember[port.m_alias].empty())
35623545
{
35633546
removeBridgePort(port);
35643547
}
@@ -3661,7 +3644,6 @@ void PortsOrch::doLagTask(Consumer &consumer)
36613644
switch_id = -1;
36623645
}
36633646

3664-
// Create a new LAG when the new alias comes
36653647
if (m_portList.find(alias) == m_portList.end())
36663648
{
36673649
if (!addLag(alias, lag_id, switch_id))
@@ -4331,6 +4313,7 @@ bool PortsOrch::addBridgePort(Port &port)
43314313
return false;
43324314
}
43334315
m_portList[port.m_alias] = port;
4316+
saiOidToAlias[port.m_bridge_port_id] = port.m_alias;
43344317
SWSS_LOG_NOTICE("Add bridge port %s to default 1Q bridge", port.m_alias.c_str());
43354318

43364319
PortUpdate update = { port, true };
@@ -4387,6 +4370,7 @@ bool PortsOrch::removeBridgePort(Port &port)
43874370
return parseHandleSaiStatusFailure(handle_status);
43884371
}
43894372
}
4373+
saiOidToAlias.erase(port.m_bridge_port_id);
43904374
port.m_bridge_port_id = SAI_NULL_OBJECT_ID;
43914375

43924376
/* Remove bridge port */
@@ -4460,7 +4444,7 @@ bool PortsOrch::addVlan(string vlan_alias)
44604444
}
44614445
}
44624446

4463-
SWSS_LOG_NOTICE("Create an empty VLAN %s vid:%hu", vlan_alias.c_str(), vlan_id);
4447+
SWSS_LOG_NOTICE("Create an empty VLAN %s vid:%hu vlan_oid:%" PRIx64, vlan_alias.c_str(), vlan_id, vlan_oid);
44644448

44654449
Port vlan(vlan_alias, Port::VLAN);
44664450
vlan.m_vlan_info.vlan_oid = vlan_oid;
@@ -4470,6 +4454,7 @@ bool PortsOrch::addVlan(string vlan_alias)
44704454
vlan.m_members = set<string>();
44714455
m_portList[vlan_alias] = vlan;
44724456
m_port_ref_count[vlan_alias] = 0;
4457+
saiOidToAlias[vlan_oid] = vlan_alias;
44734458

44744459
return true;
44754460
}
@@ -4478,6 +4463,13 @@ bool PortsOrch::removeVlan(Port vlan)
44784463
{
44794464
SWSS_LOG_ENTER();
44804465

4466+
/* If there are still fdb entries associated with the VLAN,
4467+
return false for retry */
4468+
if (vlan.m_fdb_count > 0)
4469+
{
4470+
SWSS_LOG_NOTICE("VLAN %s still has assiciated FDB entries", vlan.m_alias.c_str());
4471+
return false;
4472+
}
44814473
if (m_port_ref_count[vlan.m_alias] > 0)
44824474
{
44834475
SWSS_LOG_ERROR("Failed to remove ref count %d VLAN %s",
@@ -4525,6 +4517,7 @@ bool PortsOrch::removeVlan(Port vlan)
45254517
SWSS_LOG_NOTICE("Remove VLAN %s vid:%hu", vlan.m_alias.c_str(),
45264518
vlan.m_vlan_info.vlan_id);
45274519

4520+
saiOidToAlias.erase(vlan.m_vlan_info.vlan_oid);
45284521
m_portList.erase(vlan.m_alias);
45294522
m_port_ref_count.erase(vlan.m_alias);
45304523

@@ -4614,7 +4607,7 @@ bool PortsOrch::addVlanMember(Port &vlan, Port &port, string &tagging_mode, stri
46144607

46154608
/* a physical port may join multiple vlans */
46164609
VlanMemberEntry vme = {vlan_member_id, sai_tagging_mode};
4617-
port.m_vlan_members[vlan.m_vlan_info.vlan_id] = vme;
4610+
m_portVlanMember[port.m_alias][vlan.m_vlan_info.vlan_id] = vme;
46184611
m_portList[port.m_alias] = port;
46194612
vlan.m_members.insert(port.m_alias);
46204613
m_portList[vlan.m_alias] = vlan;
@@ -4625,6 +4618,12 @@ bool PortsOrch::addVlanMember(Port &vlan, Port &port, string &tagging_mode, stri
46254618
return true;
46264619
}
46274620

4621+
bool PortsOrch::getPortVlanMembers(Port &port, vlan_members_t &vlan_members)
4622+
{
4623+
vlan_members = m_portVlanMember[port.m_alias];
4624+
return true;
4625+
}
4626+
46284627
bool PortsOrch::addVlanFloodGroups(Port &vlan, Port &port, string end_point_ip)
46294628
{
46304629
SWSS_LOG_ENTER();
@@ -4844,10 +4843,10 @@ bool PortsOrch::removeVlanMember(Port &vlan, Port &port, string end_point_ip)
48444843
}
48454844
sai_object_id_t vlan_member_id;
48464845
sai_vlan_tagging_mode_t sai_tagging_mode;
4847-
auto vlan_member = port.m_vlan_members.find(vlan.m_vlan_info.vlan_id);
4846+
auto vlan_member = m_portVlanMember[port.m_alias].find(vlan.m_vlan_info.vlan_id);
48484847

48494848
/* Assert the port belongs to this VLAN */
4850-
assert (vlan_member != port.m_vlan_members.end());
4849+
assert (vlan_member != m_portVlanMember[port.m_alias].end());
48514850
sai_tagging_mode = vlan_member->second.vlan_mode;
48524851
vlan_member_id = vlan_member->second.vlan_member_id;
48534852

@@ -4862,7 +4861,11 @@ bool PortsOrch::removeVlanMember(Port &vlan, Port &port, string end_point_ip)
48624861
return parseHandleSaiStatusFailure(handle_status);
48634862
}
48644863
}
4865-
port.m_vlan_members.erase(vlan_member);
4864+
m_portVlanMember[port.m_alias].erase(vlan_member);
4865+
if (m_portVlanMember[port.m_alias].empty())
4866+
{
4867+
m_portVlanMember.erase(port.m_alias);
4868+
}
48664869
SWSS_LOG_NOTICE("Remove member %s from VLAN %s lid:%hx vmid:%" PRIx64,
48674870
port.m_alias.c_str(), vlan.m_alias.c_str(), vlan.m_vlan_info.vlan_id, vlan_member_id);
48684871

@@ -4905,6 +4908,20 @@ bool PortsOrch::addLag(string lag_alias, uint32_t spa_id, int32_t switch_id)
49054908
{
49064909
SWSS_LOG_ENTER();
49074910

4911+
auto lagport = m_portList.find(lag_alias);
4912+
if (lagport != m_portList.end())
4913+
{
4914+
/* The deletion of bridgeport attached to the lag may still be
4915+
* pending due to fdb entries still present on the lag. Wait
4916+
* until the cleanup is done.
4917+
*/
4918+
if (m_portList[lag_alias].m_bridge_port_id != SAI_NULL_OBJECT_ID)
4919+
{
4920+
return false;
4921+
}
4922+
return true;
4923+
}
4924+
49084925
vector<sai_attribute_t> lag_attrs;
49094926
string system_lag_alias = lag_alias;
49104927

@@ -4956,6 +4973,7 @@ bool PortsOrch::addLag(string lag_alias, uint32_t spa_id, int32_t switch_id)
49564973
lag.m_members = set<string>();
49574974
m_portList[lag_alias] = lag;
49584975
m_port_ref_count[lag_alias] = 0;
4976+
saiOidToAlias[lag_id] = lag_alias;
49594977

49604978
PortUpdate update = { lag, true };
49614979
notify(SUBJECT_TYPE_PORT_CHANGE, static_cast<void *>(&update));
@@ -5004,12 +5022,17 @@ bool PortsOrch::removeLag(Port lag)
50045022
SWSS_LOG_ERROR("Failed to remove non-empty LAG %s", lag.m_alias.c_str());
50055023
return false;
50065024
}
5007-
if (lag.m_vlan_members.size() > 0)
5025+
if (m_portVlanMember[lag.m_alias].size() > 0)
50085026
{
50095027
SWSS_LOG_ERROR("Failed to remove LAG %s, it is still in VLAN", lag.m_alias.c_str());
50105028
return false;
50115029
}
50125030

5031+
if (lag.m_bridge_port_id != SAI_NULL_OBJECT_ID)
5032+
{
5033+
return false;
5034+
}
5035+
50135036
sai_status_t status = sai_lag_api->remove_lag(lag.m_lag_id);
50145037
if (status != SAI_STATUS_SUCCESS)
50155038
{
@@ -5023,6 +5046,7 @@ bool PortsOrch::removeLag(Port lag)
50235046

50245047
SWSS_LOG_NOTICE("Remove LAG %s lid:%" PRIx64, lag.m_alias.c_str(), lag.m_lag_id);
50255048

5049+
saiOidToAlias.erase(lag.m_lag_id);
50265050
m_portList.erase(lag.m_alias);
50275051
m_port_ref_count.erase(lag.m_alias);
50285052

orchagent/portsorch.h

+7
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class PortsOrch : public Orch, public Subject
154154
string m_inbandPortName = "";
155155
bool isInbandPort(const string &alias);
156156
bool setVoqInbandIntf(string &alias, string &type);
157+
bool getPortVlanMembers(Port &port, vlan_members_t &vlan_members);
157158

158159
bool getRecircPort(Port &p, string role);
159160

@@ -226,6 +227,12 @@ class PortsOrch : public Orch, public Subject
226227
map<set<int>, sai_object_id_t> m_portListLaneMap;
227228
map<set<int>, tuple<string, uint32_t, int, string, int, string>> m_lanesAliasSpeedMap;
228229
map<string, Port> m_portList;
230+
map<string, vlan_members_t> m_portVlanMember;
231+
/* mapping from SAI object ID to Name for faster
232+
* retrieval of Port/VLAN from object ID for events
233+
* coming from SAI
234+
*/
235+
unordered_map<sai_object_id_t, string> saiOidToAlias;
229236
unordered_map<sai_object_id_t, int> m_portOidToIndex;
230237
map<string, uint32_t> m_port_ref_count;
231238
unordered_set<string> m_pendingPortSet;

0 commit comments

Comments
 (0)