Skip to content

Commit

Permalink
[intfmgrd]: Merge intfsyncd into intfmgrd
Browse files Browse the repository at this point in the history
Move intfsyncd functionality to intfmgrd, add VRF membership support.

Signed-off-by: Marian Pritsak <marianp@mellanox.com>
  • Loading branch information
marian-pritsak committed Oct 2, 2018
1 parent 94fbcd9 commit ab1741c
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 189 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/intfmgrd
cfgmgr/vlanmgrd
cfgmgr/buffermanager
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
165 changes: 140 additions & 25 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,6 +22,7 @@ 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_appIntfTableProducer(appDb, APP_INTF_TABLE_NAME)
{
}
Expand All @@ -43,6 +45,23 @@ bool IntfMgr::setIntfIp(const string &alias, const string &opCmd,
return (ret == 0);
}

bool 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";
}
int ret = swss::exec(cmd.str(), res);
return (ret == 0);
}

bool IntfMgr::isIntfStateOk(const string &alias)
{
vector<FieldValueTuple> temp;
Expand All @@ -63,6 +82,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 @@ -71,51 +98,139 @@ 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)
{
/*
* 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))
{
SWSS_LOG_DEBUG("Interface is not ready, skipping %s", alias.c_str());
return false;
}

if (keys.size() != 2)
if (!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.
* TODO: Subscribe to stateDB for port/lag/VLAN state and retry
* pending tasks immediately upon state change.
*/
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);
}
else if (op == DEL_COMMAND)
{
setIntfIp(alias, "del", ip_prefix.to_string(), ip_prefix.isV4());
m_appIntfTableProducer.del(appKey);
}
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());
}
else if (op == DEL_COMMAND)
else if (keys.size() == 2)
{
setIntfIp(alias, "del", ip_prefix.to_string(), ip_prefix.isV4());
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
5 changes: 4 additions & 1 deletion 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;
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable;

bool setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr, const bool ipv4 = true);
bool 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 @@ -751,5 +751,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 ab1741c

Please sign in to comment.