Skip to content

Commit

Permalink
PR1
Browse files Browse the repository at this point in the history
  • Loading branch information
dr412113 committed Apr 5, 2021
1 parent 872b5cb commit 047841e
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 70 deletions.
35 changes: 27 additions & 8 deletions orchagent/fdborch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ void FdbOrch::update(sai_fdb_event_t type,
{
update.port.m_fdb_count--;
m_portsOrch->setPort(update.port.m_alias, update.port);

// this is not posted in last PR but its present in gerrit
if ((update.port.m_fdb_count == 0) && (update.port.m_vlan_members.empty()))
{
m_portsOrch->removeBridgePort(update.port);
}
}
if (!vlan.m_alias.empty())
{
Expand Down Expand Up @@ -686,16 +692,15 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
std::string data;
std::vector<swss::FieldValueTuple> values;

Port vlan;
Port port;

consumer.pop(op, data, values);

if (&consumer == m_flushNotificationsConsumer)
{
if (op == "ALL")
{
/*
* so far only support flush all the FDB entries
* flush per port and flush per vlan will be added later.
*/
status = sai_fdb_api->flush_fdb_entries(gSwitchId, 0, NULL);
if (status != SAI_STATUS_SUCCESS)
{
Expand All @@ -706,14 +711,22 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
}
else if (op == "PORT")
{
/*place holder for flush port fdb*/
SWSS_LOG_ERROR("Received unsupported flush port fdb request");
if (!m_portsOrch->getPort(data, port))
{
SWSS_LOG_ERROR("could not locate port from data %s", data.c_str());
return;
}
flushFDBEntries(port.m_bridge_port_id, SAI_NULL_OBJECT_ID);
return;
}
else if (op == "VLAN")
{
/*place holder for flush vlan fdb*/
SWSS_LOG_ERROR("Received unsupported flush vlan fdb request");
if (!m_portsOrch->getPort(data, vlan))
{
SWSS_LOG_ERROR("could not locate vlan from data %s", data.c_str());
return;
}
flushFDBEntries(SAI_NULL_OBJECT_ID, vlan.m_vlan_info.vlan_oid);
return;
}
else
Expand All @@ -726,6 +739,12 @@ void FdbOrch::doTask(NotificationConsumer& consumer)
{
uint32_t count;
sai_fdb_event_notification_data_t *fdbevent = nullptr;
extern void handle_fdb_event(_In_ const std::string &data);
/* The sai_redis fdb handling is moved here so that both
* reference count updates (sai_redis and portsOrch)
* happen in same context to avoid any mismatch.
*/
handle_fdb_event(data);

sai_deserialize_fdb_event_ntf(data, count, &fdbevent);

Expand Down
1 change: 1 addition & 0 deletions orchagent/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class Port
VlanInfo m_vlan_info;
MacAddress m_mac;
sai_object_id_t m_bridge_port_id = 0; // TODO: port could have multiple bridge port IDs
sai_object_id_t m_bridge_port_admin_state = 0; // TODO: port could have multiple bridge port IDs
sai_vlan_id_t m_port_vlan_id = DEFAULT_PORT_VLAN_ID; // Port VLAN ID
sai_object_id_t m_rif_id = 0;
sai_object_id_t m_vr_id = 0;
Expand Down
145 changes: 83 additions & 62 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,35 +611,12 @@ bool PortsOrch::getPort(sai_object_id_t id, Port &port)
{
SWSS_LOG_ENTER();

for (const auto& portIter: m_portList)
{
switch (portIter.second.m_type)
{
case Port::PHY:
case Port::SYSTEM:
if(portIter.second.m_port_id == id)
{
port = portIter.second;
return true;
}
break;
case Port::LAG:
if(portIter.second.m_lag_id == id)
{
port = portIter.second;
return true;
}
break;
case Port::VLAN:
if (portIter.second.m_vlan_info.vlan_oid == id)
{
port = portIter.second;
return true;
}
break;
default:
continue;
}
auto itr = portOidToName.find(id);
if (itr == portOidToName.end())
return false;
else {
getPort(itr->second, port);
return true;
}

return false;
Expand All @@ -661,15 +638,13 @@ bool PortsOrch::getPortByBridgePortId(sai_object_id_t bridge_port_id, Port &port
{
SWSS_LOG_ENTER();

for (auto &it: m_portList)
{
if (it.second.m_bridge_port_id == bridge_port_id)
{
port = it.second;
return true;
}
auto itr = portOidToName.find(bridge_port_id);
if (itr == portOidToName.end())
return false;
else {
getPort(itr->second, port);
return true;
}

return false;
}

Expand Down Expand Up @@ -2073,6 +2048,7 @@ bool PortsOrch::initPort(const string &alias, const int index, const set<int> &l

/* Add port to port list */
m_portList[alias] = p;
portOidToName[id] = alias;
m_port_ref_count[alias] = 0;
m_portOidToIndex[id] = index;

Expand Down Expand Up @@ -3034,24 +3010,24 @@ void PortsOrch::doVlanMemberTask(Consumer &consumer)
}
else if (op == DEL_COMMAND)
{
int ret = true;

if (vlan.m_members.find(port_alias) != vlan.m_members.end())
{
if (removeVlanMember(vlan, port))
{
if (port.m_vlan_members.empty())
{
removeBridgePort(port);
}
it = consumer.m_toSync.erase(it);
}
else
{
it++;
}
ret = removeVlanMember(vlan, port);
}
else
/* Cannot locate the VLAN */
if ((ret == true) && port.m_vlan_members.empty())
{
ret = removeBridgePort(port);
}
if (ret == true)
{
it = consumer.m_toSync.erase(it);
}
else
{
it++;
}
}
else
{
Expand Down Expand Up @@ -3131,8 +3107,7 @@ void PortsOrch::doLagTask(Consumer &consumer)
switch_id = -1;
}

// Create a new LAG when the new alias comes
if (m_portList.find(alias) == m_portList.end())
if (!addLag(alias))
{
if (!addLag(alias, lag_id, switch_id))
{
Expand Down Expand Up @@ -3671,6 +3646,36 @@ bool PortsOrch::addBridgePort(Port &port)

if (port.m_bridge_port_id != SAI_NULL_OBJECT_ID)
{
/* If the port is being added to the first VLAN,
* set bridge port admin status to UP.
* This can happen if the port was just removed from
* last VLAN and fdb flush is still in progress.
*/
if (port.m_vlan_members.empty())
{
if (port.m_fdb_count > 0)
{
return false;
}
sai_attribute_t attr;
attr.id = SAI_BRIDGE_PORT_ATTR_ADMIN_STATE;
attr.value.booldata = true;
sai_status_t status = sai_bridge_api->set_bridge_port_attribute(port.m_bridge_port_id, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to set bridge port %s admin status to UP, rv:%d",
port.m_alias.c_str(), status);
return false;
}
port.m_bridge_port_admin_state = true;
m_portList[port.m_alias] = port;
if (!setHostIntfsStripTag(port, SAI_HOSTIF_VLAN_TAG_KEEP))
{
SWSS_LOG_ERROR("Failed to set %s for hostif of port %s",
hostif_vlan_tag[SAI_HOSTIF_VLAN_TAG_KEEP], port.m_alias.c_str());
return false;
}
}
return true;
}

Expand Down Expand Up @@ -3748,13 +3753,16 @@ bool PortsOrch::addBridgePort(Port &port)
}
}

port.m_bridge_port_admin_state = true;

if (!setHostIntfsStripTag(port, SAI_HOSTIF_VLAN_TAG_KEEP))
{
SWSS_LOG_ERROR("Failed to set %s for hostif of port %s",
hostif_vlan_tag[SAI_HOSTIF_VLAN_TAG_KEEP], port.m_alias.c_str());
return false;
}
m_portList[port.m_alias] = port;
portOidToName[port.m_bridge_port_id] = port.m_alias;
SWSS_LOG_NOTICE("Add bridge port %s to default 1Q bridge", port.m_alias.c_str());

return true;
Expand All @@ -3768,13 +3776,7 @@ bool PortsOrch::removeBridgePort(Port &port)
{
return true;
}
/* Set bridge port admin status to DOWN */
sai_attribute_t attr;
attr.id = SAI_BRIDGE_PORT_ATTR_ADMIN_STATE;
attr.value.booldata = false;

sai_status_t status = sai_bridge_api->set_bridge_port_attribute(port.m_bridge_port_id, &attr);
if (status != SAI_STATUS_SUCCESS)
if (port.m_bridge_port_admin_state)
{
SWSS_LOG_ERROR("Failed to set bridge port %s admin status to DOWN, rv:%d",
port.m_alias.c_str(), status);
Expand All @@ -3797,7 +3799,7 @@ bool PortsOrch::removeBridgePort(Port &port)
SWSS_LOG_INFO("Flush FDB entries for port %s", port.m_alias.c_str());

/* Remove bridge port */
status = sai_bridge_api->remove_bridge_port(port.m_bridge_port_id);
sai_status_t status = sai_bridge_api->remove_bridge_port(port.m_bridge_port_id);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to remove bridge port %s from default 1Q bridge, rv:%d",
Expand All @@ -3808,6 +3810,7 @@ bool PortsOrch::removeBridgePort(Port &port)
return parseHandleSaiStatusFailure(handle_status);
}
}
portOidToName.erase(port.m_bridge_port_id);
port.m_bridge_port_id = SAI_NULL_OBJECT_ID;

SWSS_LOG_NOTICE("Remove bridge port %s from default 1Q bridge", port.m_alias.c_str());
Expand Down Expand Up @@ -3876,21 +3879,31 @@ bool PortsOrch::addVlan(string vlan_alias)
}
}

SWSS_LOG_NOTICE("Create an empty VLAN %s vid:%hu", vlan_alias.c_str(), vlan_id);
SWSS_LOG_NOTICE("Create an empty VLAN %s vid:%hu vlan_oid 0x%lx", vlan_alias.c_str(), vlan_id, vlan_oid);

Port vlan(vlan_alias, Port::VLAN);
vlan.m_vlan_info.vlan_oid = vlan_oid;
vlan.m_vlan_info.vlan_id = vlan_id;
vlan.m_members = set<string>();
m_portList[vlan_alias] = vlan;
m_port_ref_count[vlan_alias] = 0;
portOidToName[vlan_oid] = vlan_alias;

return true;
}

bool PortsOrch::removeVlan(Port vlan)
{
SWSS_LOG_ENTER();

/* If there are still fdb entries associated with the VLAN,
return false for retry */
if (vlan.m_fdb_count > 0)
{
SWSS_LOG_NOTICE("VLAN %s still has assiciated FDB entries", vlan.m_alias.c_str());
return false;
}

if (m_port_ref_count[vlan.m_alias] > 0)
{
SWSS_LOG_ERROR("Failed to remove ref count %d VLAN %s",
Expand Down Expand Up @@ -3931,6 +3944,7 @@ bool PortsOrch::removeVlan(Port vlan)
SWSS_LOG_NOTICE("Remove VLAN %s vid:%hu", vlan.m_alias.c_str(),
vlan.m_vlan_info.vlan_id);

portOidToName.erase(vlan.m_vlan_info.vlan_oid);
m_portList.erase(vlan.m_alias);
m_port_ref_count.erase(vlan.m_alias);

Expand Down Expand Up @@ -4127,6 +4141,7 @@ bool PortsOrch::addLag(string lag_alias, uint32_t spa_id, int32_t switch_id)
lag.m_members = set<string>();
m_portList[lag_alias] = lag;
m_port_ref_count[lag_alias] = 0;
portOidToName[lag_id] = lag_alias;

PortUpdate update = { lag, true };
notify(SUBJECT_TYPE_PORT_CHANGE, static_cast<void *>(&update));
Expand Down Expand Up @@ -4181,6 +4196,11 @@ bool PortsOrch::removeLag(Port lag)
return false;
}

if (lag.m_bridge_port_id != SAI_NULL_OBJECT_ID)
{
return false;
}

sai_status_t status = sai_lag_api->remove_lag(lag.m_lag_id);
if (status != SAI_STATUS_SUCCESS)
{
Expand All @@ -4194,6 +4214,7 @@ bool PortsOrch::removeLag(Port lag)

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

portOidToName.erase(lag.m_lag_id);
m_portList.erase(lag.m_alias);
m_port_ref_count.erase(lag.m_alias);

Expand Down
5 changes: 5 additions & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ class PortsOrch : public Orch, public Subject
map<set<int>, sai_object_id_t> m_portListLaneMap;
map<set<int>, tuple<string, uint32_t, int, string, int>> m_lanesAliasSpeedMap;
map<string, Port> m_portList;
/* mapping from SAI object ID to Name for faster
* retrieval of Port/VLAN from object ID for events
* coming from SAI
*/
unordered_map<sai_object_id_t, string> portOidToName;
unordered_map<sai_object_id_t, int> m_portOidToIndex;
map<string, uint32_t> m_port_ref_count;
unordered_set<string> m_pendingPortSet;
Expand Down

0 comments on commit 047841e

Please sign in to comment.