Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FdbOrch & PortsOrch] Flush LAG FDB entry when LAG state changes to down #964

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions orchagent/fdborch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ void FdbOrch::update(SubjectType type, void *cntx)
updateVlanMember(*update);
break;
}
case SUBJECT_TYPE_PORT_STATUS_CHANGE:
{
PortStatusUpdate *update = reinterpret_cast<PortStatusUpdate *>(cntx);
updatePortStatus(*update);
break;
}
default:
break;
}
Expand Down Expand Up @@ -551,3 +557,100 @@ bool FdbOrch::removeFdbEntry(const FdbEntry& entry)

return true;
}

void FdbOrch::updatePortStatusToUp(Port& port)
{
//TODO: recover the static FDB entry when port up
return;
}

void FdbOrch::updatePortStatusToDown(Port& port)
{
SWSS_LOG_ENTER();
//TODO: remove the static FDB entry when port down

flushFdbEntry(port);
}

void FdbOrch::updatePortStatus(const PortStatusUpdate& update)
{
SWSS_LOG_ENTER();

Port updatePort = update.port;
switch (update.operStatus)
{
case SAI_PORT_OPER_STATUS_UP:
{
updatePortStatusToUp(updatePort);
break;
}
case SAI_PORT_OPER_STATUS_DOWN:
{
updatePortStatusToDown(updatePort);
break;
}
default:
{
SWSS_LOG_ERROR("Can`t processing oper status of %d", (int)update.operStatus);
break;
}
}
return;
}

bool FdbOrch::flushFdbEntry(const Port& port, const string type)
{

sai_attribute_t attr;
vector<sai_attribute_t> attrs;

if (port.m_bridge_port_id == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_DEBUG("Port %s is not added to a bridge", port.m_alias.c_str());
return true;
}
if (port.m_vlan_members.empty())
{
SWSS_LOG_DEBUG("Port %s is not added to any vlan", port.m_alias.c_str());
return true;

}
for (const auto vlanInfo: port.m_vlan_members)
{
attrs.clear();
Port vlan;
if (!m_portsOrch->getVlanByVlanId(vlanInfo.first, vlan))
{
SWSS_LOG_ERROR("Failed to get vlan by vlan ID %d", vlanInfo.first);
continue;
}

attr.id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID;
attr.value.oid = port.m_bridge_port_id;
attrs.push_back(attr);

attr.id = SAI_FDB_FLUSH_ATTR_BV_ID;
attr.value.oid = vlan.m_vlan_info.vlan_oid;
attrs.push_back(attr);

attr.id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE;
attr.value.s32 = (type == "dynamic") ? SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC : SAI_FDB_FLUSH_ENTRY_TYPE_STATIC;
attrs.push_back(attr);

sai_status_t status = sai_fdb_api->flush_fdb_entries(gSwitchId, (uint32_t)attrs.size(), attrs.data());
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to fulsh fdb on port %s in Vlan %d",
port.m_alias.c_str(), vlanInfo.first);
}
else
{
SWSS_LOG_ERROR("Success to fulsh fdb on port %s in Vlan %d",
port.m_alias.c_str(), vlanInfo.first);
}

}

return true;

}
5 changes: 5 additions & 0 deletions orchagent/fdborch.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,13 @@ class FdbOrch: public Orch, public Subject, public Observer
void doTask(NotificationConsumer& consumer);

void updateVlanMember(const VlanMemberUpdate&);
void updatePortStatus(const PortStatusUpdate&);
void updatePortStatusToDown(Port&);
void updatePortStatusToUp(Port&);

bool addFdbEntry(const FdbEntry&, const string&, const string&);
bool removeFdbEntry(const FdbEntry&);
bool flushFdbEntry(const Port& port, const string type="dynamic");

bool storeFdbEntryState(const FdbUpdate& update);
};
Expand Down
1 change: 1 addition & 0 deletions orchagent/observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum SubjectType
SUBJECT_TYPE_MIRROR_SESSION_CHANGE,
SUBJECT_TYPE_INT_SESSION_CHANGE,
SUBJECT_TYPE_PORT_CHANGE,
SUBJECT_TYPE_PORT_STATUS_CHANGE,
};

class Observer
Expand Down
65 changes: 62 additions & 3 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,29 @@ void PortsOrch::updateDbPortOperStatus(const Port& port, sai_port_oper_status_t
m_portTable->set(port.m_alias, tuples);
}

void PortsOrch::notifyPortStatusChange(sai_object_id_t id, sai_port_oper_status_t status)
{
SWSS_LOG_ENTER();
struct PortStatusUpdate update;
Port port;

/* Can only status of up/down proceeded */
if ((SAI_PORT_OPER_STATUS_UP != status) && (SAI_PORT_OPER_STATUS_DOWN != status))
{
return;
}
if (getPort(id, port))
{
update.port = port;
update.operStatus = status;
SWSS_LOG_DEBUG("Notify observer event SUBJECT_TYPE_PORT_STATUS_CHANGE: %s",
status == SAI_PORT_OPER_STATUS_UP ? "up" : "down");
notify(SUBJECT_TYPE_PORT_STATUS_CHANGE, static_cast<void *>(&update));
} else {
SWSS_LOG_ERROR("Failed to get Port info for id 0x%lx", id);
}
}

bool PortsOrch::addPort(const set<int> &lane_set, uint32_t speed, int an, string fec_mode)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -2167,7 +2190,8 @@ void PortsOrch::doLagTask(Consumer &consumer)

string alias = kfvKey(t);
string op = kfvOp(t);

string oper_status = "down";
string admin_status = "down";
if (op == SET_COMMAND)
{
// Retrieve attributes
Expand All @@ -2178,12 +2202,20 @@ void PortsOrch::doLagTask(Consumer &consumer)
{
mtu = (uint32_t)stoul(fvValue(i));
}
else if (fvField(i) == "oper_status")
{
oper_status = fvValue(i);
}
else if (fvField(i) == "admin_status")
{
admin_status = fvValue(i);
}
}

// Create a new LAG when the new alias comes
if (m_portList.find(alias) == m_portList.end())
{
if (!addLag(alias))
if (!addLag(alias, admin_status, oper_status))
{
it++;
continue;
Expand All @@ -2207,6 +2239,7 @@ void PortsOrch::doLagTask(Consumer &consumer)
gIntfsOrch->setRouterIntfsMtu(l);
}
}
setLagStatus(l, admin_status, oper_status);
}

it = consumer.m_toSync.erase(it);
Expand Down Expand Up @@ -2869,7 +2902,7 @@ bool PortsOrch::removeVlanMember(Port &vlan, Port &port)
return true;
}

bool PortsOrch::addLag(string lag_alias)
bool PortsOrch::addLag(string lag_alias, string admin_status, string oper_status)
{
SWSS_LOG_ENTER();

Expand All @@ -2887,6 +2920,8 @@ bool PortsOrch::addLag(string lag_alias)
Port lag(lag_alias, Port::LAG);
lag.m_lag_id = lag_id;
lag.m_members = set<string>();
lag.m_oper_status = (oper_status == "up") ? SAI_PORT_OPER_STATUS_UP : SAI_PORT_OPER_STATUS_DOWN;
lag.m_admin_state_up = (admin_status == "up");
m_portList[lag_alias] = lag;

PortUpdate update = { lag, true };
Expand Down Expand Up @@ -2930,6 +2965,29 @@ bool PortsOrch::removeLag(Port lag)
return true;
}

bool PortsOrch::setLagStatus(Port &lag, string admin_status, string oper_status)
{

SWSS_LOG_DEBUG("Update lag %s admin status to %s, oper status to %s",
lag.m_alias.c_str(), admin_status.c_str(), oper_status.c_str());

auto old_oper_status = lag.m_oper_status;
struct PortStatusUpdate update;
//update the lag port status
lag.m_oper_status = (oper_status == "up") ? SAI_PORT_OPER_STATUS_UP : SAI_PORT_OPER_STATUS_DOWN;
lag.m_admin_state_up = (admin_status == "up");
m_portList[lag.m_alias] = lag;
if (old_oper_status == lag.m_oper_status)
return true;
//notify the lag oper status change
update.port = lag;
update.operStatus = lag.m_oper_status;
SWSS_LOG_DEBUG("Notify observer event SUBJECT_TYPE_PORT_STATUS_CHANGE: %s",
lag.m_oper_status == SAI_PORT_OPER_STATUS_UP ? "up" : "down");
notify(SUBJECT_TYPE_PORT_STATUS_CHANGE, static_cast<void *>(&update));
return true;
}

void PortsOrch::getLagMember(Port &lag, vector<Port> &portv)
{
Port member;
Expand Down Expand Up @@ -3228,6 +3286,7 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
}

updatePortOperStatus(port, status);
notifyPortStatusChange(id, status);

/* update m_portList */
m_portList[port.m_alias] = port;
Expand Down
10 changes: 9 additions & 1 deletion orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ struct PortUpdate
bool add;
};

struct PortStatusUpdate
{
Port port;
sai_port_oper_status_t operStatus;
};

struct LagMemberUpdate
{
Port lag;
Expand Down Expand Up @@ -72,6 +78,7 @@ class PortsOrch : public Orch, public Subject
bool getAclBindPortId(string alias, sai_object_id_t &port_id);

bool setHostIntfsOperStatus(const Port& port, bool up) const;
void notifyPortStatusChange(sai_object_id_t, sai_port_oper_status_t status);
void updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const;
bool createBindAclTableGroup(sai_object_id_t id, sai_object_id_t &group_oid, acl_stage_type_t acl_stage = ACL_STAGE_EGRESS);
bool bindAclTable(sai_object_id_t id, sai_object_id_t table_oid, sai_object_id_t &group_member_oid, acl_stage_type_t acl_stage = ACL_STAGE_INGRESS);
Expand Down Expand Up @@ -150,11 +157,12 @@ class PortsOrch : public Orch, public Subject
bool addVlanMember(Port &vlan, Port &port, string& tagging_mode);
bool removeVlanMember(Port &vlan, Port &port);

bool addLag(string lag);
bool addLag(string lag, string admin_status, string oper_status);
bool removeLag(Port lag);
bool addLagMember(Port &lag, Port &port);
bool removeLagMember(Port &lag, Port &port);
void getLagMember(Port &lag, vector<Port> &portv);
bool setLagStatus(Port &lag, string admin_status, string oper_status);

bool addPort(const set<int> &lane_set, uint32_t speed, int an=0, string fec="");
bool removePort(sai_object_id_t port_id);
Expand Down