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

[Orchagent]: FdbOrch changes for EVPN VXLAN #1275

Merged
merged 27 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6d3d2b5
[Orchagent]: FdbOrch changes for EVPN VXLAN
jainp1979 Apr 28, 2020
84642fc
This commit contains:
jainp1979 Jun 23, 2020
4d9bd0a
Fixed LGTM Warnings
jainp1979 Jun 24, 2020
187388e
[Orchagent]: FdbOrch changes for EVPN VXLAN
jainp1979 Oct 28, 2020
fb85618
[Orchagent]: FdbOrch changes for EVPN VXLAN
jainp1979 Oct 28, 2020
304234e
Merge branch 'master' into evpn_fdb_orchagent
jainp1979 Oct 28, 2020
073da4a
reverted vlanmgr changes
anilkpandey Dec 16, 2020
7025c7e
Merge remote-tracking branch 'upstream/master' into evpn_fdb_orchagent
anilkpandey Dec 16, 2020
7a83154
fix build issue
anilkpandey Dec 16, 2020
88f487e
Update portsorch.cpp
anilkpandey Dec 16, 2020
b9e696a
Merge remote-tracking branch 'upstream/master' into evpn_fdb_orchagent
anilkpandey Dec 18, 2020
2c0b5f5
fix build issue
anilkpandey Dec 18, 2020
e119e4f
Update fdborch.cpp
anilkpandey Dec 18, 2020
4c58722
Update aclorch_ut.cpp
anilkpandey Dec 18, 2020
e84411e
fix lgtm
anilkpandey Dec 19, 2020
e209750
Update test_evpn_fdb.py
anilkpandey Dec 21, 2020
eedde3c
Update test_evpn_fdb.py
anilkpandey Dec 21, 2020
ef3adf8
Update test_evpn_fdb.py
anilkpandey Dec 22, 2020
f97af78
Merge remote-tracking branch 'upstream/master' into evpn_fdb_orchagent
anilkpandey Dec 23, 2020
5f38e64
remove fdb flush related changes
anilkpandey Dec 23, 2020
41a4a18
updated as per review comments
anilkpandey Dec 24, 2020
f17b20e
Update fdborch.cpp
anilkpandey Dec 28, 2020
3ceb819
updated as per latest review comments
anilkpandey Dec 29, 2020
9021773
Merge remote-tracking branch 'upstream/master' into evpn_fdb_orchagent
anilkpandey Dec 29, 2020
df6b9e7
Update portsorch.cpp
anilkpandey Dec 29, 2020
1665c71
Merge remote-tracking branch 'upstream/master' into evpn_fdb_orchagent
anilkpandey Dec 31, 2020
798d5fe
fix vs test
anilkpandey Dec 31, 2020
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
220 changes: 206 additions & 14 deletions cfgmgr/vlanmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ using namespace swss;

#define DOT1Q_BRIDGE_NAME "Bridge"
#define VLAN_PREFIX "Vlan"
#define SWITCH_STR "switch"
#define LAG_PREFIX "PortChannel"
#define DEFAULT_VLAN_ID "1"
#define DEFAULT_MTU_STR "9100"
#define VLAN_HLEN 4
#define MAX_VLAN_ID 4095

extern MacAddress gMacAddress;

Expand All @@ -28,6 +30,8 @@ VlanMgr::VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME),
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME),
m_stateVlanMemberTable(stateDb, STATE_VLAN_MEMBER_TABLE_NAME),
m_appFdbTableProducer(appDb, APP_FDB_TABLE_NAME),
m_appSwitchTableProducer(appDb, APP_SWITCH_TABLE_NAME),
m_appVlanTableProducer(appDb, APP_VLAN_TABLE_NAME),
m_appVlanMemberTableProducer(appDb, APP_VLAN_MEMBER_TABLE_NAME)
{
Expand Down Expand Up @@ -88,6 +92,10 @@ VlanMgr::VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c

EXEC_WITH_ERROR_THROW(echo_cmd_backup, res);
}
/* vlan state notification from portsorch */
m_VlanStateNotificationConsumer = new swss::NotificationConsumer(appDb, "VLANSTATE");
auto vlanStatusNotificatier = new Notifier(m_VlanStateNotificationConsumer, this, "VLANSTATE");
Orch::addExecutor(vlanStatusNotificatier);
}

bool VlanMgr::addHostVlan(int vlan_id)
Expand All @@ -101,7 +109,7 @@ bool VlanMgr::addHostVlan(int vlan_id)
+ BASH_CMD + " -c \""
+ BRIDGE_CMD + " vlan add vid " + std::to_string(vlan_id) + " dev " + DOT1Q_BRIDGE_NAME + " self && "
+ IP_CMD + " link add link " + DOT1Q_BRIDGE_NAME
+ " up"
+ " down"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a behavior change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been included in #885, will remove from here.

+ " name " + VLAN_PREFIX + std::to_string(vlan_id)
+ " address " + gMacAddress.to_string()
+ " type vlan id " + std::to_string(vlan_id) + "\"";
Expand Down Expand Up @@ -179,14 +187,29 @@ bool VlanMgr::addHostVlanMember(int vlan_id, const string &port_alias, const str
// /bin/bash -c "/sbin/ip link set {{port_alias}} master Bridge &&
// /sbin/bridge vlan del vid 1 dev {{ port_alias }} &&
// /sbin/bridge vlan add vid {{vlan_id}} dev {{port_alias}} {{tagging_mode}}"
ostringstream cmds, inner;
inner << IP_CMD " link set " << shellquote(port_alias) << " master " DOT1Q_BRIDGE_NAME " && "
BRIDGE_CMD " vlan del vid " DEFAULT_VLAN_ID " dev " << shellquote(port_alias) << " && "
BRIDGE_CMD " vlan add vid " + std::to_string(vlan_id) + " dev " << shellquote(port_alias) << " " + tagging_cmd;
cmds << BASH_CMD " -c " << shellquote(inner.str());

const std::string key = std::string("") + "Vlan1|" + port_alias;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Vlan1?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been included in #885, will remove from here.


std::string res;
EXEC_WITH_ERROR_THROW(cmds.str(), res);
if (isVlanMemberStateOk(key)) {
ostringstream cmds, inner;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could define this outside to avoid duplicate declaration

inner << IP_CMD " link set " << shellquote(port_alias) << " master " DOT1Q_BRIDGE_NAME " && "
BRIDGE_CMD " vlan add vid " + std::to_string(vlan_id) + " dev " << shellquote(port_alias) << " " + tagging_cmd;
cmds << BASH_CMD " -c " << shellquote(inner.str());

std::string res;
EXEC_WITH_ERROR_THROW(cmds.str(), res);
}
else
{
ostringstream cmds, inner;
inner << IP_CMD " link set " << shellquote(port_alias) << " master " DOT1Q_BRIDGE_NAME " && "
BRIDGE_CMD " vlan del vid " DEFAULT_VLAN_ID " dev " << shellquote(port_alias) << " && "
BRIDGE_CMD " vlan add vid " + std::to_string(vlan_id) + " dev " << shellquote(port_alias) << " " + tagging_cmd;
cmds << BASH_CMD " -c " << shellquote(inner.str());

std::string res;
EXEC_WITH_ERROR_THROW(cmds.str(), res);
}

return true;
}
Expand Down Expand Up @@ -224,6 +247,137 @@ bool VlanMgr::isVlanMacOk()
return !!gMacAddress;
}

void VlanMgr::doSwitchTask(Consumer &consumer)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure a CLI/config is introduced for this. Lets discuss this in WG call to understand more

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been included in #885, will remove from here.

{
SWSS_LOG_ENTER();
auto it = consumer.m_toSync.begin();

while (it != consumer.m_toSync.end())
{
KeyOpFieldsValuesTuple t = it->second;

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

/* Ensure the key starts with "switch" otherwise ignore */
if (key != SWITCH_STR)
{
SWSS_LOG_NOTICE("Ignoring SWITCH key %s", key.c_str());
it = consumer.m_toSync.erase(it);
continue;
}

SWSS_LOG_DEBUG("key:switch");

for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "fdb_aging_time")
{
long agingTime = 0;
SWSS_LOG_DEBUG("attribute:fdb_aging_time");
if (op == SET_COMMAND)
{
SWSS_LOG_DEBUG("operation:set");
agingTime = strtol(fvValue(i).c_str(), NULL, 0);
if (agingTime < 0)
{
SWSS_LOG_ERROR("Invalid fdb_aging_time %s", fvValue(i).c_str());
break;
}
SWSS_LOG_DEBUG("value:%s",fvValue(i).c_str());
}
else if (op == DEL_COMMAND)
{
SWSS_LOG_DEBUG("operation:del");
agingTime = 0;
}
else
{
SWSS_LOG_ERROR("Unknown operation type %s", op.c_str());
break;
}

vector<FieldValueTuple> fvVector;
FieldValueTuple aging_time("fdb_aging_time", to_string(agingTime));
fvVector.push_back(aging_time);
m_appSwitchTableProducer.set(key, fvVector);
break;
}
}

it = consumer.m_toSync.erase(it);
}
}

void VlanMgr::doFdbTask(Consumer &consumer)
{
auto it = consumer.m_toSync.begin();

while (it != consumer.m_toSync.end())
{
KeyOpFieldsValuesTuple t = it->second;

/* format: <VLAN_name>|<MAC_address> */
vector<string> keys = tokenize(kfvKey(t), config_db_key_delimiter, 1);
/* keys[0] is vlan as (Vlan10) and keys[1] is mac as (00-00-00-00-00-00) */
string op = kfvOp(t);

/* Ensure the key starts with "Vlan" otherwise ignore */
if (strncmp(keys[0].c_str(), VLAN_PREFIX, 4))
{
SWSS_LOG_ERROR("Invalid key format. No 'Vlan' prefix: %s", keys[0].c_str());
it = consumer.m_toSync.erase(it);
continue;
}

unsigned long vlan_id;
vlan_id = strtoul(keys[0].substr(strlen(VLAN_PREFIX)).c_str(), NULL, 0);

if ((vlan_id <= 0) || (vlan_id > MAX_VLAN_ID))
{
SWSS_LOG_ERROR("Invalid key format. Vlan is out of range: %s", keys[0].c_str());
it = consumer.m_toSync.erase(it);
continue;
}

MacAddress mac = MacAddress(keys[1]);

string key = VLAN_PREFIX + to_string(vlan_id);
key += DEFAULT_KEY_SEPARATOR;
key += mac.to_string();

if (op == SET_COMMAND)
{
string port;
for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "port")
{
port = fvValue(i);
break;
}
}

vector<FieldValueTuple> fvVector;
FieldValueTuple p("port", port);
fvVector.push_back(p);
FieldValueTuple t("type", "static");
fvVector.push_back(t);

m_appFdbTableProducer.set(key, fvVector);
}
else if (op == DEL_COMMAND)
{
m_appFdbTableProducer.del(key);
}
else
{
SWSS_LOG_ERROR("Unknown operation type %s", op.c_str());
}
it = consumer.m_toSync.erase(it);
}
}

void VlanMgr::doVlanTask(Consumer &consumer)
{
if (!isVlanMacOk())
Expand Down Expand Up @@ -296,12 +450,12 @@ void VlanMgr::doVlanTask(Consumer &consumer)
{
/* Set vlan admin status */
if (fvField(i) == "admin_status")
{
admin_status = fvValue(i);
setHostVlanAdminState(vlan_id, admin_status);
fvVector.push_back(i);
}
/* Set vlan mtu */
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like tabspaces got added. Please fix

admin_status = fvValue(i);
setHostVlanAdminState(vlan_id, admin_status);
fvVector.push_back(i);
}
/* Set vlan mtu */
else if (fvField(i) == "mtu")
{
mtu = fvValue(i);
Expand Down Expand Up @@ -593,9 +747,47 @@ void VlanMgr::doTask(Consumer &consumer)
{
doVlanMemberTask(consumer);
}
else if (table_name == CFG_FDB_TABLE_NAME)
{
doFdbTask(consumer);
}
else if (table_name == CFG_SWITCH_TABLE_NAME)
{
SWSS_LOG_DEBUG("Table:SWITCH");
doSwitchTask(consumer);
}
else
{
SWSS_LOG_ERROR("Unknown config table %s ", table_name.c_str());
throw runtime_error("VlanMgr doTask failure.");
}
}

void VlanMgr::doTask(NotificationConsumer &consumer)
{
std::string op;
std::string data;
std::vector<swss::FieldValueTuple> values;

if (&consumer != m_VlanStateNotificationConsumer)
{
SWSS_LOG_WARN("received incorrect notification message");
return;
}

consumer.pop(op, data, values);

unsigned long vlan_id = strtoul(data.substr(strlen(VLAN_PREFIX)).c_str(), NULL, 0);

SWSS_LOG_NOTICE("vlanmgr received port status notification state %s vlan %s",
op.c_str(), data.c_str());

if (isVlanStateOk(data))
{
setHostVlanAdminState((int)vlan_id, op);
}
else
{
SWSS_LOG_ERROR("received state update for vlan %s not existing", data.c_str());
}
}
7 changes: 7 additions & 0 deletions cfgmgr/vlanmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "dbconnector.h"
#include "producerstatetable.h"
#include "orch.h"
#include "notifier.h"

#include <set>
#include <map>
Expand All @@ -19,14 +20,20 @@ class VlanMgr : public Orch

private:
ProducerStateTable m_appVlanTableProducer, m_appVlanMemberTableProducer;
ProducerStateTable m_appFdbTableProducer;
ProducerStateTable m_appSwitchTableProducer;
Table m_cfgVlanTable, m_cfgVlanMemberTable;
Table m_statePortTable, m_stateLagTable;
Table m_stateVlanTable, m_stateVlanMemberTable;
std::set<std::string> m_vlans;
NotificationConsumer* m_VlanStateNotificationConsumer;

void doTask(Consumer &consumer);
void doTask(NotificationConsumer &consumer);
void doVlanTask(Consumer &consumer);
void doVlanMemberTask(Consumer &consumer);
void doFdbTask(Consumer &consumer);
void doSwitchTask(Consumer &consumer);
void processUntaggedVlanMembers(std::string vlan, const std::string &members);

bool addHostVlan(int vlan_id);
Expand Down
2 changes: 2 additions & 0 deletions cfgmgr/vlanmgrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ int main(int argc, char **argv)
vector<string> cfg_vlan_tables = {
CFG_VLAN_TABLE_NAME,
CFG_VLAN_MEMBER_TABLE_NAME,
CFG_FDB_TABLE_NAME,
CFG_SWITCH_TABLE_NAME,
};

DBConnector cfgDb("CONFIG_DB", 0);
Expand Down
Loading