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

[portsorch]: add support to set mac-address learning attribute on bridge-port #809

Merged
merged 11 commits into from
Nov 12, 2019
23 changes: 22 additions & 1 deletion cfgmgr/portmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ bool PortMgr::setPortAdminStatus(const string &alias, const bool up)
return true;
}

bool PortMgr::setPortLearnMode(const string &alias, const string &learn_mode)
{
// Set the port MAC learn mode in application database
vector<FieldValueTuple> fvs;
FieldValueTuple fv("learn_mode", learn_mode);
fvs.push_back(fv);
m_appPortTable.set(alias, fvs);

return true;
}

bool PortMgr::isPortStateOk(const string &alias)
{
vector<FieldValueTuple> temp;
Expand Down Expand Up @@ -91,7 +102,7 @@ void PortMgr::doTask(Consumer &consumer)
continue;
}

string admin_status, mtu;
string admin_status, mtu, learn_mode;

bool configured = (m_portList.find(alias) != m_portList.end());

Expand All @@ -116,6 +127,10 @@ void PortMgr::doTask(Consumer &consumer)
{
admin_status = fvValue(i);
}
else if (fvField(i) == "learn_mode")
{
learn_mode = fvValue(i);
}
}

if (!mtu.empty())
Expand All @@ -129,6 +144,12 @@ void PortMgr::doTask(Consumer &consumer)
setPortAdminStatus(alias, admin_status == "up");
SWSS_LOG_NOTICE("Configure %s admin status to %s", alias.c_str(), admin_status.c_str());
}

if (!learn_mode.empty())
{
setPortLearnMode(alias, learn_mode);
SWSS_LOG_NOTICE("Configure %s MAC learn mode to %s", alias.c_str(), learn_mode.c_str());
}
}

it = consumer.m_toSync.erase(it);
Expand Down
1 change: 1 addition & 0 deletions cfgmgr/portmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PortMgr : public Orch
void doTask(Consumer &consumer);
bool setPortMtu(const std::string &alias, const std::string &mtu);
bool setPortAdminStatus(const std::string &alias, const bool up);
bool setPortLearnMode(const std::string &alias, const std::string &learn_mode);
bool isPortStateOk(const std::string &alias);
};

Expand Down
23 changes: 23 additions & 0 deletions cfgmgr/teammgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void TeamMgr::doLagTask(Consumer &consumer)
bool fallback = false;
string admin_status = DEFAULT_ADMIN_STATUS_STR;
string mtu = DEFAULT_MTU_STR;
string learn_mode;

for (auto i : kfvFieldsValues(t))
{
Expand Down Expand Up @@ -153,6 +154,12 @@ void TeamMgr::doLagTask(Consumer &consumer)
mtu = fvValue(i);
SWSS_LOG_INFO("Get MTU %s", mtu.c_str());
}
else if (fvField(i) == "learn_mode")
{
learn_mode = fvValue(i);
SWSS_LOG_INFO("Get learn_mode %s",
learn_mode.c_str());
}
}

if (m_lagList.find(alias) == m_lagList.end())
Expand All @@ -168,6 +175,11 @@ void TeamMgr::doLagTask(Consumer &consumer)

setLagAdminStatus(alias, admin_status);
setLagMtu(alias, mtu);
if (!learn_mode.empty())
{
setLagLearnMode(alias, learn_mode);
SWSS_LOG_NOTICE("Configure %s MAC learn mode to %s", alias.c_str(), learn_mode.c_str());
}
}
else if (op == DEL_COMMAND)
{
Expand Down Expand Up @@ -365,6 +377,17 @@ bool TeamMgr::setLagMtu(const string &alias, const string &mtu)
return true;
}

bool TeamMgr::setLagLearnMode(const string &alias, const string &learn_mode)
{
// Set the port MAC learn mode in application database
vector<FieldValueTuple> fvs;
FieldValueTuple fv("learn_mode", learn_mode);
fvs.push_back(fv);
m_appLagTable.set(alias, fvs);

return true;
}

task_process_status TeamMgr::addLag(const string &alias, int min_links, bool fallback)
{
SWSS_LOG_ENTER();
Expand Down
1 change: 1 addition & 0 deletions cfgmgr/teammgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class TeamMgr : public Orch

bool setLagAdminStatus(const std::string &alias, const std::string &admin_status);
bool setLagMtu(const std::string &alias, const std::string &mtu);
bool setLagLearnMode(const std::string &alias, const std::string &learn_mode);

bool isPortEnslaved(const std::string &);
bool findPortMaster(std::string &, const std::string &);
Expand Down
1 change: 1 addition & 0 deletions orchagent/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Port
int m_index = 0; // PHY_PORT: index
uint32_t m_mtu = DEFAULT_MTU;
uint32_t m_speed = 0; // Mbps
std::string m_learn_mode = "hardware";
bool m_autoneg = false;
bool m_admin_state_up = false;
sai_object_id_t m_port_id = 0;
Expand Down
121 changes: 119 additions & 2 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ static map<string, sai_port_priority_flow_control_mode_t> pfc_asym_map =
{ "off", SAI_PORT_PRIORITY_FLOW_CONTROL_MODE_COMBINED }
};

static map<string, sai_bridge_port_fdb_learning_mode_t> learn_mode_map =
{
{ "drop", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_DROP },
{ "disable", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_DISABLE },
{ "hardware", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW },
{ "cpu_trap", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_CPU_TRAP},
{ "cpu_log", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_CPU_LOG},
{ "notification", SAI_BRIDGE_PORT_FDB_LEARNING_MODE_FDB_NOTIFICATION}
};

const vector<sai_port_stat_t> portStatIds =
{
SAI_PORT_STAT_IF_IN_OCTETS,
Expand Down Expand Up @@ -1543,6 +1553,7 @@ void PortsOrch::doPortTask(Consumer &consumer)
string pfc_asym;
uint32_t mtu = 0;
uint32_t speed = 0;
string learn_mode;
int an = -1;

for (auto i : kfvFieldsValues(t))
Expand Down Expand Up @@ -1585,6 +1596,12 @@ void PortsOrch::doPortTask(Consumer &consumer)
fec_mode = fvValue(i);
}

/* Get port fdb learn mode*/
if (fvField(i) == "learn_mode")
{
learn_mode = fvValue(i);
}

/* Set port asymmetric PFC */
if (fvField(i) == "pfc_asym")
pfc_asym = fvValue(i);
Expand Down Expand Up @@ -1858,6 +1875,32 @@ void PortsOrch::doPortTask(Consumer &consumer)
}
}

if (!learn_mode.empty() && (p.m_learn_mode != learn_mode))
{
if (p.m_bridge_port_id != SAI_NULL_OBJECT_ID)
{
if(setBridgePortLearnMode(p, learn_mode))
{
p.m_learn_mode = learn_mode;
m_portList[alias] = p;
SWSS_LOG_NOTICE("Set port %s learn mode to %s", alias.c_str(), learn_mode.c_str());
}
else
{
SWSS_LOG_ERROR("Failed to set port %s learn mode to %s", alias.c_str(), learn_mode.c_str());
it++;
continue;
}
}
else
{
p.m_learn_mode = learn_mode;
m_portList[alias] = p;

SWSS_LOG_NOTICE("Saved to set port %s learn mode %s", alias.c_str(), learn_mode.c_str());
}
}

if (pfc_asym != "")
{
if (setPortPfcAsym(p, pfc_asym))
Expand Down Expand Up @@ -2168,13 +2211,19 @@ void PortsOrch::doLagTask(Consumer &consumer)
{
// Retrieve attributes
uint32_t mtu = 0;
string learn_mode;

for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "mtu")
{
mtu = (uint32_t)stoul(fvValue(i));
}
if (fvField(i) == "oper_status")
else if (fvField(i) == "learn_mode")
{
learn_mode = fvValue(i);
}
else if (fvField(i) == "oper_status")
{
if (fvValue(i) == "down")
{
Expand Down Expand Up @@ -2214,6 +2263,32 @@ void PortsOrch::doLagTask(Consumer &consumer)
gIntfsOrch->setRouterIntfsMtu(l);
}
}

if (!learn_mode.empty() && (l.m_learn_mode != learn_mode))
{
if (l.m_bridge_port_id != SAI_NULL_OBJECT_ID)
{
if(setBridgePortLearnMode(l, learn_mode))
{
l.m_learn_mode = learn_mode;
m_portList[alias] = l;
SWSS_LOG_NOTICE("Set port %s learn mode to %s", alias.c_str(), learn_mode.c_str());
}
else
{
SWSS_LOG_ERROR("Failed to set port %s learn mode to %s", alias.c_str(), learn_mode.c_str());
it++;
continue;
}
}
else
{
l.m_learn_mode = learn_mode;
m_portList[alias] = l;

SWSS_LOG_NOTICE("Saved to set port %s learn mode %s", alias.c_str(), learn_mode.c_str());
}
}
}

it = consumer.m_toSync.erase(it);
Expand Down Expand Up @@ -2628,7 +2703,15 @@ bool PortsOrch::addBridgePort(Port &port)

/* And with hardware FDB learning mode set to HW (explicit default value) */
attr.id = SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE;
attr.value.s32 = SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW;
auto found = learn_mode_map.find(port.m_learn_mode);
if (found == learn_mode_map.end())
{
attr.value.s32 = SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW;
}
else
{
attr.value.s32 = found->second;
}
attrs.push_back(attr);

sai_status_t status = sai_bridge_api->create_bridge_port(&port.m_bridge_port_id, gSwitchId, (uint32_t)attrs.size(), attrs.data());
Expand Down Expand Up @@ -2699,6 +2782,40 @@ bool PortsOrch::removeBridgePort(Port &port)
return true;
}

bool PortsOrch::setBridgePortLearnMode(Port &port, string learn_mode)
{
SWSS_LOG_ENTER();

if (port.m_bridge_port_id == SAI_NULL_OBJECT_ID)
{
return true;
}

auto found = learn_mode_map.find(learn_mode);
if (found == learn_mode_map.end())
{
SWSS_LOG_ERROR("Incorrect MAC learn mode: %s", learn_mode.c_str());
return false;
}

/* Set bridge port learning mode */
sai_attribute_t attr;
attr.id = SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE;
attr.value.s32 = found->second;

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 learning mode, rv:%d",
port.m_alias.c_str(), status);
return false;
}

SWSS_LOG_NOTICE("Set bridge port %s learning mode %s", port.m_alias.c_str(), learn_mode.c_str());

return true;
}

bool PortsOrch::addVlan(string vlan_alias)
{
SWSS_LOG_ENTER();
Expand Down
3 changes: 2 additions & 1 deletion orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ class PortsOrch : public Orch, public Subject
map<set<int>, tuple<string, uint32_t, int, string>> m_lanesAliasSpeedMap;
map<string, Port> m_portList;
map<string, uint32_t> m_port_ref_count;

unordered_set<string> m_pendingPortSet;


NotificationConsumer* m_portStatusNotificationConsumer;

void doTask(Consumer &consumer);
Expand All @@ -147,6 +147,7 @@ class PortsOrch : public Orch, public Subject

bool addBridgePort(Port &port);
bool removeBridgePort(Port &port);
bool setBridgePortLearnMode(Port &port, string learn_mode);

bool addVlan(string vlan);
bool removeVlan(Port vlan);
Expand Down
Loading