Skip to content
Merged
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
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;
}