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 string &alias, const string &mtu);
bool setPortAdminStatus(const string &alias, const bool up);
bool setPortLearnMode(const string &alias, const string &learn_mode);
bool isPortStateOk(const 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 string &alias, const string &admin_status);
bool setLagMtu(const string &alias, const string &mtu);
bool setLagLearnMode(const string &alias, const string &learn_mode);

bool isPortEnslaved(const string &);
bool findPortMaster(string &, const 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: 120 additions & 1 deletion orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,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 @@ -1541,6 +1551,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 @@ -1583,6 +1594,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 @@ -1876,6 +1893,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 @@ -2186,12 +2229,20 @@ 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));
}

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

// Create a new LAG when the new alias comes
Expand Down Expand Up @@ -2221,6 +2272,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 @@ -2635,7 +2712,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 @@ -2706,6 +2791,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