-
Notifications
You must be signed in to change notification settings - Fork 539
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
Changes from 6 commits
6d3d2b5
84642fc
4d9bd0a
187388e
fb85618
304234e
073da4a
7025c7e
7a83154
88f487e
b9e696a
2c0b5f5
e119e4f
4c58722
e84411e
e209750
eedde3c
ef3adf8
f97af78
5f38e64
41a4a18
f17b20e
3ceb819
9021773
df6b9e7
1665c71
798d5fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
||
|
@@ -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) | ||
{ | ||
|
@@ -90,6 +94,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) | ||
|
@@ -103,7 +111,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" | ||
+ " name " + VLAN_PREFIX + std::to_string(vlan_id) | ||
+ " address " + gMacAddress.to_string() | ||
+ " type vlan id " + std::to_string(vlan_id) + "\""; | ||
|
@@ -196,14 +204,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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why Vlan1? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
|
@@ -241,6 +264,137 @@ bool VlanMgr::isVlanMacOk() | |
return !!gMacAddress; | ||
} | ||
|
||
void VlanMgr::doSwitchTask(Consumer &consumer) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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()) | ||
|
@@ -314,12 +468,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 */ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
|
@@ -619,9 +773,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()); | ||
} | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.