Skip to content

Commit 31ab4b8

Browse files
committed
cfgmgr debug CLI for vlan, intf and switch
Signed-off-by: Jipan Yang <[email protected]>
1 parent 136621b commit 31ab4b8

File tree

13 files changed

+946
-1
lines changed

13 files changed

+946
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ deps/
4343
teamsyncd/teamsyncd
4444
fpmsyncd/fpmsyncd
4545
intfsyncd/intfsyncd
46+
cfgmgr/cfgmgrtest/cfgmgr
4647
neighsyncd/neighsyncd
4748
portsyncd/portsyncd
4849
orchagent/orchagent

Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SUBDIRS = fpmsyncd neighsyncd intfsyncd portsyncd orchagent swssconfig
1+
SUBDIRS = fpmsyncd neighsyncd intfsyncd portsyncd orchagent swssconfig cfgmgr
22

33
if HAVE_LIBTEAM
44
SUBDIRS += teamsyncd

cfgmgr/Makefile.am

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/orchagent
2+
CFLAGS_SAI = -I /usr/include/sai
3+
4+
bin_PROGRAMS = vlanmgrd intfmgrd
5+
6+
if DEBUG
7+
DBGFLAGS = -ggdb -DDEBUG
8+
else
9+
DBGFLAGS = -g
10+
endif
11+
12+
vlanmgrd_SOURCES = vlanmgrd.cpp vlanmgr.cpp $(top_srcdir)/orchagent/orch.cpp shellcmd.h
13+
vlanmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
14+
vlanmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
15+
vlanmgrd_LDADD = -lswsscommon
16+
17+
18+
intfmgrd_SOURCES = intfmgrd.cpp intfmgr.cpp $(top_srcdir)/orchagent/orch.cpp shellcmd.h
19+
intfmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
20+
intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
21+
intfmgrd_LDADD = -lswsscommon
22+
23+
SUBDIRS = cfgmgrtest

cfgmgr/cfgmgrtest/Makefile.am

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/orchagent -I $(top_srcdir)/cfgmgr
2+
CFLAGS_SAI = -I /usr/include/sai
3+
4+
bin_PROGRAMS = cfgmgr
5+
6+
if DEBUG
7+
DBGFLAGS = -ggdb -DDEBUG
8+
else
9+
DBGFLAGS = -g
10+
endif
11+
12+
13+
cfgmgr_SOURCES = cfgmgr.cpp vlancfgmgr.cpp intfcfgmgr.cpp switchcfgmgr.cpp
14+
cfgmgr_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
15+
cfgmgr_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
16+
cfgmgr_LDADD = -lswsscommon

cfgmgr/cfgmgrtest/cfgmgr.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "cfgmgr.h"
2+
3+
using namespace std;
4+
5+
[[ noreturn ]] void usage()
6+
{
7+
std::cout << "Usage: cfgmgr OBJECT { COMMAND | help }" << std::endl
8+
<< "\t where OBJECT := { vlan | intf | switch }\n" << std::endl;
9+
exit(0);
10+
}
11+
12+
void incomplete_command(void)
13+
{
14+
std::cout << "Command line is not complete. Try option \"help\" " << std::endl;
15+
exit(-1);
16+
}
17+
18+
int matches(const char *cmd, const char *pattern)
19+
{
20+
size_t len = strlen(cmd);
21+
22+
if (len > strlen(pattern))
23+
return -1;
24+
return memcmp(pattern, cmd, len);
25+
}
26+
27+
static int do_help(int argc, char **argv)
28+
{
29+
usage();
30+
}
31+
32+
static const struct cmd {
33+
const char *cmd;
34+
int (*func)(int argc, char **argv);
35+
} cmds[] = {
36+
{ "intf", do_intf },
37+
{ "vlan", do_vlan },
38+
{ "switch", do_switch },
39+
{ "help", do_help },
40+
{ NULL, NULL }
41+
};
42+
43+
static int do_cmd(const char *argv0, int argc, char **argv)
44+
{
45+
const struct cmd *c;
46+
47+
for (c = cmds; c->cmd; ++c) {
48+
if (matches(argv0, c->cmd) == 0)
49+
return c->func(argc-1, argv+1);
50+
}
51+
52+
cout << "Object " << argv0 << " is unknown, try \"cfgmgr help\".\n" << std::endl;
53+
return -1;
54+
}
55+
56+
int main(int argc, char **argv)
57+
{
58+
if (argc > 1)
59+
return do_cmd(argv[1], argc-1, argv+1);
60+
61+
usage();
62+
}

cfgmgr/cfgmgrtest/cfgmgr.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef __CFGMGR__
2+
#define __CFGMGR__
3+
4+
#include <iostream>
5+
#include <functional>
6+
#include <algorithm>
7+
#include <unistd.h>
8+
#include <net/if.h>
9+
#include <cerrno>
10+
#include <cstring>
11+
12+
typedef enum ShowOpEnum_ {
13+
SHOW_NONE = 0,
14+
SHOW_CONFIG,
15+
SHOW_STATE,
16+
} ShowOpEnum;
17+
18+
extern int do_intf(int argc, char **argv);
19+
extern int do_vlan(int argc, char **argv);
20+
extern int do_switch(int argc, char **argv);
21+
22+
#define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0)
23+
#define NEXT_ARG_OK() (argc - 1 > 0)
24+
#define NEXT_ARG_FWD() do { argv++; argc--; } while(0)
25+
#define PREV_ARG() do { argv--; argc++; } while(0)
26+
27+
extern void incomplete_command(void);
28+
extern int matches(const char *cmd, const char *pattern);
29+
30+
#endif

cfgmgr/cfgmgrtest/intfcfgmgr.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#include <iostream>
2+
#include <sstream>
3+
#include <iomanip>
4+
#include <vector>
5+
#include <functional>
6+
#include <algorithm>
7+
#include <unistd.h>
8+
#include <net/if.h>
9+
#include <cerrno>
10+
#include <cstring>
11+
#include "schema.h"
12+
#include "exec.h"
13+
#include "cfgmgr.h"
14+
#include "intfcfgmgr.h"
15+
#include "orch.h"
16+
#include "shellcmd.h"
17+
18+
using namespace std;
19+
using namespace swss;
20+
21+
const string INTFS_PREFIX = "Ethernet";
22+
const string VLAN_PREFIX = "Vlan";
23+
const string LAG_PREFIX = "PortChannel";
24+
25+
[[ noreturn ]] static void usage(std::string program, int status, std::string message)
26+
{
27+
if (message.size() != 0)
28+
{
29+
std::cout << message << std::endl << std::endl;
30+
}
31+
std::cout << "Usage: " << program << " intf { add | del } PREFIX dev IFNAME\n" << std::endl
32+
<< "\t" << program << " intf show <config | state> [ dev IFNAME ]" << std::endl;
33+
34+
exit(status);
35+
}
36+
37+
int IntfCfgMgr::intf_modify(Operation cmd, int argc, char **argv)
38+
{
39+
char *dev = NULL;
40+
string key;
41+
string prefix;
42+
string scope = "global";
43+
string family = IPV4_NAME;
44+
Table *table;
45+
46+
if (argc <= 0) {
47+
usage("cfgmgr", -1, "Invalid option");
48+
}
49+
50+
// TODO: more validity check on prefix.
51+
prefix = *argv;
52+
53+
NEXT_ARG();
54+
while (argc > 0) {
55+
if (matches(*argv, "dev") == 0) {
56+
NEXT_ARG();
57+
dev = *argv;
58+
} else {
59+
if (matches(*argv, "help") == 0) {
60+
usage("cfgmgr", 0, "");
61+
}
62+
}
63+
argc--; argv++;
64+
}
65+
66+
if (dev == NULL) {
67+
cout << "dev IFNAME is required arguments" << endl;
68+
usage("cfgmgr", -1, "Invalid option");
69+
}
70+
71+
if (if_nametoindex(dev) == 0) {
72+
cout << "Cannot find device " << dev << " : " << std::strerror(errno) << endl;
73+
return -1;
74+
}
75+
76+
key = dev;
77+
key += CONFIGDB_KEY_SEPARATOR;
78+
key += prefix;
79+
80+
if (!key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX))
81+
{
82+
table = &m_cfgIntfTable;
83+
}
84+
else if (!key.compare(0, LAG_PREFIX.length(), LAG_PREFIX))
85+
{
86+
table = &m_cfgLagIntfTable;
87+
}
88+
else if (!key.compare(0, VLAN_PREFIX.length(), VLAN_PREFIX))
89+
{
90+
table = &m_cfgVlanIntfTable;
91+
}
92+
else
93+
{
94+
cout << dev << " is not a Ethernet or PortChannel or Vlan interface, not supported for now" << endl;
95+
return -1;
96+
}
97+
98+
if (cmd == IntfCfgMgr::DELETE)
99+
{
100+
table->del(key);
101+
}
102+
else
103+
{
104+
std::vector<FieldValueTuple> fvVector;
105+
FieldValueTuple f("family", family);
106+
FieldValueTuple s("scope", scope);
107+
fvVector.push_back(s);
108+
fvVector.push_back(f);
109+
table->set(key, fvVector);
110+
}
111+
return 0;
112+
}
113+
114+
int IntfCfgMgr::intf_show(int argc, char **argv)
115+
{
116+
char *filter_dev = NULL;
117+
unsigned int if_index;
118+
ShowOpEnum show_op = SHOW_NONE;
119+
short vid = -1;
120+
121+
while (argc > 0) {
122+
if (matches(*argv, "dev") == 0) {
123+
NEXT_ARG();
124+
filter_dev = *argv;
125+
}
126+
else if (matches(*argv, "config") == 0) {
127+
show_op = SHOW_CONFIG;
128+
}
129+
else if (matches(*argv, "state") == 0) {
130+
show_op = SHOW_STATE;
131+
}
132+
argc--; argv++;
133+
}
134+
135+
if (show_op == SHOW_NONE)
136+
{
137+
usage("cfgmgr", 0, "");
138+
}
139+
140+
stringstream cmd;
141+
stringstream redis_cmd_db;
142+
stringstream redis_cmd_keys;
143+
stringstream redis_cmd;
144+
145+
redis_cmd_db << REDIS_CLI_CMD << " -n " << CONFIG_DB << "";
146+
cmd << IP_CMD << " address show ";
147+
redis_cmd_keys << "\\*INTERFACE\\|\\*";
148+
149+
if (vid >= 0) {
150+
redis_cmd_keys << vid << "\\*";
151+
}
152+
153+
if (filter_dev) {
154+
if_index = if_nametoindex(filter_dev);
155+
if (if_index == 0) {
156+
cout << "Cannot find bridge device " << filter_dev << " : " << std::strerror(errno) << endl;
157+
return -1;
158+
}
159+
cmd << " dev " << filter_dev;
160+
161+
redis_cmd_keys << filter_dev << "\\*";
162+
}
163+
164+
redis_cmd << redis_cmd_db.str() << " KEYS " << redis_cmd_keys.str()
165+
<< " | " << XARGS_CMD << " -n 1 -I % sh -c 'echo \"%\"; "
166+
<< redis_cmd_db.str() << " hgetall \"%\" | " << PASTE_CMD <<" -d '=' - - | "
167+
<< SED_CMD <<" 's/^/$/'; " << ECHO_CMD << " '";
168+
169+
string res;
170+
if (show_op == SHOW_CONFIG)
171+
{
172+
cout << "-----Redis ConfigDB data---" << endl;
173+
//cout << redis_cmd <<endl;
174+
175+
EXEC_WITH_ERROR_THROW(redis_cmd.str(), res);
176+
cout << res;
177+
return 0;
178+
}
179+
180+
cout << "----Linux hostenv data----" << endl;
181+
EXEC_WITH_ERROR_THROW(cmd.str(), res);
182+
cout << res << endl;
183+
return 0;
184+
}
185+
186+
IntfCfgMgr::IntfCfgMgr(DBConnector *db) :
187+
m_cfgIntfTable(db, CFG_INTF_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
188+
m_cfgLagIntfTable(db, CFG_LAG_INTF_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR),
189+
m_cfgVlanIntfTable(db, CFG_VLAN_INTF_TABLE_NAME, CONFIGDB_TABLE_NAME_SEPARATOR)
190+
{
191+
192+
}
193+
194+
int do_intf(int argc, char **argv)
195+
{
196+
auto exitWithUsage = std::bind(usage, "cfgmgr", std::placeholders::_1, std::placeholders::_2);
197+
198+
DBConnector db(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
199+
IntfCfgMgr cfgmgr(&db);
200+
201+
if (argc > 0)
202+
{
203+
if (matches(*argv, "add") == 0)
204+
return cfgmgr.intf_modify(IntfCfgMgr::ADD, argc-1, argv+1);
205+
if (matches(*argv, "delete") == 0)
206+
return cfgmgr.intf_modify(IntfCfgMgr::DELETE, argc-1, argv+1);
207+
if (matches(*argv, "show") == 0)
208+
return cfgmgr.intf_show(argc-1, argv+1);
209+
if (matches(*argv, "help") == 0)
210+
exitWithUsage(EXIT_SUCCESS, "");
211+
else
212+
exitWithUsage(EXIT_FAILURE, "Invalid option");
213+
}
214+
else {
215+
exitWithUsage(EXIT_FAILURE, "Invalid option");
216+
}
217+
218+
return EXIT_SUCCESS;
219+
}

cfgmgr/cfgmgrtest/intfcfgmgr.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef __INTFCFGMGR__
2+
#define __INTFCFGMGR__
3+
4+
#include "dbconnector.h"
5+
#include "table.h"
6+
7+
namespace swss {
8+
9+
class IntfCfgMgr
10+
{
11+
public:
12+
enum Operation {
13+
ADD,
14+
DELETE,
15+
SHOW,
16+
} ;
17+
enum { MAX_ADDR_SIZE = 64 };
18+
19+
IntfCfgMgr(DBConnector *db);
20+
int intf_modify(Operation cmd, int argc, char **argv);
21+
int intf_show(int argc, char **argv);
22+
23+
private:
24+
Table m_cfgIntfTable, m_cfgLagIntfTable, m_cfgVlanIntfTable;
25+
};
26+
27+
}
28+
29+
#endif

0 commit comments

Comments
 (0)