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

Vlan stacking implementation #2372

Open
wants to merge 2 commits 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
224 changes: 224 additions & 0 deletions cfgmgr/vlanmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "tokenize.h"
#include "shellcmd.h"
#include "warm_restart.h"
#include "converter.h"
#include <swss/redisutility.h>

using namespace std;
Expand All @@ -31,6 +32,8 @@ VlanMgr::VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
m_stateVlanMemberTable(stateDb, STATE_VLAN_MEMBER_TABLE_NAME),
m_appVlanTableProducer(appDb, APP_VLAN_TABLE_NAME),
m_appVlanMemberTableProducer(appDb, APP_VLAN_MEMBER_TABLE_NAME),
m_appVlanStackingTableProducer(appDb, APP_VLAN_STACKING_TABLE_NAME),
m_appVlanXlateTableProducer(appDb, APP_VLAN_TRANSLATION_TABLE_NAME),
replayDone(false)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -675,6 +678,167 @@ void VlanMgr::doVlanMemberTask(Consumer &consumer)
}
}

void VlanMgr::doVlanStackTask(Consumer& consumer)
{
auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
{
auto& t = it->second;

string key = kfvKey(t);

vector<string> keys = tokenize(key, config_db_key_delimiter);

if (keys.size() != 2)
{
SWSS_LOG_ERROR("Unknown VLAN Stacking config %s.", key.c_str());
it = consumer.m_toSync.erase(it);
continue;
}

if (!isValidVlanId(keys.at(1), 1, 4094))
{
SWSS_LOG_ERROR("Unknown VLAN Stacking config %s.", key.c_str());
it = consumer.m_toSync.erase(it);
continue;
}

string new_key = keys.at(0) + DEFAULT_KEY_SEPARATOR + keys.at(1);

string op = kfvOp(t);

if (op == SET_COMMAND)
{
uint8_t s_vlan_priority = 0;
vector<uint16_t> c_vlanids;

for (auto itp : kfvFieldsValues(t))
{
string attr_name = fvField(itp);
string attr_value = to_upper(fvValue(itp));

if (attr_name == "c_vlanids")
{
auto rv = parseVlanList(attr_value, c_vlanids);
if (rv == false)
{
goto vlan_stacking_parse_failed;
}
}
else if (attr_name == "s_vlan_priority")
{
try
{
s_vlan_priority = (uint8_t)stoi(attr_value);
}
catch (std::invalid_argument& e)
{
goto vlan_stacking_parse_failed;
}

if (s_vlan_priority < 0 || s_vlan_priority > 7)

Choose a reason for hiding this comment

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

s_vlan_priority is unsigned int. It cant be "< 0". Need to relook at this check?

Choose a reason for hiding this comment

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

BTW 0xFF is a valid value right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, 0xFF is not valid value

{
goto vlan_stacking_parse_failed;
}
}
}

if (0)
{
vlan_stacking_parse_failed:
it = consumer.m_toSync.erase(it);
continue;
}

vector<FieldValueTuple> fvVector;

m_appVlanStackingTableProducer.set(new_key, kfvFieldsValues(t));
it = consumer.m_toSync.erase(it);
}
else if (op == DEL_COMMAND)
{
SWSS_LOG_INFO("del entry in appVlanStackingTable");
m_appVlanStackingTableProducer.del(new_key);
it = consumer.m_toSync.erase(it);
}
else
{
SWSS_LOG_ERROR("Unknown operation type %s", op.c_str());
it = consumer.m_toSync.erase(it);
}
}
}

void VlanMgr::doVlanXlateTask(Consumer& consumer)
{
auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
{
auto& t = it->second;

string key = kfvKey(t);

vector<string> keys = tokenize(key, config_db_key_delimiter);

if (keys.size() != 2)
{
SWSS_LOG_ERROR("Unknown VLAN Translation config %s.", key.c_str());
it = consumer.m_toSync.erase(it);
continue;
}

if (!isValidVlanId(keys.at(1), 1, 4094))
{
SWSS_LOG_ERROR("Unknown VLAN Translation config %s.", key.c_str());
it = consumer.m_toSync.erase(it);
continue;
}

string new_key = keys.at(0) + DEFAULT_KEY_SEPARATOR + keys.at(1);

string op = kfvOp(t);

if (op == SET_COMMAND)
{
for (auto itp : kfvFieldsValues(t))
{
string attr_name = fvField(itp);
string attr_value = to_upper(fvValue(itp));

if (attr_name == "c_vlanid")
{
if (!isValidVlanId(attr_value, 1, 4094))
{
goto vlan_xlate_parse_failed;
}
}
}

if (0)
{
vlan_xlate_parse_failed:
it = consumer.m_toSync.erase(it);
continue;
}

vector<FieldValueTuple> fvVector;
m_appVlanXlateTableProducer.set(new_key, kfvFieldsValues(t));
it = consumer.m_toSync.erase(it);
}
else if (op == DEL_COMMAND)
{
SWSS_LOG_INFO("del entry in appVlanTranslationTable");
m_appVlanXlateTableProducer.del(new_key);
it = consumer.m_toSync.erase(it);
}
else
{
SWSS_LOG_ERROR("Unknown operation type %s", op.c_str());
it = consumer.m_toSync.erase(it);
}
}
}

void VlanMgr::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();
Expand All @@ -689,9 +853,69 @@ void VlanMgr::doTask(Consumer &consumer)
{
doVlanMemberTask(consumer);
}
else if (table_name == CFG_VLAN_STACKING_TABLE_NAME)
{
SWSS_LOG_DEBUG("Table:CFG_VLAN_STACKING_TABLE_NAME");
doVlanStackTask(consumer);
}
else if (table_name == CFG_VLAN_TRANSLATION_TABLE_NAME)
{
SWSS_LOG_DEBUG("Table:CFG_VLAN_TRANSLATION_TABLE_NAME");
doVlanXlateTask(consumer);
}
else
{
SWSS_LOG_ERROR("Unknown config table %s ", table_name.c_str());
throw runtime_error("VlanMgr doTask failure.");
}
}

bool VlanMgr::isValidVlanId(const std::string& str, uint16_t min, uint16_t max)
{
try
{
to_uint<uint16_t>(str, min, max);
}
catch (std::invalid_argument& e)
{
return false;
}

return true;
}

bool VlanMgr::parseVlanList(const std::string& raw_vlanids, std::vector<uint16_t>& vlanids)
{
stringstream ss(raw_vlanids);
while (ss.good()) {
string substr;
getline(ss, substr, ',');
if (substr.find("..") != std::string::npos)
{
string delimiter = "..";
size_t pos = substr.find("..");
string start = substr.substr(0, pos);
string end = substr.substr(pos + delimiter.size());

if (!isValidVlanId(start, 1, 4094) || !isValidVlanId(end, 1, 4094))
{
return false;
}

for (int i = std::stoi(start); i <= std::stoi(end); i++)
{
vlanids.push_back((uint16_t)i);
}
}
else
{
if (!isValidVlanId(substr, 1, 4094))
{
return false;
}

vlanids.push_back((uint16_t)std::stoi(substr));
}
}
return true;
}
6 changes: 6 additions & 0 deletions cfgmgr/vlanmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ class VlanMgr : public Orch
public:
VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const std::vector<std::string> &tableNames);
using Orch::doTask;
static bool isValidVlanId(const std::string& str, uint16_t min, uint16_t max);
static bool parseVlanList(const std::string& raw_vlanids, std::vector<uint16_t>& vlanids);

private:
ProducerStateTable m_appVlanTableProducer, m_appVlanMemberTableProducer;
ProducerStateTable m_appVlanStackingTableProducer;
ProducerStateTable m_appVlanXlateTableProducer;
Table m_cfgVlanTable, m_cfgVlanMemberTable;
Table m_statePortTable, m_stateLagTable;
Table m_stateVlanTable, m_stateVlanMemberTable;
Expand All @@ -30,6 +34,8 @@ class VlanMgr : public Orch
void doTask(Consumer &consumer);
void doVlanTask(Consumer &consumer);
void doVlanMemberTask(Consumer &consumer);
void doVlanStackTask(Consumer &consumer);
void doVlanXlateTask(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 @@ -55,6 +55,8 @@ int main(int argc, char **argv)
vector<string> cfg_vlan_tables = {
CFG_VLAN_TABLE_NAME,
CFG_VLAN_MEMBER_TABLE_NAME,
CFG_VLAN_STACKING_TABLE_NAME,
CFG_VLAN_TRANSLATION_TABLE_NAME
};

DBConnector cfgDb("CONFIG_DB", 0);
Expand Down
4 changes: 3 additions & 1 deletion orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ bool OrchDaemon::init()
{ APP_VLAN_TABLE_NAME, portsorch_base_pri + 2 },
{ APP_VLAN_MEMBER_TABLE_NAME, portsorch_base_pri },
{ APP_LAG_TABLE_NAME, portsorch_base_pri + 4 },
{ APP_LAG_MEMBER_TABLE_NAME, portsorch_base_pri }
{ APP_LAG_MEMBER_TABLE_NAME, portsorch_base_pri },
{ APP_VLAN_STACKING_TABLE_NAME, portsorch_base_pri },
{ APP_VLAN_TRANSLATION_TABLE_NAME, portsorch_base_pri }
};

vector<table_name_with_pri_t> app_fdb_tables = {
Expand Down
Loading