Line data Source code
1 : /*
2 : * dpdkinfo.c - CLI dpdkinfo to get info. about bond, lacp, mem etc.
3 : *
4 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
5 : */
6 :
7 : #include <stdio.h>
8 : #include <stdlib.h>
9 : #include <unistd.h>
10 : #include <string.h>
11 : #include <errno.h>
12 : #include <inttypes.h>
13 : #include <stdlib.h>
14 : #include <stdbool.h>
15 : #include <getopt.h>
16 :
17 : #include <sys/types.h>
18 : #include <sys/socket.h>
19 :
20 : #include <net/if.h>
21 :
22 : #include "ini_parser.h"
23 : #include "vr_os.h"
24 : #include "vr_types.h"
25 : #include "vr_nexthop.h"
26 : #include "ini_parser.h"
27 : #include "nl_util.h"
28 : #include "ini_parser.h"
29 : #include "vr_packet.h"
30 : #include "vr_interface.h"
31 :
32 : static struct nl_client *cl;
33 : static bool dump_pending = false;
34 : static int dump_marker = -1;
35 : /* For supporting multiple CLI clients, Message buffer table id is stored and
36 : * resend if dump_pending is true */
37 : /* Optional parameter: buffsz -> Send buffer size for the Output buffer(outbuf)
38 : * */
39 : static int buff_table_id, buffsz;
40 :
41 : static int help_set, ver_set, bond_set, lacp_set, mempool_set, stats_set,
42 : xstats_set, lcore_set, app_set, ddp_set, sock_dir_set, link_set;
43 : static unsigned int core = (unsigned)-1;
44 : static unsigned int stats_index = 0;
45 : /* For few CLI, Inbuf has to send to vrouter for processing(i.e kind of filter
46 : */
47 : static uint8_t *vr_info_inbuf;
48 :
49 : static vr_info_msg_en msginfo;
50 :
51 : enum opt_index {
52 : HELP_OPT_INDEX,
53 : VER_OPT_INDEX,
54 : BOND_OPT_INDEX,
55 : LACP_OPT_INDEX,
56 : MEMPOOL_OPT_INDEX,
57 : STATS_OPT_INDEX,
58 : XSTATS_OPT_INDEX,
59 : BUFFSZ_OPT_INDEX,
60 : LCORE_OPT_INDEX,
61 : APP_OPT_INDEX,
62 : DDP_OPT_INDEX,
63 : SOCK_DIR_OPT_INDEX,
64 : LINK_OPT_INDEX,
65 : MAX_OPT_INDEX,
66 : };
67 :
68 : static struct option long_options[] = {
69 : [HELP_OPT_INDEX] = {"help", no_argument, &help_set, 1},
70 : [VER_OPT_INDEX] = {"version", no_argument, &ver_set, 1},
71 : [BOND_OPT_INDEX] = {"bond", no_argument, &bond_set, 1},
72 : [LACP_OPT_INDEX] = {"lacp", required_argument, &lacp_set, 1},
73 : [MEMPOOL_OPT_INDEX] = {"mempool", required_argument, &mempool_set, 1},
74 : [STATS_OPT_INDEX] = {"stats", required_argument, &stats_set, 1},
75 : [XSTATS_OPT_INDEX] = {"xstats", optional_argument, &xstats_set, 1},
76 : [LCORE_OPT_INDEX] = {"lcore", no_argument, &lcore_set, 1},
77 : [APP_OPT_INDEX] = {"app", no_argument, &app_set, 1},
78 : [DDP_OPT_INDEX] = {"ddp", required_argument, &ddp_set, 1},
79 : [BUFFSZ_OPT_INDEX] = {"buffsz", required_argument, &buffsz, 1},
80 : [SOCK_DIR_OPT_INDEX] = {"sock-dir", required_argument, &sock_dir_set, 1},
81 : [LINK_OPT_INDEX] = {"link", required_argument, &link_set, 1},
82 : [MAX_OPT_INDEX] = {NULL, 0, 0, 0},
83 : };
84 :
85 : static void
86 0 : Usage()
87 : {
88 0 : printf("Usage: dpdkinfo [--help]\n");
89 0 : printf(" --version|-v\
90 : Show DPDK Version\n");
91 0 : printf(" --bond|-b\
92 : Show Master/Slave bond information\n");
93 0 : printf(" --lacp|-l <all/conf>\
94 : Show LACP information from DPDK\n");
95 0 : printf(" --mempool|-m <all/<mempool-name>>\
96 : Show Mempool information\n");
97 0 : printf(" --stats|-n <eth>\
98 : Show Stats information\n");
99 0 : printf(" --xstats|-x < =all/ =0(Master)/ =1(Slave(0))/ =2(Slave(1))>\
100 : Show Extended Stats information\n");
101 0 : printf(" --lcore|-c\
102 : Show Lcore information\n");
103 0 : printf(" --app|-a\
104 : Show App information\n");
105 0 : printf(" --ddp|-d <list>\
106 : Show DDP information for X710 NIC\n");
107 0 : printf(" Optional: --buffsz <value>\
108 : Send output buffer size (less than 1000Mb)\n");
109 0 : exit(-EINVAL);
110 : }
111 :
112 : static void
113 1 : validate_options(void)
114 : {
115 1 : if(!(ver_set || bond_set || lacp_set || mempool_set ||
116 0 : stats_set || xstats_set || lcore_set || app_set|| ddp_set || link_set))
117 0 : Usage();
118 :
119 1 : return;
120 : }
121 :
122 : /*
123 : * Response messages are sent through character buffer via Sandesh and it has
124 : * a limitation of sending upto 4K(PAGE_SIZE) for each iteration.
125 : * */
126 : static void
127 1 : dpdkinfo_resp_cb_process(void *s_req)
128 : {
129 1 : int ret = 0;
130 1 : vr_info_req *resp = (vr_info_req *)s_req;
131 1 : if(resp != NULL && resp->vdu_proc_info) {
132 : /* Print the Message buffer(character buffer)
133 : * sent by vRouter(Server) */
134 1 : printf("%s", resp->vdu_proc_info);
135 : }
136 :
137 : /* For Sandesh DUMP, we should update the marker id and buff_table_id for
138 : * the next interation. */
139 1 : if (resp->h_op == SANDESH_OP_DUMP) {
140 1 : dump_marker = resp->vdu_index;
141 1 : buff_table_id = resp->vdu_buff_table_id;
142 : }
143 1 : }
144 :
145 : static void
146 1 : response_process(void *s)
147 : {
148 1 : vr_response_common_process((vr_response *)s, &dump_pending);
149 1 : }
150 :
151 : static void
152 1 : dpdkinfo_fill_nl_callbacks()
153 : {
154 1 : nl_cb.vr_info_req_process = dpdkinfo_resp_cb_process;
155 1 : nl_cb.vr_response_process = response_process;
156 1 : }
157 :
158 : static void
159 2 : parse_long_opts(int opt_index, char *opt_arg)
160 : {
161 2 : errno = 0;
162 :
163 2 : switch (opt_index) {
164 0 : case VER_OPT_INDEX:
165 0 : msginfo = INFO_VER_DPDK;
166 0 : break;
167 :
168 0 : case BOND_OPT_INDEX:
169 0 : msginfo = INFO_BOND;
170 0 : break;
171 :
172 0 : case LACP_OPT_INDEX:
173 0 : msginfo = INFO_LACP;
174 0 : if (!strcmp(opt_arg, "all") || !strcmp(opt_arg, "conf")){
175 0 : vr_info_inbuf = opt_arg;
176 : } else {
177 0 : Usage();
178 : }
179 0 : break;
180 :
181 1 : case MEMPOOL_OPT_INDEX:
182 1 : msginfo = INFO_MEMPOOL;
183 1 : vr_info_inbuf = opt_arg;
184 1 : break;
185 :
186 0 : case STATS_OPT_INDEX:
187 0 : msginfo = INFO_STATS;
188 0 : if (strcmp(opt_arg,"eth") == 0){
189 0 : vr_info_inbuf = opt_arg;
190 : } else {
191 0 : Usage();
192 : }
193 0 : break;
194 :
195 0 : case XSTATS_OPT_INDEX:
196 0 : msginfo = INFO_XSTATS;
197 0 : if (!opt_arg){
198 0 : opt_arg = "";
199 : }
200 0 : if (!strcmp(opt_arg, "all") || !strcmp(opt_arg, "") ||
201 0 : !strcmp(opt_arg, "0") || ((atoi(opt_arg) > 0) &&
202 0 : (atoi(opt_arg) <= VR_INTERFACE_BOND_MAX_SLAVES))){
203 0 : vr_info_inbuf = opt_arg;
204 : } else {
205 0 : Usage();
206 : }
207 0 : break;
208 :
209 0 : case LCORE_OPT_INDEX:
210 0 : msginfo = INFO_LCORE;
211 0 : break;
212 :
213 0 : case APP_OPT_INDEX:
214 0 : msginfo = INFO_APP;
215 0 : break;
216 :
217 0 : case DDP_OPT_INDEX:
218 0 : msginfo = INFO_DDP;
219 0 : if (!strcmp(opt_arg, "list")){
220 0 : vr_info_inbuf = opt_arg;
221 : } else {
222 0 : Usage();
223 : }
224 0 : break;
225 :
226 1 : case SOCK_DIR_OPT_INDEX:
227 1 : vr_socket_dir = opt_arg;
228 1 : break;
229 :
230 0 : case BUFFSZ_OPT_INDEX:
231 : /* Setting buffsz limit to 1000Mb */
232 0 : if ((unsigned)strtol(opt_arg, NULL, 0) >= 0x3E800000){
233 0 : Usage();
234 : }
235 0 : buffsz = (unsigned)strtol(opt_arg, NULL, 0);
236 0 : break;
237 :
238 0 : case LINK_OPT_INDEX:
239 0 : msginfo = INFO_LINK;
240 0 : vr_info_inbuf = opt_arg;
241 0 : break;
242 :
243 0 : case HELP_OPT_INDEX:
244 : default:
245 0 : Usage();
246 : }
247 :
248 2 : return;
249 : }
250 :
251 : /* vr_get_dpdkinfo API send request to vRouter(server) and uses
252 : * h_op = DUMP for message request.
253 : * */
254 : static int
255 1 : vr_get_dpdkinfo(struct nl_client *cl)
256 : {
257 : int ret;
258 1 : bool dump = true;
259 :
260 1 : op_retry:
261 1 : ret = vr_send_info_dump(cl, 0, dump_marker, buff_table_id, msginfo, buffsz,
262 : vr_info_inbuf);
263 1 : if (ret < 0)
264 0 : return ret;
265 :
266 1 : ret = vr_recvmsg(cl, dump);
267 1 : if (ret <= 0)
268 0 : return ret;
269 :
270 : /* Will loop through till it reaches end of buffer */
271 1 : if (dump_pending)
272 0 : goto op_retry;
273 1 : return 0;
274 : }
275 :
276 : int
277 1 : main(int argc, char *argv[])
278 : {
279 : char opt;
280 1 : int ret, option_index, log_core = 0, i = 0;
281 1 : int platform = 0;
282 :
283 : /* Register callback function for Netlink message */
284 1 : dpdkinfo_fill_nl_callbacks();
285 :
286 1 : parse_ini_file();
287 :
288 3 : while (((opt = getopt_long(argc, argv, "-:hvbl:m:sn:p:d:cax::",
289 3 : long_options, &option_index)) >= 0)) {
290 2 : switch (opt) {
291 0 : case 'v':
292 0 : ver_set = 1;
293 0 : msginfo = INFO_VER_DPDK;
294 0 : break;
295 :
296 0 : case 'b':
297 0 : bond_set = 1;
298 0 : msginfo = INFO_BOND;
299 0 : break;
300 :
301 0 : case 'l':
302 0 : lacp_set = 1;
303 0 : msginfo = INFO_LACP;
304 0 : parse_long_opts(LACP_OPT_INDEX, optarg);
305 0 : break;
306 :
307 0 : case 'm':
308 0 : mempool_set = 1;
309 0 : msginfo = INFO_MEMPOOL;
310 0 : parse_long_opts(MEMPOOL_OPT_INDEX, optarg);
311 0 : break;
312 :
313 0 : case 'n':
314 0 : stats_set = 1;
315 0 : msginfo = INFO_STATS;
316 0 : parse_long_opts(STATS_OPT_INDEX, optarg);
317 0 : break;
318 :
319 0 : case 's':
320 0 : sock_dir_set = 1;
321 0 : parse_long_opts(SOCK_DIR_OPT_INDEX, optarg);
322 0 : break;
323 :
324 0 : case 'x':
325 0 : xstats_set = 1;
326 0 : msginfo = INFO_XSTATS;
327 0 : parse_long_opts(XSTATS_OPT_INDEX, optarg);
328 0 : break;
329 :
330 0 : case 'c':
331 0 : lcore_set = 1;
332 0 : msginfo = INFO_LCORE;
333 0 : break;
334 :
335 0 : case 'a':
336 0 : app_set = 1;
337 0 : msginfo = INFO_APP;
338 0 : break;
339 :
340 0 : case 'p':
341 0 : link_set = 1;
342 0 : msginfo = INFO_LINK;
343 0 : parse_long_opts(LINK_OPT_INDEX, optarg);
344 0 : break;
345 :
346 0 : case 'd':
347 0 : ddp_set = 1;
348 0 : msginfo = INFO_DDP;
349 0 : parse_long_opts(DDP_OPT_INDEX, optarg);
350 0 : break;
351 :
352 2 : case 0:
353 2 : parse_long_opts(option_index, optarg);
354 2 : break;
355 :
356 0 : case 'h':
357 : default:
358 0 : Usage();
359 : }
360 : }
361 1 : validate_options();
362 :
363 : /* Support for running from VTEST(vRouter UT Framework)*/
364 1 : if (sock_dir_set) {
365 1 : set_platform_vtest();
366 : }
367 1 : platform = get_platform();
368 1 : if ((platform != DPDK_PLATFORM) && (platform != VTEST_PLATFORM)) {
369 0 : Usage();
370 : }
371 :
372 1 : cl = vr_get_nl_client(VR_NETLINK_PROTO_DEFAULT);
373 1 : if (!cl)
374 0 : return -1;
375 :
376 1 : vr_get_dpdkinfo(cl);
377 :
378 1 : return 0;
379 : }
|