Skip to content

Commit

Permalink
[configdb]: configDB enforcer for interface (sonic-net#357)
Browse files Browse the repository at this point in the history
* configDB enforcer for interface

Support VLAN interface only for now

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>

* Use OrchBase for configDB intf configuration enforcer

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>

* Rename intfconf to intfmgr

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>

* Use shell full path command macros

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>

* Optimize shell command execution error handling

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>

* Use Orch class for intfmgrd orchestration

Signed-off-by: Jipan Yang <jipan.yang@alibaba-inc.com>
  • Loading branch information
jipanyang authored and lguohan committed Nov 5, 2017
1 parent 021ef4f commit 6e84504
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ deps/
teamsyncd/teamsyncd
fpmsyncd/fpmsyncd
intfsyncd/intfsyncd
cfgmgr/intfmgrd
cfgmgr/vlanmgrd
neighsyncd/neighsyncd
portsyncd/portsyncd
Expand Down
6 changes: 5 additions & 1 deletion cfgmgr/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/orchagent
CFLAGS_SAI = -I /usr/include/sai

bin_PROGRAMS = vlanmgrd
bin_PROGRAMS = vlanmgrd intfmgrd

if DEBUG
DBGFLAGS = -ggdb -DDEBUG
Expand All @@ -14,3 +14,7 @@ vlanmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
vlanmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
vlanmgrd_LDADD = -lswsscommon

intfmgrd_SOURCES = intfmgrd.cpp intfmgr.cpp $(top_srcdir)/orchagent/orch.cpp shellcmd.h
intfmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
intfmgrd_LDADD = -lswsscommon
126 changes: 126 additions & 0 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include <string.h>
#include "logger.h"
#include "dbconnector.h"
#include "producerstatetable.h"
#include "tokenize.h"
#include "ipprefix.h"
#include "intfmgr.h"
#include "exec.h"
#include "shellcmd.h"

using namespace std;
using namespace swss;

#define VLAN_PREFIX "Vlan"
#define LAG_PREFIX "PortChannel"

IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) :
Orch(cfgDb, tableNames),
m_cfgIntfTable(cfgDb, CFG_INTF_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
m_cfgVlanIntfTable(cfgDb, CFG_VLAN_INTF_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
m_statePortTable(stateDb, STATE_PORT_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
m_appIntfTableProducer(appDb, APP_INTF_TABLE_NAME)
{
}

bool IntfMgr::setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr)
{
stringstream cmd;
string res;

cmd << IP_CMD << " address " << opCmd << " " << ipPrefixStr << " dev " << alias;;
int ret = swss::exec(cmd.str(), res);
return (ret == 0);
}

bool IntfMgr::isIntfStateOk(const string &alias)
{
vector<FieldValueTuple> temp;

if (!alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX))
{
if (m_stateVlanTable.get(alias, temp))
{
SWSS_LOG_DEBUG("Vlan %s is ready", alias.c_str());
return true;
}
}
else if (!alias.compare(0, strlen(LAG_PREFIX), LAG_PREFIX))
{
if (m_stateLagTable.get(alias, temp))
{
SWSS_LOG_DEBUG("Lag %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());
return true;
}

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

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

string keySeparator = CONFIGDB_KEY_SEPARATOR;
vector<string> keys = tokenize(kfvKey(t), keySeparator[0]);
string alias(keys[0]);

if (alias.compare(0, strlen(VLAN_PREFIX), VLAN_PREFIX))
{
/* handle IP over vlan Only for now, skip the rest */
it = consumer.m_toSync.erase(it);
continue;
}

size_t pos = kfvKey(t).find(CONFIGDB_KEY_SEPARATOR);
if (pos == string::npos)
{
SWSS_LOG_DEBUG("Invalid key %s", kfvKey(t).c_str());
it = consumer.m_toSync.erase(it);
continue;
}
IpPrefix ip_prefix(kfvKey(t).substr(pos+1));

SWSS_LOG_DEBUG("intfs doTask: %s", (dumpTuple(consumer, t)).c_str());

string op = kfvOp(t);
if (op == SET_COMMAND)
{
/*
* Don't proceed if port/lag/VLAN is not ready yet.
* The pending task will be checked periodially 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", kfvKey(t).c_str());
it++;
continue;
}
string opCmd("add");
string ipPrefixStr = ip_prefix.to_string();
setIntfIp(alias, opCmd, ipPrefixStr);
}
else if (op == DEL_COMMAND)
{
string opCmd("del");
string ipPrefixStr = ip_prefix.to_string();
setIntfIp(alias, opCmd, ipPrefixStr);
}

it = consumer.m_toSync.erase(it);
continue;
}
}
30 changes: 30 additions & 0 deletions cfgmgr/intfmgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef __INTFMGR__
#define __INTFMGR__

#include "dbconnector.h"
#include "producerstatetable.h"
#include "orch.h"

#include <map>
#include <string>

namespace swss {

class IntfMgr : public Orch
{
public:
IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames);

private:
ProducerStateTable m_appIntfTableProducer;
Table m_cfgIntfTable, m_cfgVlanIntfTable;
Table m_statePortTable, m_stateLagTable, m_stateVlanTable;

bool setIntfIp(const string &alias, const string &opCmd, const string &ipPrefixStr);
void doTask(Consumer &consumer);
bool isIntfStateOk(const string &alias);
};

}

#endif
97 changes: 97 additions & 0 deletions cfgmgr/intfmgrd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include <unistd.h>
#include <vector>
#include <mutex>
#include "dbconnector.h"
#include "select.h"
#include "exec.h"
#include "schema.h"
#include "intfmgr.h"
#include <fstream>
#include <iostream>

using namespace std;
using namespace swss;

/* select() function timeout retry time, in millisecond */
#define SELECT_TIMEOUT 1000

/*
* Following global variables are defined here for the purpose of
* using existing Orch class which is to be refactored soon to
* eliminate the direct exposure of the global variables.
*
* Once Orch class refactoring is done, these global variables
* should be removed from here.
*/
int gBatchSize = 0;
bool gSwssRecord = false;
bool gLogRotate = false;
ofstream gRecordOfs;
string gRecordFile;
/* Global database mutex */
mutex gDbMutex;

int main(int argc, char **argv)
{
Logger::linkToDbNative("intfmgrd");
SWSS_LOG_ENTER();

SWSS_LOG_NOTICE("--- Starting intfmgrd ---");

try
{
vector<string> cfg_intf_tables = {
CFG_INTF_TABLE_NAME,
CFG_LAG_INTF_TABLE_NAME,
CFG_VLAN_INTF_TABLE_NAME,
};

DBConnector cfgDb(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
DBConnector appDb(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
DBConnector stateDb(STATE_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);

IntfMgr intfmgr(&cfgDb, &appDb, &stateDb, cfg_intf_tables);

// TODO: add tables in stateDB which interface depends on to monitor list
std::vector<Orch *> cfgOrchList = {&intfmgr};

swss::Select s;
for (Orch *o : cfgOrchList)
{
s.addSelectables(o->getSelectables());
}

SWSS_LOG_NOTICE("starting main loop");
while (true)
{
Selectable *sel;
int fd, ret;

ret = s.select(&sel, &fd, SELECT_TIMEOUT);
if (ret == Select::ERROR)
{
SWSS_LOG_NOTICE("Error: %s!", strerror(errno));
continue;
}
if (ret == Select::TIMEOUT)
{
((Orch *)&intfmgr)->doTask();
continue;
}

for (Orch *o : cfgOrchList)
{
TableConsumable *c = (TableConsumable *)sel;
if (o->hasSelectable(c))
{
o->execute(c->getTableName());
}
}
}
}
catch(const std::exception &e)
{
SWSS_LOG_ERROR("Runtime error: %s", e.what());
}
return -1;
}

0 comments on commit 6e84504

Please sign in to comment.