Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ deps/
teamsyncd/teamsyncd
fpmsyncd/fpmsyncd
intfsyncd/intfsyncd
cfgagent/cfgagent
cfgagent/cfgmgr
neighsyncd/neighsyncd
portsyncd/portsyncd
orchagent/orchagent
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
SUBDIRS = fpmsyncd neighsyncd intfsyncd portsyncd orchagent swssconfig cfgagent

if HAVE_LIBTEAM
SUBDIRS += teamsyncd
Expand Down
18 changes: 18 additions & 0 deletions cfgagent/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
INCLUDES = -I $(top_srcdir)
CFLAGS_SAI = -I /usr/include/sai

bin_PROGRAMS = cfgagentd

if DEBUG
DBGFLAGS = -ggdb -DDEBUG
else
DBGFLAGS = -g
endif

cfgagentd_SOURCES = cfgagentd.cpp vlancfgagent.cpp portcfgagent.cpp intfcfgagent.cpp switchcfgagent.cpp cfgorch.cpp

cfgagentd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
cfgagentd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
cfgagentd_LDADD = -lswsscommon

SUBDIRS = cfgmgrtest
195 changes: 195 additions & 0 deletions cfgagent/cfgagentd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#include <getopt.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <mutex>
#include "dbconnector.h"
#include "select.h"
#include "exec.h"
#include "netdispatcher.h"
#include "producerstatetable.h"
#include "cfgagent/vlancfgagent.h"
#include "cfgagent/portcfgagent.h"
#include "cfgagent/intfcfgagent.h"
#include "cfgagent/switchcfgagent.h"

using namespace std;
using namespace swss;

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

#define DEFAULT_BATCH_SIZE 128
int gBatchSize = DEFAULT_BATCH_SIZE;

MacAddress gMacAddress;
bool gInitDone = false;
bool gSwssCfgRecord = true;
ofstream gCfgRecordOfs;
string gCfgRecordFile;
/* Global database mutex */
mutex gDbMutex;

SwitchCfgAgent *gSwtichcfgagent;

void usage()
{
cout << "usage: cfgagent [-h] [-r record_type] [-d record_location] [-b batch_size]" << endl;
cout << " -h: display this message" << endl;
cout << " -r record_type: record orchagent logs with type (default 3)" << endl;
cout << " 0: do not record logs" << endl;
cout << " 1: record SwSS task sequence as swss.cfg.*.rec" << endl;
cout << " -d record_location: set record logs folder location (default .)" << endl;
cout << " -b batch_size: set consumer table pop operation batch size (default 128)" << endl;
}

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

int opt;
string record_location = ".";
bool teamd_init_done = false;

while ((opt = getopt(argc, argv, "b:r:d:h")) != -1)
{
switch (opt)
{
case 'b':
gBatchSize = atoi(optarg);
break;
case 'r':
if (!strcmp(optarg, "0"))
{
gSwssCfgRecord = false;
}
else if (!strcmp(optarg, "1"))
{
continue; /* default behavior */
}
else
{
usage();
exit(EXIT_FAILURE);
}
break;
case 'd':
record_location = optarg;
if (access(record_location.c_str(), W_OK))
{
SWSS_LOG_ERROR("Failed to access writable directory %s", record_location.c_str());
exit(EXIT_FAILURE);
}
break;
case 'h':
usage();
exit(EXIT_SUCCESS);
default: /* '?' */
exit(EXIT_FAILURE);
}
}

SWSS_LOG_NOTICE("--- Starting cfgagentd ---");

/* Disable/enable SwSS cfg recording */
if (gSwssCfgRecord)
{
gCfgRecordFile = record_location + "/" + "swss.cfg.rec";
gCfgRecordOfs.open(gCfgRecordFile, std::ofstream::out | std::ofstream::app);

if (!gCfgRecordOfs.is_open())
{
SWSS_LOG_ERROR("Failed to open SwSS recording file %s", gCfgRecordFile.c_str());
exit(EXIT_FAILURE);
}
}
gMacAddress = swss::exec("ip link show eth0 | grep ether | awk '{print $2}'");

try
{
vector<string> cfg_vlan_tables = {
CFG_VLAN_TABLE_NAME,
CFG_VLAN_MEMBER_TABLE_NAME,
};

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

Table porttableconsumer(&appDb, APP_PORT_TABLE_NAME);
Table lagtableconsumer(&appDb, APP_LAG_TABLE_NAME);

PortCfgAgent portcfgagent(&cfgDb, &appDb, CFG_PORT_TABLE_NAME);
VlanCfgAgent vlancfgagent(&cfgDb, &appDb, cfg_vlan_tables);
IntfCfgAgent intfcfgagent(&cfgDb, &appDb, CFG_INTF_TABLE_NAME);
gSwtichcfgagent = new SwitchCfgAgent(&cfgDb, &appDb, CFG_SWITCH_TABLE_NAME);
std::vector<CfgOrch *> cfgOrchList = {&vlancfgagent, &portcfgagent, &intfcfgagent, gSwtichcfgagent};

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

gSwtichcfgagent->syncCfgDB();
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!\n", strerror(errno));
continue;
}
if (ret == Select::TIMEOUT)
{
if (gInitDone == false)
{
vector<FieldValueTuple> temp;
if (porttableconsumer.get("ConfigDone", temp))
{
gInitDone = true;
SWSS_LOG_NOTICE("Physical ports hostif init done\n");
}
}
else
{
if (teamd_init_done == false)
{
vector<FieldValueTuple> temp;
if (lagtableconsumer.get("ConfigDone", temp))
{
teamd_init_done = true;
SWSS_LOG_NOTICE("Teamd lag init done\n");
vlancfgagent.syncCfgDB();
/* Sync interface config after VLAN */
intfcfgagent.syncCfgDB();
}
}
}
continue;
}

for (CfgOrch *o : cfgOrchList)
{
if (o->hasSelectable((ConsumerStateTable *)sel))
{
o->execute(((ConsumerStateTable *)sel)->getTableName());
}
}
}
}
catch(const std::exception &e)
{
SWSS_LOG_ERROR("Runtime error: %s", e.what());
}
return 0;
}
16 changes: 16 additions & 0 deletions cfgagent/cfgmgrtest/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
INCLUDES = -I $(top_srcdir)

bin_PROGRAMS = cfgmgr

if DEBUG
DBGFLAGS = -ggdb -DDEBUG
else
DBGFLAGS = -g
endif


cfgmgr_SOURCES = cfgmgr.cpp vlancfgmgr.cpp portcfgmgr.cpp \
lagcfgmgr.cpp intfcfgmgr.cpp switchcfgmgr.cpp
cfgmgr_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
cfgmgr_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
cfgmgr_LDADD = -lswsscommon
64 changes: 64 additions & 0 deletions cfgagent/cfgmgrtest/cfgmgr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "cfgmgr.h"

using namespace std;

[[ noreturn ]] void usage()
{
std::cout << "Usage: cfgmgr OBJECT { COMMAND | help }" << std::endl
<< "\t where OBJECT := { port | lag | vlan | intf | switch }\n" << std::endl;
exit(0);
}

void incomplete_command(void)
{
std::cout << "Command line is not complete. Try option \"help\" " << std::endl;
exit(-1);
}

int matches(const char *cmd, const char *pattern)
{
size_t len = strlen(cmd);

if (len > strlen(pattern))
return -1;
return memcmp(pattern, cmd, len);
}

static int do_help(int argc, char **argv)
{
usage();
}

static const struct cmd {
const char *cmd;
int (*func)(int argc, char **argv);
} cmds[] = {
{ "port", do_port },
{ "lag", do_lag },
{ "intf", do_intf },
{ "vlan", do_vlan },
{ "switch", do_switch },
{ "help", do_help },
{ NULL, NULL }
};

static int do_cmd(const char *argv0, int argc, char **argv)
{
const struct cmd *c;

for (c = cmds; c->cmd; ++c) {
if (matches(argv0, c->cmd) == 0)
return c->func(argc-1, argv+1);
}

cout << "Object " << argv0 << " is unknown, try \"cfgmgr help\".\n" << std::endl;
return -1;
}

int main(int argc, char **argv)
{
if (argc > 1)
return do_cmd(argv[1], argc-1, argv+1);

usage();
}
26 changes: 26 additions & 0 deletions cfgagent/cfgmgrtest/cfgmgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef __CFGMGR__
#define __CFGMGR__

#include <iostream>
#include <functional>
#include <algorithm>
#include <unistd.h>
#include <net/if.h>
#include <cerrno>
#include <cstring>

extern int do_port(int argc, char **argv);
extern int do_lag(int argc, char **argv);
extern int do_intf(int argc, char **argv);
extern int do_vlan(int argc, char **argv);
extern int do_switch(int argc, char **argv);

#define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0)
#define NEXT_ARG_OK() (argc - 1 > 0)
#define NEXT_ARG_FWD() do { argv++; argc--; } while(0)
#define PREV_ARG() do { argv--; argc++; } while(0)

extern void incomplete_command(void);
extern int matches(const char *cmd, const char *pattern);

#endif
Loading