Skip to content

Commit e00e571

Browse files
kcudnikShuotian Cheng
authored and
Shuotian Cheng
committed
Add saidump tool to view SAI state (sonic-net#116)
1 parent bc3aba1 commit e00e571

File tree

6 files changed

+309
-3
lines changed

6 files changed

+309
-3
lines changed

Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
SUBDIRS = meta lib vslib syncd player
1+
SUBDIRS = meta lib vslib syncd player saidump

configure.ac

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,5 @@ AC_OUTPUT(Makefile
9595
vslib/Makefile
9696
vslib/src/Makefile
9797
syncd/Makefile
98-
player/Makefile)
98+
player/Makefile
99+
saidump/Makefile)

debian/syncd.install

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
usr/bin/asicdump
12
usr/bin/syncd*
23
etc/*

meta/saiserialize.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ void sai_deserialize_attr_id(
149149

150150
void sai_deserialize_attr_id(
151151
_In_ const std::string& s,
152-
_In_ const sai_attr_metadata_t& meta);
152+
_In_ const sai_attr_metadata_t** meta);
153153

154154
// deserialize ntf
155155

saidump/Makefile.am

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
AM_CPPFLAGS = -I/usr/include/sai -I$(top_srcdir)/common
2+
3+
bin_PROGRAMS = saidump
4+
5+
if DEBUG
6+
DBGFLAGS = -ggdb -DDEBUG
7+
else
8+
DBGFLAGS = -g
9+
endif
10+
11+
saidump_SOURCES = saidump.cpp
12+
saidump_CPPFLAGS = $(DBGFLAGS) $(AM_CPPFLAGS) $(CFLAGS_COMMON)
13+
saidump_LDADD = -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -L$(top_srcdir)/lib/src/.libs -lsairedis

saidump/saidump.cpp

+291
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
#include <vector>
2+
#include <string>
3+
#include <iostream>
4+
#include <sstream>
5+
6+
extern "C" {
7+
#include <sai.h>
8+
}
9+
10+
#include "swss/table.h"
11+
#include "swss/logger.h"
12+
#include "meta/saiserialize.h"
13+
14+
#include <getopt.h>
15+
16+
using namespace swss;
17+
using namespace std;
18+
19+
struct CmdOptions
20+
{
21+
bool shortNames;
22+
bool disableColors;
23+
bool skipAttributes;
24+
bool followReferences;
25+
};
26+
27+
CmdOptions g_cmdOptions;
28+
std::map<sai_object_id_t, const TableMap*> g_oid_map;
29+
30+
void printUsage()
31+
{
32+
SWSS_LOG_ENTER();
33+
34+
std::cout << "Usage: asicdump [-C] [-s] [-h]" << std::endl;
35+
std::cout << " -C --disableColors" << std::endl;
36+
std::cout << " Disable colors" << std::endl;
37+
std::cout << " -s --shortNames:" << std::endl;
38+
std::cout << " Use short names" << std::endl;
39+
std::cout << " -h --help:" << std::endl;
40+
std::cout << " Print out this message" << std::endl;
41+
}
42+
43+
CmdOptions handleCmdLine(int argc, char **argv)
44+
{
45+
SWSS_LOG_ENTER();
46+
47+
CmdOptions options;
48+
49+
options.shortNames = false;
50+
options.disableColors = false;
51+
52+
const char* const optstring = "Csh";
53+
54+
while(true)
55+
{
56+
static struct option long_options[] =
57+
{
58+
{ "disableColors", no_argument, 0, 'C' },
59+
{ "shortNames", no_argument, 0, 's' },
60+
{ "help", no_argument, 0, 'h' },
61+
{ 0, 0, 0, 0 }
62+
};
63+
64+
int option_index = 0;
65+
66+
int c = getopt_long(argc, argv, optstring, long_options, &option_index);
67+
68+
if (c == -1)
69+
{
70+
break;
71+
}
72+
73+
switch (c)
74+
{
75+
case 'C':
76+
SWSS_LOG_NOTICE("Disable colors");
77+
options.disableColors = true;
78+
break;
79+
80+
case 's':
81+
SWSS_LOG_NOTICE("Short names");
82+
options.shortNames = true;
83+
break;
84+
85+
case 'h':
86+
printUsage();
87+
exit(EXIT_SUCCESS);
88+
89+
case '?':
90+
SWSS_LOG_WARN("unknown option %c", optopt);
91+
printUsage();
92+
exit(EXIT_FAILURE);
93+
94+
default:
95+
SWSS_LOG_ERROR("getopt_long failure");
96+
exit(EXIT_FAILURE);
97+
}
98+
}
99+
100+
return options;
101+
}
102+
103+
size_t get_max_attr_len(const TableMap& map)
104+
{
105+
SWSS_LOG_ENTER();
106+
107+
size_t max = 0;
108+
109+
for (const auto&field: map)
110+
{
111+
max = std::max(max, field.first.length());
112+
}
113+
114+
return max;
115+
}
116+
117+
std::string pad_string(std::string s, size_t pad)
118+
{
119+
SWSS_LOG_ENTER();
120+
121+
size_t len = s.length();
122+
123+
if (len < pad)
124+
{
125+
s.insert(len, pad - len, ' ');
126+
}
127+
128+
return s;
129+
}
130+
131+
const TableMap* get_table_map(sai_object_id_t object_id)
132+
{
133+
SWSS_LOG_ENTER();
134+
135+
auto it = g_oid_map.find(object_id);
136+
137+
if (it == g_oid_map.end())
138+
{
139+
SWSS_LOG_ERROR("unable to find oid %llx in oid map", object_id);
140+
throw;
141+
}
142+
143+
return it->second;
144+
}
145+
146+
void print_attributes(size_t indent, const TableMap& map)
147+
{
148+
SWSS_LOG_ENTER();
149+
150+
size_t max_len = get_max_attr_len(map);
151+
152+
std::string str_indent = pad_string("", indent);
153+
154+
for (const auto&field: map)
155+
{
156+
const sai_attr_metadata_t *meta;
157+
sai_deserialize_attr_id(field.first, &meta);
158+
159+
std::stringstream ss;
160+
161+
ss << str_indent << pad_string(field.first, max_len) << " : ";
162+
163+
ss << field.second;
164+
165+
std::cout << ss.str() << std::endl;
166+
}
167+
}
168+
169+
int main(int argc, char ** argv)
170+
{
171+
swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);
172+
173+
SWSS_LOG_ENTER();
174+
175+
swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE);
176+
177+
meta_init();
178+
179+
swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_INFO);
180+
181+
g_cmdOptions = handleCmdLine(argc, argv);
182+
183+
swss::DBConnector db(ASIC_DB, "localhost", 6379, 0);
184+
185+
swss::Table t(&db, "ASIC_STATE");
186+
187+
TableDump dump;
188+
189+
t.dump(dump);
190+
191+
for (const auto&key: dump)
192+
{
193+
auto start = key.first.find_first_of(":");
194+
auto str_object_type = key.first.substr(0, start);
195+
auto str_object_id = key.first.substr(start + 1);
196+
197+
sai_object_type_t object_type;
198+
sai_deserialize_object_type(str_object_type, object_type);
199+
200+
switch (object_type)
201+
{
202+
case SAI_OBJECT_TYPE_FDB:
203+
case SAI_OBJECT_TYPE_SWITCH:
204+
case SAI_OBJECT_TYPE_NEIGHBOR:
205+
case SAI_OBJECT_TYPE_ROUTE:
206+
case SAI_OBJECT_TYPE_VLAN:
207+
case SAI_OBJECT_TYPE_TRAP:
208+
break;
209+
210+
default:
211+
{
212+
sai_object_id_t object_id;
213+
sai_deserialize_object_id(str_object_id, object_id);
214+
215+
g_oid_map[object_id] = &key.second;
216+
}
217+
break;
218+
}
219+
}
220+
221+
for (const auto&key: dump)
222+
{
223+
auto start = key.first.find_first_of(":");
224+
auto str_object_type = key.first.substr(0, start);
225+
auto str_object_id = key.first.substr(start + 1);
226+
227+
sai_object_type_t object_type;
228+
sai_deserialize_object_type(str_object_type, object_type);
229+
230+
if (g_cmdOptions.shortNames)
231+
{
232+
str_object_type = metadata_enum_sai_object_type_t.valuesshortnames[object_type];
233+
}
234+
235+
std::cout << str_object_type << " " << str_object_id << " " << std::endl;
236+
237+
switch (object_type)
238+
{
239+
case SAI_OBJECT_TYPE_FDB:
240+
{
241+
sai_fdb_entry_t fdb_entry;
242+
sai_deserialize_fdb_entry(str_object_id, fdb_entry);
243+
}
244+
break;
245+
246+
case SAI_OBJECT_TYPE_SWITCH:
247+
break;
248+
249+
case SAI_OBJECT_TYPE_NEIGHBOR:
250+
{
251+
sai_neighbor_entry_t neighbor_entry;
252+
sai_deserialize_neighbor_entry(str_object_id, neighbor_entry);
253+
}
254+
break;
255+
256+
case SAI_OBJECT_TYPE_ROUTE:
257+
{
258+
sai_unicast_route_entry_t route_entry;
259+
sai_deserialize_route_entry(str_object_id, route_entry);
260+
}
261+
break;
262+
263+
case SAI_OBJECT_TYPE_VLAN:
264+
{
265+
sai_vlan_id_t vlan_id;
266+
sai_deserialize_vlan_id(str_object_id, vlan_id);
267+
}
268+
break;
269+
270+
case SAI_OBJECT_TYPE_TRAP:
271+
{
272+
sai_hostif_trap_id_t trap_id;
273+
sai_deserialize_hostif_trap_id(str_object_id, trap_id);
274+
}
275+
break;
276+
277+
default:
278+
{
279+
sai_object_id_t object_id;
280+
sai_deserialize_object_id(str_object_id, object_id);
281+
}
282+
break;
283+
}
284+
285+
size_t indent = 4;
286+
287+
print_attributes(indent, key.second);
288+
289+
std::cout << std::endl;
290+
}
291+
}

0 commit comments

Comments
 (0)