Skip to content

VLAN trunk support: cfgagent update. #297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
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
188 changes: 188 additions & 0 deletions cfgagent/cfgagentd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#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

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;
}

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 '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((Subscriber *)sel))
{
o->execute(((Subscriber *)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