Skip to content

Commit

Permalink
[intfmgrd]: Merge intfsyncd into intfmgrd (sonic-net#635)
Browse files Browse the repository at this point in the history
* [intfmgrd]: Merge intfsyncd into intfmgrd

Move intfsyncd functionality to intfmgrd, add VRF membership support.
  • Loading branch information
marian-pritsak authored and prsunny committed Dec 27, 2018
1 parent a45c7b5 commit 0c07a80
Show file tree
Hide file tree
Showing 15 changed files with 327 additions and 231 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ deps/
###############
teamsyncd/teamsyncd
fpmsyncd/fpmsyncd
intfsyncd/intfsyncd
cfgmgr/buffermgrd
cfgmgr/intfmgrd
cfgmgr/portmgrd
Expand Down
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS = fpmsyncd neighsyncd intfsyncd portsyncd orchagent swssconfig cfgmgr
SUBDIRS = fpmsyncd neighsyncd portsyncd orchagent swssconfig cfgmgr

if HAVE_LIBTEAM
SUBDIRS += teamsyncd
Expand Down
169 changes: 138 additions & 31 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using namespace swss;

#define VLAN_PREFIX "Vlan"
#define LAG_PREFIX "PortChannel"
#define VNET_PREFIX "Vnet"

IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) :
Orch(cfgDb, tableNames),
Expand All @@ -21,12 +22,13 @@ IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
m_statePortTable(stateDb, STATE_PORT_TABLE_NAME),
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME),
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME),
m_stateVrfTable(stateDb, STATE_VRF_TABLE_NAME),
m_stateIntfTable(stateDb, STATE_INTERFACE_TABLE_NAME),
m_appIntfTableProducer(appDb, APP_INTF_TABLE_NAME)
{
}

bool IntfMgr::setIntfIp(const string &alias, const string &opCmd,
void IntfMgr::setIntfIp(const string &alias, const string &opCmd,
const string &ipPrefixStr, const bool ipv4)
{
stringstream cmd;
Expand All @@ -41,7 +43,26 @@ bool IntfMgr::setIntfIp(const string &alias, const string &opCmd,
cmd << IP_CMD << " -6 address " << opCmd << " " << ipPrefixStr << " dev " << alias;
}
int ret = swss::exec(cmd.str(), res);
return (ret == 0);
if (ret)
{
SWSS_LOG_ERROR("Command '%s' failed with rc %d", cmd.str().c_str(), ret);
}
}

void IntfMgr::setIntfVrf(const string &alias, const string vrfName)
{
stringstream cmd;
string res;

if (!vrfName.empty())
{
cmd << IP_CMD << " link set " << alias << " master " << vrfName;
}
else
{
cmd << IP_CMD << " link set " << alias << " nomaster";
}
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}

bool IntfMgr::isIntfStateOk(const string &alias)
Expand All @@ -64,6 +85,14 @@ bool IntfMgr::isIntfStateOk(const string &alias)
return true;
}
}
else if (!alias.compare(0, strlen(VNET_PREFIX), VNET_PREFIX))
{
if (m_stateVrfTable.get(alias, temp))
{
SWSS_LOG_DEBUG("Vnet %s is ready", alias.c_str());
return true;
}
}
else if (m_statePortTable.get(alias, temp))
{
SWSS_LOG_DEBUG("Port %s is ready", alias.c_str());
Expand All @@ -72,55 +101,133 @@ bool IntfMgr::isIntfStateOk(const string &alias)

return false;
}
void IntfMgr::doTask(Consumer &consumer)

bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
const vector<FieldValueTuple>& data,
const string& op)
{
SWSS_LOG_ENTER();

auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
string alias(keys[0]);
string vrf_name = "";

for (auto idx : data)
{
KeyOpFieldsValuesTuple t = it->second;
const auto &field = fvField(idx);
const auto &value = fvValue(idx);
if (field == "vnet_name" || field == "vrf_name")
{
vrf_name = value;
}
}

vector<string> keys = tokenize(kfvKey(t), config_db_key_delimiter);
if (op == SET_COMMAND)
{
if (!isIntfStateOk(alias))
{
SWSS_LOG_DEBUG("Interface is not ready, skipping %s", alias.c_str());
return false;
}

if (keys.size() != 2)
if (!vrf_name.empty() && !isIntfStateOk(vrf_name))
{
SWSS_LOG_ERROR("Invalid key %s", kfvKey(t).c_str());
it = consumer.m_toSync.erase(it);
continue;
SWSS_LOG_DEBUG("VRF is not ready, skipping %s", vrf_name.c_str());
return false;
}

setIntfVrf(alias, vrf_name);
m_appIntfTableProducer.set(alias, data);
}
else if (op == DEL_COMMAND)
{
setIntfVrf(alias, "");
m_appIntfTableProducer.del(alias);
}
else
{
SWSS_LOG_ERROR("Unknown operation: %s", op.c_str());
}

return true;
}

bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
const vector<FieldValueTuple>& data,
const string& op)
{
SWSS_LOG_ENTER();

string alias(keys[0]);
IpPrefix ip_prefix(keys[1]);
string appKey = keys[0] + ":" + keys[1];

if (op == SET_COMMAND)
{
/*
* Don't proceed if port/LAG/VLAN is not ready yet.
* The pending task will be checked periodically and retried.
*/
if (!isIntfStateOk(alias))
{
SWSS_LOG_DEBUG("Interface is not ready, skipping %s", alias.c_str());
return false;
}

string alias(keys[0]);
IpPrefix ip_prefix(keys[1]);
setIntfIp(alias, "add", ip_prefix.to_string(), ip_prefix.isV4());

std::vector<FieldValueTuple> fvVector;
FieldValueTuple f("family", ip_prefix.isV4() ? IPV4_NAME : IPV6_NAME);
FieldValueTuple s("scope", "global");
fvVector.push_back(s);
fvVector.push_back(f);

m_appIntfTableProducer.set(appKey, fvVector);
m_stateIntfTable.hset(keys[0] + state_db_key_delimiter + keys[1], "state", "ok");
}
else if (op == DEL_COMMAND)
{
setIntfIp(alias, "del", ip_prefix.to_string(), ip_prefix.isV4());
m_appIntfTableProducer.del(appKey);
m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]);
}
else
{
SWSS_LOG_ERROR("Unknown operation: %s", op.c_str());
}

return true;
}

void IntfMgr::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();

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

vector<string> keys = tokenize(kfvKey(t), config_db_key_delimiter);
const vector<FieldValueTuple>& data = kfvFieldsValues(t);
string op = kfvOp(t);
if (op == SET_COMMAND)

if (keys.size() == 1)
{
/*
* Don't proceed if port/LAG/VLAN is not ready yet.
* The pending task will be checked periodically and retried.
* TODO: Subscribe to stateDB for port/lag/VLAN state and retry
* pending tasks immediately upon state change.
*/
if (!isIntfStateOk(alias))
if (!doIntfGeneralTask(keys, data, op))
{
SWSS_LOG_DEBUG("Interface is not ready, skipping %s", kfvKey(t).c_str());
it++;
continue;
}
setIntfIp(alias, "add", ip_prefix.to_string(), ip_prefix.isV4());
m_stateIntfTable.hset(keys[0] + state_db_key_delimiter + keys[1], "state", "ok");
SWSS_LOG_NOTICE("Add %s to %s", ip_prefix.to_string().c_str(), alias.c_str());
}
else if (op == DEL_COMMAND)
else if (keys.size() == 2)
{
setIntfIp(alias, "del", ip_prefix.to_string(), ip_prefix.isV4());
m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]);
SWSS_LOG_NOTICE("Remove %s from %s", ip_prefix.to_string().c_str(), alias.c_str());
if (!doIntfAddrTask(keys, data, op))
{
continue;
}
}
else
{
SWSS_LOG_ERROR("Unknown operation: %s", op.c_str());
SWSS_LOG_ERROR("Invalid key %s", kfvKey(t).c_str());
}

it = consumer.m_toSync.erase(it);
Expand Down
7 changes: 5 additions & 2 deletions cfgmgr/intfmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ class IntfMgr : public Orch
private:
ProducerStateTable m_appIntfTableProducer;
Table m_cfgIntfTable, m_cfgVlanIntfTable;
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateIntfTable;
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable;

bool setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr, const bool ipv4 = true);
void setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr, const bool ipv4 = true);
void setIntfVrf(const string &alias, const string vrfName);
bool doIntfGeneralTask(const vector<string>& keys, const vector<FieldValueTuple>& data, const string& op);
bool doIntfAddrTask(const vector<string>& keys, const vector<FieldValueTuple>& data, const string& op);
void doTask(Consumer &consumer);
bool isIntfStateOk(const string &alias);
};
Expand Down
1 change: 0 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ AC_CONFIG_FILES([
orchagent/Makefile
fpmsyncd/Makefile
neighsyncd/Makefile
intfsyncd/Makefile
portsyncd/Makefile
teamsyncd/Makefile
swssconfig/Makefile
Expand Down
4 changes: 1 addition & 3 deletions doc/swss-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Stores information for physical switch ports managed by the switch chip. Ports t

---------------------------------------------
### INTF_TABLE
intfsyncd manages this table. In SONiC, CPU (management) and logical ports (vlan, loopback, LAG) are declared in /etc/network/interface and loaded into the INTF_TABLE.
cfgmgrd manages this table. In SONiC, CPU (management) and logical ports (vlan, loopback, LAG) are declared in /etc/network/interface and /etc/sonic/config_db.json and loaded into the INTF_TABLE.

IP prefixes are formatted according to [RFC5954](https://tools.ietf.org/html/rfc5954) with a prefix length appended to the end

Expand Down Expand Up @@ -802,5 +802,3 @@ What configuration files should we have? Do apps, orch agent each need separate
[port_config.ini](https://github.com/stcheng/swss/blob/mock/portsyncd/port_config.ini) - defines physical port information

portsyncd reads from port_config.ini and updates PORT_TABLE in APP_DB

All other apps (intfsyncd) read from PORT_TABLE in APP_DB
16 changes: 0 additions & 16 deletions intfsyncd/Makefile.am

This file was deleted.

64 changes: 0 additions & 64 deletions intfsyncd/intfsync.cpp

This file was deleted.

25 changes: 0 additions & 25 deletions intfsyncd/intfsync.h

This file was deleted.

Loading

0 comments on commit 0c07a80

Please sign in to comment.