1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606 * Copyright(c) 2020 Intel Corporation
3*2d9fd380Sjfb8856606 */
4*2d9fd380Sjfb8856606
5*2d9fd380Sjfb8856606 #include <stdio.h>
6*2d9fd380Sjfb8856606 #include <stdint.h>
7*2d9fd380Sjfb8856606 #include <stdlib.h>
8*2d9fd380Sjfb8856606 #include <string.h>
9*2d9fd380Sjfb8856606
10*2d9fd380Sjfb8856606 #include <rte_common.h>
11*2d9fd380Sjfb8856606 #include <rte_ethdev.h>
12*2d9fd380Sjfb8856606 #include <rte_swx_port_ethdev.h>
13*2d9fd380Sjfb8856606 #include <rte_swx_port_source_sink.h>
14*2d9fd380Sjfb8856606 #include <rte_swx_pipeline.h>
15*2d9fd380Sjfb8856606 #include <rte_swx_ctl.h>
16*2d9fd380Sjfb8856606
17*2d9fd380Sjfb8856606 #include "cli.h"
18*2d9fd380Sjfb8856606
19*2d9fd380Sjfb8856606 #include "obj.h"
20*2d9fd380Sjfb8856606 #include "thread.h"
21*2d9fd380Sjfb8856606
22*2d9fd380Sjfb8856606 #ifndef CMD_MAX_TOKENS
23*2d9fd380Sjfb8856606 #define CMD_MAX_TOKENS 256
24*2d9fd380Sjfb8856606 #endif
25*2d9fd380Sjfb8856606
26*2d9fd380Sjfb8856606 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
27*2d9fd380Sjfb8856606 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
28*2d9fd380Sjfb8856606 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
29*2d9fd380Sjfb8856606 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
30*2d9fd380Sjfb8856606 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
31*2d9fd380Sjfb8856606 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
32*2d9fd380Sjfb8856606 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
33*2d9fd380Sjfb8856606 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
34*2d9fd380Sjfb8856606 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
35*2d9fd380Sjfb8856606 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
36*2d9fd380Sjfb8856606 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
37*2d9fd380Sjfb8856606
38*2d9fd380Sjfb8856606 #define skip_white_spaces(pos) \
39*2d9fd380Sjfb8856606 ({ \
40*2d9fd380Sjfb8856606 __typeof__(pos) _p = (pos); \
41*2d9fd380Sjfb8856606 for ( ; isspace(*_p); _p++) \
42*2d9fd380Sjfb8856606 ; \
43*2d9fd380Sjfb8856606 _p; \
44*2d9fd380Sjfb8856606 })
45*2d9fd380Sjfb8856606
46*2d9fd380Sjfb8856606 static int
parser_read_uint64(uint64_t * value,const char * p)47*2d9fd380Sjfb8856606 parser_read_uint64(uint64_t *value, const char *p)
48*2d9fd380Sjfb8856606 {
49*2d9fd380Sjfb8856606 char *next;
50*2d9fd380Sjfb8856606 uint64_t val;
51*2d9fd380Sjfb8856606
52*2d9fd380Sjfb8856606 p = skip_white_spaces(p);
53*2d9fd380Sjfb8856606 if (!isdigit(*p))
54*2d9fd380Sjfb8856606 return -EINVAL;
55*2d9fd380Sjfb8856606
56*2d9fd380Sjfb8856606 val = strtoul(p, &next, 10);
57*2d9fd380Sjfb8856606 if (p == next)
58*2d9fd380Sjfb8856606 return -EINVAL;
59*2d9fd380Sjfb8856606
60*2d9fd380Sjfb8856606 p = next;
61*2d9fd380Sjfb8856606 switch (*p) {
62*2d9fd380Sjfb8856606 case 'T':
63*2d9fd380Sjfb8856606 val *= 1024ULL;
64*2d9fd380Sjfb8856606 /* fall through */
65*2d9fd380Sjfb8856606 case 'G':
66*2d9fd380Sjfb8856606 val *= 1024ULL;
67*2d9fd380Sjfb8856606 /* fall through */
68*2d9fd380Sjfb8856606 case 'M':
69*2d9fd380Sjfb8856606 val *= 1024ULL;
70*2d9fd380Sjfb8856606 /* fall through */
71*2d9fd380Sjfb8856606 case 'k':
72*2d9fd380Sjfb8856606 case 'K':
73*2d9fd380Sjfb8856606 val *= 1024ULL;
74*2d9fd380Sjfb8856606 p++;
75*2d9fd380Sjfb8856606 break;
76*2d9fd380Sjfb8856606 }
77*2d9fd380Sjfb8856606
78*2d9fd380Sjfb8856606 p = skip_white_spaces(p);
79*2d9fd380Sjfb8856606 if (*p != '\0')
80*2d9fd380Sjfb8856606 return -EINVAL;
81*2d9fd380Sjfb8856606
82*2d9fd380Sjfb8856606 *value = val;
83*2d9fd380Sjfb8856606 return 0;
84*2d9fd380Sjfb8856606 }
85*2d9fd380Sjfb8856606
86*2d9fd380Sjfb8856606 static int
parser_read_uint32(uint32_t * value,const char * p)87*2d9fd380Sjfb8856606 parser_read_uint32(uint32_t *value, const char *p)
88*2d9fd380Sjfb8856606 {
89*2d9fd380Sjfb8856606 uint64_t val = 0;
90*2d9fd380Sjfb8856606 int ret = parser_read_uint64(&val, p);
91*2d9fd380Sjfb8856606
92*2d9fd380Sjfb8856606 if (ret < 0)
93*2d9fd380Sjfb8856606 return ret;
94*2d9fd380Sjfb8856606
95*2d9fd380Sjfb8856606 if (val > UINT32_MAX)
96*2d9fd380Sjfb8856606 return -ERANGE;
97*2d9fd380Sjfb8856606
98*2d9fd380Sjfb8856606 *value = val;
99*2d9fd380Sjfb8856606 return 0;
100*2d9fd380Sjfb8856606 }
101*2d9fd380Sjfb8856606
102*2d9fd380Sjfb8856606 static int
parser_read_uint16(uint16_t * value,const char * p)103*2d9fd380Sjfb8856606 parser_read_uint16(uint16_t *value, const char *p)
104*2d9fd380Sjfb8856606 {
105*2d9fd380Sjfb8856606 uint64_t val = 0;
106*2d9fd380Sjfb8856606 int ret = parser_read_uint64(&val, p);
107*2d9fd380Sjfb8856606
108*2d9fd380Sjfb8856606 if (ret < 0)
109*2d9fd380Sjfb8856606 return ret;
110*2d9fd380Sjfb8856606
111*2d9fd380Sjfb8856606 if (val > UINT16_MAX)
112*2d9fd380Sjfb8856606 return -ERANGE;
113*2d9fd380Sjfb8856606
114*2d9fd380Sjfb8856606 *value = val;
115*2d9fd380Sjfb8856606 return 0;
116*2d9fd380Sjfb8856606 }
117*2d9fd380Sjfb8856606
118*2d9fd380Sjfb8856606 #define PARSE_DELIMITER " \f\n\r\t\v"
119*2d9fd380Sjfb8856606
120*2d9fd380Sjfb8856606 static int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)121*2d9fd380Sjfb8856606 parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
122*2d9fd380Sjfb8856606 {
123*2d9fd380Sjfb8856606 uint32_t i;
124*2d9fd380Sjfb8856606
125*2d9fd380Sjfb8856606 if ((string == NULL) ||
126*2d9fd380Sjfb8856606 (tokens == NULL) ||
127*2d9fd380Sjfb8856606 (*n_tokens < 1))
128*2d9fd380Sjfb8856606 return -EINVAL;
129*2d9fd380Sjfb8856606
130*2d9fd380Sjfb8856606 for (i = 0; i < *n_tokens; i++) {
131*2d9fd380Sjfb8856606 tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
132*2d9fd380Sjfb8856606 if (tokens[i] == NULL)
133*2d9fd380Sjfb8856606 break;
134*2d9fd380Sjfb8856606 }
135*2d9fd380Sjfb8856606
136*2d9fd380Sjfb8856606 if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
137*2d9fd380Sjfb8856606 return -E2BIG;
138*2d9fd380Sjfb8856606
139*2d9fd380Sjfb8856606 *n_tokens = i;
140*2d9fd380Sjfb8856606 return 0;
141*2d9fd380Sjfb8856606 }
142*2d9fd380Sjfb8856606
143*2d9fd380Sjfb8856606 static int
is_comment(char * in)144*2d9fd380Sjfb8856606 is_comment(char *in)
145*2d9fd380Sjfb8856606 {
146*2d9fd380Sjfb8856606 if ((strlen(in) && index("!#%;", in[0])) ||
147*2d9fd380Sjfb8856606 (strncmp(in, "//", 2) == 0) ||
148*2d9fd380Sjfb8856606 (strncmp(in, "--", 2) == 0))
149*2d9fd380Sjfb8856606 return 1;
150*2d9fd380Sjfb8856606
151*2d9fd380Sjfb8856606 return 0;
152*2d9fd380Sjfb8856606 }
153*2d9fd380Sjfb8856606
154*2d9fd380Sjfb8856606 static const char cmd_mempool_help[] =
155*2d9fd380Sjfb8856606 "mempool <mempool_name>\n"
156*2d9fd380Sjfb8856606 " buffer <buffer_size>\n"
157*2d9fd380Sjfb8856606 " pool <pool_size>\n"
158*2d9fd380Sjfb8856606 " cache <cache_size>\n"
159*2d9fd380Sjfb8856606 " cpu <cpu_id>\n";
160*2d9fd380Sjfb8856606
161*2d9fd380Sjfb8856606 static void
cmd_mempool(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)162*2d9fd380Sjfb8856606 cmd_mempool(char **tokens,
163*2d9fd380Sjfb8856606 uint32_t n_tokens,
164*2d9fd380Sjfb8856606 char *out,
165*2d9fd380Sjfb8856606 size_t out_size,
166*2d9fd380Sjfb8856606 void *obj)
167*2d9fd380Sjfb8856606 {
168*2d9fd380Sjfb8856606 struct mempool_params p;
169*2d9fd380Sjfb8856606 char *name;
170*2d9fd380Sjfb8856606 struct mempool *mempool;
171*2d9fd380Sjfb8856606
172*2d9fd380Sjfb8856606 if (n_tokens != 10) {
173*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
174*2d9fd380Sjfb8856606 return;
175*2d9fd380Sjfb8856606 }
176*2d9fd380Sjfb8856606
177*2d9fd380Sjfb8856606 name = tokens[1];
178*2d9fd380Sjfb8856606
179*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "buffer") != 0) {
180*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
181*2d9fd380Sjfb8856606 return;
182*2d9fd380Sjfb8856606 }
183*2d9fd380Sjfb8856606
184*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
185*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
186*2d9fd380Sjfb8856606 return;
187*2d9fd380Sjfb8856606 }
188*2d9fd380Sjfb8856606
189*2d9fd380Sjfb8856606 if (strcmp(tokens[4], "pool") != 0) {
190*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
191*2d9fd380Sjfb8856606 return;
192*2d9fd380Sjfb8856606 }
193*2d9fd380Sjfb8856606
194*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
195*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
196*2d9fd380Sjfb8856606 return;
197*2d9fd380Sjfb8856606 }
198*2d9fd380Sjfb8856606
199*2d9fd380Sjfb8856606 if (strcmp(tokens[6], "cache") != 0) {
200*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
201*2d9fd380Sjfb8856606 return;
202*2d9fd380Sjfb8856606 }
203*2d9fd380Sjfb8856606
204*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
205*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
206*2d9fd380Sjfb8856606 return;
207*2d9fd380Sjfb8856606 }
208*2d9fd380Sjfb8856606
209*2d9fd380Sjfb8856606 if (strcmp(tokens[8], "cpu") != 0) {
210*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
211*2d9fd380Sjfb8856606 return;
212*2d9fd380Sjfb8856606 }
213*2d9fd380Sjfb8856606
214*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
215*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
216*2d9fd380Sjfb8856606 return;
217*2d9fd380Sjfb8856606 }
218*2d9fd380Sjfb8856606
219*2d9fd380Sjfb8856606 mempool = mempool_create(obj, name, &p);
220*2d9fd380Sjfb8856606 if (mempool == NULL) {
221*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
222*2d9fd380Sjfb8856606 return;
223*2d9fd380Sjfb8856606 }
224*2d9fd380Sjfb8856606 }
225*2d9fd380Sjfb8856606
226*2d9fd380Sjfb8856606 static const char cmd_link_help[] =
227*2d9fd380Sjfb8856606 "link <link_name>\n"
228*2d9fd380Sjfb8856606 " dev <device_name> | port <port_id>\n"
229*2d9fd380Sjfb8856606 " rxq <n_queues> <queue_size> <mempool_name>\n"
230*2d9fd380Sjfb8856606 " txq <n_queues> <queue_size>\n"
231*2d9fd380Sjfb8856606 " promiscuous on | off\n"
232*2d9fd380Sjfb8856606 " [rss <qid_0> ... <qid_n>]\n";
233*2d9fd380Sjfb8856606
234*2d9fd380Sjfb8856606 static void
cmd_link(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)235*2d9fd380Sjfb8856606 cmd_link(char **tokens,
236*2d9fd380Sjfb8856606 uint32_t n_tokens,
237*2d9fd380Sjfb8856606 char *out,
238*2d9fd380Sjfb8856606 size_t out_size,
239*2d9fd380Sjfb8856606 void *obj)
240*2d9fd380Sjfb8856606 {
241*2d9fd380Sjfb8856606 struct link_params p;
242*2d9fd380Sjfb8856606 struct link_params_rss rss;
243*2d9fd380Sjfb8856606 struct link *link;
244*2d9fd380Sjfb8856606 char *name;
245*2d9fd380Sjfb8856606
246*2d9fd380Sjfb8856606 memset(&p, 0, sizeof(p));
247*2d9fd380Sjfb8856606
248*2d9fd380Sjfb8856606 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
249*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
250*2d9fd380Sjfb8856606 return;
251*2d9fd380Sjfb8856606 }
252*2d9fd380Sjfb8856606 name = tokens[1];
253*2d9fd380Sjfb8856606
254*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "dev") == 0)
255*2d9fd380Sjfb8856606 p.dev_name = tokens[3];
256*2d9fd380Sjfb8856606 else if (strcmp(tokens[2], "port") == 0) {
257*2d9fd380Sjfb8856606 p.dev_name = NULL;
258*2d9fd380Sjfb8856606
259*2d9fd380Sjfb8856606 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
260*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
261*2d9fd380Sjfb8856606 return;
262*2d9fd380Sjfb8856606 }
263*2d9fd380Sjfb8856606 } else {
264*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
265*2d9fd380Sjfb8856606 return;
266*2d9fd380Sjfb8856606 }
267*2d9fd380Sjfb8856606
268*2d9fd380Sjfb8856606 if (strcmp(tokens[4], "rxq") != 0) {
269*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
270*2d9fd380Sjfb8856606 return;
271*2d9fd380Sjfb8856606 }
272*2d9fd380Sjfb8856606
273*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
274*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
275*2d9fd380Sjfb8856606 return;
276*2d9fd380Sjfb8856606 }
277*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
278*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
279*2d9fd380Sjfb8856606 return;
280*2d9fd380Sjfb8856606 }
281*2d9fd380Sjfb8856606
282*2d9fd380Sjfb8856606 p.rx.mempool_name = tokens[7];
283*2d9fd380Sjfb8856606
284*2d9fd380Sjfb8856606 if (strcmp(tokens[8], "txq") != 0) {
285*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
286*2d9fd380Sjfb8856606 return;
287*2d9fd380Sjfb8856606 }
288*2d9fd380Sjfb8856606
289*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
290*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
291*2d9fd380Sjfb8856606 return;
292*2d9fd380Sjfb8856606 }
293*2d9fd380Sjfb8856606
294*2d9fd380Sjfb8856606 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
295*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
296*2d9fd380Sjfb8856606 return;
297*2d9fd380Sjfb8856606 }
298*2d9fd380Sjfb8856606
299*2d9fd380Sjfb8856606 if (strcmp(tokens[11], "promiscuous") != 0) {
300*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
301*2d9fd380Sjfb8856606 return;
302*2d9fd380Sjfb8856606 }
303*2d9fd380Sjfb8856606
304*2d9fd380Sjfb8856606 if (strcmp(tokens[12], "on") == 0)
305*2d9fd380Sjfb8856606 p.promiscuous = 1;
306*2d9fd380Sjfb8856606 else if (strcmp(tokens[12], "off") == 0)
307*2d9fd380Sjfb8856606 p.promiscuous = 0;
308*2d9fd380Sjfb8856606 else {
309*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
310*2d9fd380Sjfb8856606 return;
311*2d9fd380Sjfb8856606 }
312*2d9fd380Sjfb8856606
313*2d9fd380Sjfb8856606 /* RSS */
314*2d9fd380Sjfb8856606 p.rx.rss = NULL;
315*2d9fd380Sjfb8856606 if (n_tokens > 13) {
316*2d9fd380Sjfb8856606 uint32_t queue_id, i;
317*2d9fd380Sjfb8856606
318*2d9fd380Sjfb8856606 if (strcmp(tokens[13], "rss") != 0) {
319*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
320*2d9fd380Sjfb8856606 return;
321*2d9fd380Sjfb8856606 }
322*2d9fd380Sjfb8856606
323*2d9fd380Sjfb8856606 p.rx.rss = &rss;
324*2d9fd380Sjfb8856606
325*2d9fd380Sjfb8856606 rss.n_queues = 0;
326*2d9fd380Sjfb8856606 for (i = 14; i < n_tokens; i++) {
327*2d9fd380Sjfb8856606 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
328*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
329*2d9fd380Sjfb8856606 "queue_id");
330*2d9fd380Sjfb8856606 return;
331*2d9fd380Sjfb8856606 }
332*2d9fd380Sjfb8856606
333*2d9fd380Sjfb8856606 rss.queue_id[rss.n_queues] = queue_id;
334*2d9fd380Sjfb8856606 rss.n_queues++;
335*2d9fd380Sjfb8856606 }
336*2d9fd380Sjfb8856606 }
337*2d9fd380Sjfb8856606
338*2d9fd380Sjfb8856606 link = link_create(obj, name, &p);
339*2d9fd380Sjfb8856606 if (link == NULL) {
340*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
341*2d9fd380Sjfb8856606 return;
342*2d9fd380Sjfb8856606 }
343*2d9fd380Sjfb8856606 }
344*2d9fd380Sjfb8856606
345*2d9fd380Sjfb8856606 /* Print the link stats and info */
346*2d9fd380Sjfb8856606 static void
print_link_info(struct link * link,char * out,size_t out_size)347*2d9fd380Sjfb8856606 print_link_info(struct link *link, char *out, size_t out_size)
348*2d9fd380Sjfb8856606 {
349*2d9fd380Sjfb8856606 struct rte_eth_stats stats;
350*2d9fd380Sjfb8856606 struct rte_ether_addr mac_addr;
351*2d9fd380Sjfb8856606 struct rte_eth_link eth_link;
352*2d9fd380Sjfb8856606 uint16_t mtu;
353*2d9fd380Sjfb8856606 int ret;
354*2d9fd380Sjfb8856606
355*2d9fd380Sjfb8856606 memset(&stats, 0, sizeof(stats));
356*2d9fd380Sjfb8856606 rte_eth_stats_get(link->port_id, &stats);
357*2d9fd380Sjfb8856606
358*2d9fd380Sjfb8856606 ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
359*2d9fd380Sjfb8856606 if (ret != 0) {
360*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s: MAC address get failed: %s",
361*2d9fd380Sjfb8856606 link->name, rte_strerror(-ret));
362*2d9fd380Sjfb8856606 return;
363*2d9fd380Sjfb8856606 }
364*2d9fd380Sjfb8856606
365*2d9fd380Sjfb8856606 ret = rte_eth_link_get(link->port_id, ð_link);
366*2d9fd380Sjfb8856606 if (ret < 0) {
367*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s: link get failed: %s",
368*2d9fd380Sjfb8856606 link->name, rte_strerror(-ret));
369*2d9fd380Sjfb8856606 return;
370*2d9fd380Sjfb8856606 }
371*2d9fd380Sjfb8856606
372*2d9fd380Sjfb8856606 rte_eth_dev_get_mtu(link->port_id, &mtu);
373*2d9fd380Sjfb8856606
374*2d9fd380Sjfb8856606 snprintf(out, out_size,
375*2d9fd380Sjfb8856606 "\n"
376*2d9fd380Sjfb8856606 "%s: flags=<%s> mtu %u\n"
377*2d9fd380Sjfb8856606 "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
378*2d9fd380Sjfb8856606 "\tport# %u speed %s\n"
379*2d9fd380Sjfb8856606 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
380*2d9fd380Sjfb8856606 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
381*2d9fd380Sjfb8856606 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
382*2d9fd380Sjfb8856606 "\tTX errors %" PRIu64"\n",
383*2d9fd380Sjfb8856606 link->name,
384*2d9fd380Sjfb8856606 eth_link.link_status == 0 ? "DOWN" : "UP",
385*2d9fd380Sjfb8856606 mtu,
386*2d9fd380Sjfb8856606 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
387*2d9fd380Sjfb8856606 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
388*2d9fd380Sjfb8856606 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
389*2d9fd380Sjfb8856606 link->n_rxq,
390*2d9fd380Sjfb8856606 link->n_txq,
391*2d9fd380Sjfb8856606 link->port_id,
392*2d9fd380Sjfb8856606 rte_eth_link_speed_to_str(eth_link.link_speed),
393*2d9fd380Sjfb8856606 stats.ipackets,
394*2d9fd380Sjfb8856606 stats.ibytes,
395*2d9fd380Sjfb8856606 stats.ierrors,
396*2d9fd380Sjfb8856606 stats.imissed,
397*2d9fd380Sjfb8856606 stats.rx_nombuf,
398*2d9fd380Sjfb8856606 stats.opackets,
399*2d9fd380Sjfb8856606 stats.obytes,
400*2d9fd380Sjfb8856606 stats.oerrors);
401*2d9fd380Sjfb8856606 }
402*2d9fd380Sjfb8856606
403*2d9fd380Sjfb8856606 /*
404*2d9fd380Sjfb8856606 * link show [<link_name>]
405*2d9fd380Sjfb8856606 */
406*2d9fd380Sjfb8856606 static void
cmd_link_show(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)407*2d9fd380Sjfb8856606 cmd_link_show(char **tokens,
408*2d9fd380Sjfb8856606 uint32_t n_tokens,
409*2d9fd380Sjfb8856606 char *out,
410*2d9fd380Sjfb8856606 size_t out_size,
411*2d9fd380Sjfb8856606 void *obj)
412*2d9fd380Sjfb8856606 {
413*2d9fd380Sjfb8856606 struct link *link;
414*2d9fd380Sjfb8856606 char *link_name;
415*2d9fd380Sjfb8856606
416*2d9fd380Sjfb8856606 if (n_tokens != 2 && n_tokens != 3) {
417*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
418*2d9fd380Sjfb8856606 return;
419*2d9fd380Sjfb8856606 }
420*2d9fd380Sjfb8856606
421*2d9fd380Sjfb8856606 if (n_tokens == 2) {
422*2d9fd380Sjfb8856606 link = link_next(obj, NULL);
423*2d9fd380Sjfb8856606
424*2d9fd380Sjfb8856606 while (link != NULL) {
425*2d9fd380Sjfb8856606 out_size = out_size - strlen(out);
426*2d9fd380Sjfb8856606 out = &out[strlen(out)];
427*2d9fd380Sjfb8856606
428*2d9fd380Sjfb8856606 print_link_info(link, out, out_size);
429*2d9fd380Sjfb8856606 link = link_next(obj, link);
430*2d9fd380Sjfb8856606 }
431*2d9fd380Sjfb8856606 } else {
432*2d9fd380Sjfb8856606 out_size = out_size - strlen(out);
433*2d9fd380Sjfb8856606 out = &out[strlen(out)];
434*2d9fd380Sjfb8856606
435*2d9fd380Sjfb8856606 link_name = tokens[2];
436*2d9fd380Sjfb8856606 link = link_find(obj, link_name);
437*2d9fd380Sjfb8856606
438*2d9fd380Sjfb8856606 if (link == NULL) {
439*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
440*2d9fd380Sjfb8856606 "Link does not exist");
441*2d9fd380Sjfb8856606 return;
442*2d9fd380Sjfb8856606 }
443*2d9fd380Sjfb8856606 print_link_info(link, out, out_size);
444*2d9fd380Sjfb8856606 }
445*2d9fd380Sjfb8856606 }
446*2d9fd380Sjfb8856606
447*2d9fd380Sjfb8856606 static const char cmd_pipeline_create_help[] =
448*2d9fd380Sjfb8856606 "pipeline <pipeline_name> create <numa_node>\n";
449*2d9fd380Sjfb8856606
450*2d9fd380Sjfb8856606 static void
cmd_pipeline_create(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)451*2d9fd380Sjfb8856606 cmd_pipeline_create(char **tokens,
452*2d9fd380Sjfb8856606 uint32_t n_tokens,
453*2d9fd380Sjfb8856606 char *out,
454*2d9fd380Sjfb8856606 size_t out_size,
455*2d9fd380Sjfb8856606 void *obj)
456*2d9fd380Sjfb8856606 {
457*2d9fd380Sjfb8856606 struct pipeline *p;
458*2d9fd380Sjfb8856606 char *name;
459*2d9fd380Sjfb8856606 uint32_t numa_node;
460*2d9fd380Sjfb8856606
461*2d9fd380Sjfb8856606 if (n_tokens != 4) {
462*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
463*2d9fd380Sjfb8856606 return;
464*2d9fd380Sjfb8856606 }
465*2d9fd380Sjfb8856606
466*2d9fd380Sjfb8856606 name = tokens[1];
467*2d9fd380Sjfb8856606
468*2d9fd380Sjfb8856606 if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
469*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
470*2d9fd380Sjfb8856606 return;
471*2d9fd380Sjfb8856606 }
472*2d9fd380Sjfb8856606
473*2d9fd380Sjfb8856606 p = pipeline_create(obj, name, (int)numa_node);
474*2d9fd380Sjfb8856606 if (!p) {
475*2d9fd380Sjfb8856606 snprintf(out, out_size, "pipeline create error.");
476*2d9fd380Sjfb8856606 return;
477*2d9fd380Sjfb8856606 }
478*2d9fd380Sjfb8856606 }
479*2d9fd380Sjfb8856606
480*2d9fd380Sjfb8856606 static const char cmd_pipeline_port_in_help[] =
481*2d9fd380Sjfb8856606 "pipeline <pipeline_name> port in <port_id>\n"
482*2d9fd380Sjfb8856606 " link <link_name> rxq <queue_id> bsz <burst_size>\n"
483*2d9fd380Sjfb8856606 " | source <mempool_name> <file_name>\n";
484*2d9fd380Sjfb8856606
485*2d9fd380Sjfb8856606 static void
cmd_pipeline_port_in(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)486*2d9fd380Sjfb8856606 cmd_pipeline_port_in(char **tokens,
487*2d9fd380Sjfb8856606 uint32_t n_tokens,
488*2d9fd380Sjfb8856606 char *out,
489*2d9fd380Sjfb8856606 size_t out_size,
490*2d9fd380Sjfb8856606 void *obj)
491*2d9fd380Sjfb8856606 {
492*2d9fd380Sjfb8856606 struct pipeline *p;
493*2d9fd380Sjfb8856606 int status;
494*2d9fd380Sjfb8856606 uint32_t port_id = 0, t0;
495*2d9fd380Sjfb8856606
496*2d9fd380Sjfb8856606 if (n_tokens < 6) {
497*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
498*2d9fd380Sjfb8856606 return;
499*2d9fd380Sjfb8856606 }
500*2d9fd380Sjfb8856606
501*2d9fd380Sjfb8856606 p = pipeline_find(obj, tokens[1]);
502*2d9fd380Sjfb8856606 if (!p || p->ctl) {
503*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
504*2d9fd380Sjfb8856606 return;
505*2d9fd380Sjfb8856606 }
506*2d9fd380Sjfb8856606
507*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "port") != 0) {
508*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
509*2d9fd380Sjfb8856606 return;
510*2d9fd380Sjfb8856606 }
511*2d9fd380Sjfb8856606
512*2d9fd380Sjfb8856606 if (strcmp(tokens[3], "in") != 0) {
513*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
514*2d9fd380Sjfb8856606 return;
515*2d9fd380Sjfb8856606 }
516*2d9fd380Sjfb8856606
517*2d9fd380Sjfb8856606 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
518*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
519*2d9fd380Sjfb8856606 return;
520*2d9fd380Sjfb8856606 }
521*2d9fd380Sjfb8856606
522*2d9fd380Sjfb8856606 t0 = 5;
523*2d9fd380Sjfb8856606
524*2d9fd380Sjfb8856606 if (strcmp(tokens[t0], "link") == 0) {
525*2d9fd380Sjfb8856606 struct rte_swx_port_ethdev_reader_params params;
526*2d9fd380Sjfb8856606 struct link *link;
527*2d9fd380Sjfb8856606
528*2d9fd380Sjfb8856606 if (n_tokens < t0 + 6) {
529*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH,
530*2d9fd380Sjfb8856606 "pipeline port in link");
531*2d9fd380Sjfb8856606 return;
532*2d9fd380Sjfb8856606 }
533*2d9fd380Sjfb8856606
534*2d9fd380Sjfb8856606 link = link_find(obj, tokens[t0 + 1]);
535*2d9fd380Sjfb8856606 if (!link) {
536*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
537*2d9fd380Sjfb8856606 "link_name");
538*2d9fd380Sjfb8856606 return;
539*2d9fd380Sjfb8856606 }
540*2d9fd380Sjfb8856606 params.dev_name = link->dev_name;
541*2d9fd380Sjfb8856606
542*2d9fd380Sjfb8856606 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
543*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
544*2d9fd380Sjfb8856606 return;
545*2d9fd380Sjfb8856606 }
546*2d9fd380Sjfb8856606
547*2d9fd380Sjfb8856606 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
548*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
549*2d9fd380Sjfb8856606 "queue_id");
550*2d9fd380Sjfb8856606 return;
551*2d9fd380Sjfb8856606 }
552*2d9fd380Sjfb8856606
553*2d9fd380Sjfb8856606 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
554*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
555*2d9fd380Sjfb8856606 return;
556*2d9fd380Sjfb8856606 }
557*2d9fd380Sjfb8856606
558*2d9fd380Sjfb8856606 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
559*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
560*2d9fd380Sjfb8856606 "burst_size");
561*2d9fd380Sjfb8856606 return;
562*2d9fd380Sjfb8856606 }
563*2d9fd380Sjfb8856606
564*2d9fd380Sjfb8856606 t0 += 6;
565*2d9fd380Sjfb8856606
566*2d9fd380Sjfb8856606 status = rte_swx_pipeline_port_in_config(p->p,
567*2d9fd380Sjfb8856606 port_id,
568*2d9fd380Sjfb8856606 "ethdev",
569*2d9fd380Sjfb8856606 ¶ms);
570*2d9fd380Sjfb8856606 } else if (strcmp(tokens[t0], "source") == 0) {
571*2d9fd380Sjfb8856606 struct rte_swx_port_source_params params;
572*2d9fd380Sjfb8856606 struct mempool *mp;
573*2d9fd380Sjfb8856606
574*2d9fd380Sjfb8856606 if (n_tokens < t0 + 3) {
575*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH,
576*2d9fd380Sjfb8856606 "pipeline port in source");
577*2d9fd380Sjfb8856606 return;
578*2d9fd380Sjfb8856606 }
579*2d9fd380Sjfb8856606
580*2d9fd380Sjfb8856606 mp = mempool_find(obj, tokens[t0 + 1]);
581*2d9fd380Sjfb8856606 if (!mp) {
582*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
583*2d9fd380Sjfb8856606 "mempool_name");
584*2d9fd380Sjfb8856606 return;
585*2d9fd380Sjfb8856606 }
586*2d9fd380Sjfb8856606 params.pool = mp->m;
587*2d9fd380Sjfb8856606
588*2d9fd380Sjfb8856606 params.file_name = tokens[t0 + 2];
589*2d9fd380Sjfb8856606
590*2d9fd380Sjfb8856606 t0 += 3;
591*2d9fd380Sjfb8856606
592*2d9fd380Sjfb8856606 status = rte_swx_pipeline_port_in_config(p->p,
593*2d9fd380Sjfb8856606 port_id,
594*2d9fd380Sjfb8856606 "source",
595*2d9fd380Sjfb8856606 ¶ms);
596*2d9fd380Sjfb8856606 } else {
597*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
598*2d9fd380Sjfb8856606 return;
599*2d9fd380Sjfb8856606 }
600*2d9fd380Sjfb8856606
601*2d9fd380Sjfb8856606 if (status) {
602*2d9fd380Sjfb8856606 snprintf(out, out_size, "port in error.");
603*2d9fd380Sjfb8856606 return;
604*2d9fd380Sjfb8856606 }
605*2d9fd380Sjfb8856606
606*2d9fd380Sjfb8856606 if (n_tokens != t0) {
607*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
608*2d9fd380Sjfb8856606 return;
609*2d9fd380Sjfb8856606 }
610*2d9fd380Sjfb8856606 }
611*2d9fd380Sjfb8856606
612*2d9fd380Sjfb8856606 static const char cmd_pipeline_port_out_help[] =
613*2d9fd380Sjfb8856606 "pipeline <pipeline_name> port out <port_id>\n"
614*2d9fd380Sjfb8856606 " link <link_name> txq <txq_id> bsz <burst_size>\n"
615*2d9fd380Sjfb8856606 " | sink <file_name> | none\n";
616*2d9fd380Sjfb8856606
617*2d9fd380Sjfb8856606 static void
cmd_pipeline_port_out(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)618*2d9fd380Sjfb8856606 cmd_pipeline_port_out(char **tokens,
619*2d9fd380Sjfb8856606 uint32_t n_tokens,
620*2d9fd380Sjfb8856606 char *out,
621*2d9fd380Sjfb8856606 size_t out_size,
622*2d9fd380Sjfb8856606 void *obj)
623*2d9fd380Sjfb8856606 {
624*2d9fd380Sjfb8856606 struct pipeline *p;
625*2d9fd380Sjfb8856606 int status;
626*2d9fd380Sjfb8856606 uint32_t port_id = 0, t0;
627*2d9fd380Sjfb8856606
628*2d9fd380Sjfb8856606 if (n_tokens < 6) {
629*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
630*2d9fd380Sjfb8856606 return;
631*2d9fd380Sjfb8856606 }
632*2d9fd380Sjfb8856606
633*2d9fd380Sjfb8856606 p = pipeline_find(obj, tokens[1]);
634*2d9fd380Sjfb8856606 if (!p || p->ctl) {
635*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
636*2d9fd380Sjfb8856606 return;
637*2d9fd380Sjfb8856606 }
638*2d9fd380Sjfb8856606
639*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "port") != 0) {
640*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
641*2d9fd380Sjfb8856606 return;
642*2d9fd380Sjfb8856606 }
643*2d9fd380Sjfb8856606
644*2d9fd380Sjfb8856606 if (strcmp(tokens[3], "out") != 0) {
645*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
646*2d9fd380Sjfb8856606 return;
647*2d9fd380Sjfb8856606 }
648*2d9fd380Sjfb8856606
649*2d9fd380Sjfb8856606 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
650*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
651*2d9fd380Sjfb8856606 return;
652*2d9fd380Sjfb8856606 }
653*2d9fd380Sjfb8856606
654*2d9fd380Sjfb8856606 t0 = 5;
655*2d9fd380Sjfb8856606
656*2d9fd380Sjfb8856606 if (strcmp(tokens[t0], "link") == 0) {
657*2d9fd380Sjfb8856606 struct rte_swx_port_ethdev_writer_params params;
658*2d9fd380Sjfb8856606 struct link *link;
659*2d9fd380Sjfb8856606
660*2d9fd380Sjfb8856606 if (n_tokens < t0 + 6) {
661*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH,
662*2d9fd380Sjfb8856606 "pipeline port out link");
663*2d9fd380Sjfb8856606 return;
664*2d9fd380Sjfb8856606 }
665*2d9fd380Sjfb8856606
666*2d9fd380Sjfb8856606 link = link_find(obj, tokens[t0 + 1]);
667*2d9fd380Sjfb8856606 if (!link) {
668*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
669*2d9fd380Sjfb8856606 "link_name");
670*2d9fd380Sjfb8856606 return;
671*2d9fd380Sjfb8856606 }
672*2d9fd380Sjfb8856606 params.dev_name = link->dev_name;
673*2d9fd380Sjfb8856606
674*2d9fd380Sjfb8856606 if (strcmp(tokens[t0 + 2], "txq") != 0) {
675*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
676*2d9fd380Sjfb8856606 return;
677*2d9fd380Sjfb8856606 }
678*2d9fd380Sjfb8856606
679*2d9fd380Sjfb8856606 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
680*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
681*2d9fd380Sjfb8856606 "queue_id");
682*2d9fd380Sjfb8856606 return;
683*2d9fd380Sjfb8856606 }
684*2d9fd380Sjfb8856606
685*2d9fd380Sjfb8856606 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
686*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
687*2d9fd380Sjfb8856606 return;
688*2d9fd380Sjfb8856606 }
689*2d9fd380Sjfb8856606
690*2d9fd380Sjfb8856606 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
691*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID,
692*2d9fd380Sjfb8856606 "burst_size");
693*2d9fd380Sjfb8856606 return;
694*2d9fd380Sjfb8856606 }
695*2d9fd380Sjfb8856606
696*2d9fd380Sjfb8856606 t0 += 6;
697*2d9fd380Sjfb8856606
698*2d9fd380Sjfb8856606 status = rte_swx_pipeline_port_out_config(p->p,
699*2d9fd380Sjfb8856606 port_id,
700*2d9fd380Sjfb8856606 "ethdev",
701*2d9fd380Sjfb8856606 ¶ms);
702*2d9fd380Sjfb8856606 } else if (strcmp(tokens[t0], "sink") == 0) {
703*2d9fd380Sjfb8856606 struct rte_swx_port_sink_params params;
704*2d9fd380Sjfb8856606
705*2d9fd380Sjfb8856606 params.file_name = strcmp(tokens[t0 + 1], "none") ?
706*2d9fd380Sjfb8856606 tokens[t0 + 1] : NULL;
707*2d9fd380Sjfb8856606
708*2d9fd380Sjfb8856606 t0 += 2;
709*2d9fd380Sjfb8856606
710*2d9fd380Sjfb8856606 status = rte_swx_pipeline_port_out_config(p->p,
711*2d9fd380Sjfb8856606 port_id,
712*2d9fd380Sjfb8856606 "sink",
713*2d9fd380Sjfb8856606 ¶ms);
714*2d9fd380Sjfb8856606 } else {
715*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
716*2d9fd380Sjfb8856606 return;
717*2d9fd380Sjfb8856606 }
718*2d9fd380Sjfb8856606
719*2d9fd380Sjfb8856606 if (status) {
720*2d9fd380Sjfb8856606 snprintf(out, out_size, "port out error.");
721*2d9fd380Sjfb8856606 return;
722*2d9fd380Sjfb8856606 }
723*2d9fd380Sjfb8856606
724*2d9fd380Sjfb8856606 if (n_tokens != t0) {
725*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
726*2d9fd380Sjfb8856606 return;
727*2d9fd380Sjfb8856606 }
728*2d9fd380Sjfb8856606 }
729*2d9fd380Sjfb8856606
730*2d9fd380Sjfb8856606 static const char cmd_pipeline_build_help[] =
731*2d9fd380Sjfb8856606 "pipeline <pipeline_name> build <spec_file>\n";
732*2d9fd380Sjfb8856606
733*2d9fd380Sjfb8856606 static void
cmd_pipeline_build(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)734*2d9fd380Sjfb8856606 cmd_pipeline_build(char **tokens,
735*2d9fd380Sjfb8856606 uint32_t n_tokens,
736*2d9fd380Sjfb8856606 char *out,
737*2d9fd380Sjfb8856606 size_t out_size,
738*2d9fd380Sjfb8856606 void *obj)
739*2d9fd380Sjfb8856606 {
740*2d9fd380Sjfb8856606 struct pipeline *p = NULL;
741*2d9fd380Sjfb8856606 FILE *spec = NULL;
742*2d9fd380Sjfb8856606 uint32_t err_line;
743*2d9fd380Sjfb8856606 const char *err_msg;
744*2d9fd380Sjfb8856606 int status;
745*2d9fd380Sjfb8856606
746*2d9fd380Sjfb8856606 if (n_tokens != 4) {
747*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
748*2d9fd380Sjfb8856606 return;
749*2d9fd380Sjfb8856606 }
750*2d9fd380Sjfb8856606
751*2d9fd380Sjfb8856606 p = pipeline_find(obj, tokens[1]);
752*2d9fd380Sjfb8856606 if (!p || p->ctl) {
753*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
754*2d9fd380Sjfb8856606 return;
755*2d9fd380Sjfb8856606 }
756*2d9fd380Sjfb8856606
757*2d9fd380Sjfb8856606 spec = fopen(tokens[3], "r");
758*2d9fd380Sjfb8856606 if (!spec) {
759*2d9fd380Sjfb8856606 snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
760*2d9fd380Sjfb8856606 return;
761*2d9fd380Sjfb8856606 }
762*2d9fd380Sjfb8856606
763*2d9fd380Sjfb8856606 status = rte_swx_pipeline_build_from_spec(p->p,
764*2d9fd380Sjfb8856606 spec,
765*2d9fd380Sjfb8856606 &err_line,
766*2d9fd380Sjfb8856606 &err_msg);
767*2d9fd380Sjfb8856606 fclose(spec);
768*2d9fd380Sjfb8856606 if (status) {
769*2d9fd380Sjfb8856606 snprintf(out, out_size, "Error %d at line %u: %s\n.",
770*2d9fd380Sjfb8856606 status, err_line, err_msg);
771*2d9fd380Sjfb8856606 return;
772*2d9fd380Sjfb8856606 }
773*2d9fd380Sjfb8856606
774*2d9fd380Sjfb8856606 p->ctl = rte_swx_ctl_pipeline_create(p->p);
775*2d9fd380Sjfb8856606 if (!p->ctl) {
776*2d9fd380Sjfb8856606 snprintf(out, out_size, "Pipeline control create failed.");
777*2d9fd380Sjfb8856606 rte_swx_pipeline_free(p->p);
778*2d9fd380Sjfb8856606 return;
779*2d9fd380Sjfb8856606 }
780*2d9fd380Sjfb8856606 }
781*2d9fd380Sjfb8856606
782*2d9fd380Sjfb8856606 static void
table_entry_free(struct rte_swx_table_entry * entry)783*2d9fd380Sjfb8856606 table_entry_free(struct rte_swx_table_entry *entry)
784*2d9fd380Sjfb8856606 {
785*2d9fd380Sjfb8856606 if (!entry)
786*2d9fd380Sjfb8856606 return;
787*2d9fd380Sjfb8856606
788*2d9fd380Sjfb8856606 free(entry->key);
789*2d9fd380Sjfb8856606 free(entry->key_mask);
790*2d9fd380Sjfb8856606 free(entry->action_data);
791*2d9fd380Sjfb8856606 free(entry);
792*2d9fd380Sjfb8856606 }
793*2d9fd380Sjfb8856606
794*2d9fd380Sjfb8856606 static const char cmd_pipeline_table_update_help[] =
795*2d9fd380Sjfb8856606 "pipeline <pipeline_name> table <table_name> update <file_name_add> "
796*2d9fd380Sjfb8856606 "<file_name_delete> <file_name_default>";
797*2d9fd380Sjfb8856606
798*2d9fd380Sjfb8856606 static void
cmd_pipeline_table_update(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)799*2d9fd380Sjfb8856606 cmd_pipeline_table_update(char **tokens,
800*2d9fd380Sjfb8856606 uint32_t n_tokens,
801*2d9fd380Sjfb8856606 char *out,
802*2d9fd380Sjfb8856606 size_t out_size,
803*2d9fd380Sjfb8856606 void *obj)
804*2d9fd380Sjfb8856606 {
805*2d9fd380Sjfb8856606 struct pipeline *p;
806*2d9fd380Sjfb8856606 char *pipeline_name, *table_name, *line = NULL;
807*2d9fd380Sjfb8856606 char *file_name_add, *file_name_delete, *file_name_default;
808*2d9fd380Sjfb8856606 FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL;
809*2d9fd380Sjfb8856606 uint32_t line_id;
810*2d9fd380Sjfb8856606 int status;
811*2d9fd380Sjfb8856606
812*2d9fd380Sjfb8856606 if (n_tokens != 8) {
813*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
814*2d9fd380Sjfb8856606 return;
815*2d9fd380Sjfb8856606 }
816*2d9fd380Sjfb8856606
817*2d9fd380Sjfb8856606 pipeline_name = tokens[1];
818*2d9fd380Sjfb8856606 p = pipeline_find(obj, pipeline_name);
819*2d9fd380Sjfb8856606 if (!p || !p->ctl) {
820*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
821*2d9fd380Sjfb8856606 return;
822*2d9fd380Sjfb8856606 }
823*2d9fd380Sjfb8856606
824*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "table") != 0) {
825*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
826*2d9fd380Sjfb8856606 return;
827*2d9fd380Sjfb8856606 }
828*2d9fd380Sjfb8856606
829*2d9fd380Sjfb8856606 table_name = tokens[3];
830*2d9fd380Sjfb8856606
831*2d9fd380Sjfb8856606 if (strcmp(tokens[4], "update") != 0) {
832*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update");
833*2d9fd380Sjfb8856606 return;
834*2d9fd380Sjfb8856606 }
835*2d9fd380Sjfb8856606
836*2d9fd380Sjfb8856606 file_name_add = tokens[5];
837*2d9fd380Sjfb8856606 file_name_delete = tokens[6];
838*2d9fd380Sjfb8856606 file_name_default = tokens[7];
839*2d9fd380Sjfb8856606
840*2d9fd380Sjfb8856606 /* File open. */
841*2d9fd380Sjfb8856606 if (strcmp(file_name_add, "none")) {
842*2d9fd380Sjfb8856606 file_add = fopen(file_name_add, "r");
843*2d9fd380Sjfb8856606 if (!file_add) {
844*2d9fd380Sjfb8856606 snprintf(out, out_size, "Cannot open file %s",
845*2d9fd380Sjfb8856606 file_name_add);
846*2d9fd380Sjfb8856606 goto error;
847*2d9fd380Sjfb8856606 }
848*2d9fd380Sjfb8856606 }
849*2d9fd380Sjfb8856606
850*2d9fd380Sjfb8856606 if (strcmp(file_name_delete, "none")) {
851*2d9fd380Sjfb8856606 file_delete = fopen(file_name_delete, "r");
852*2d9fd380Sjfb8856606 if (!file_delete) {
853*2d9fd380Sjfb8856606 snprintf(out, out_size, "Cannot open file %s",
854*2d9fd380Sjfb8856606 file_name_delete);
855*2d9fd380Sjfb8856606 goto error;
856*2d9fd380Sjfb8856606 }
857*2d9fd380Sjfb8856606 }
858*2d9fd380Sjfb8856606
859*2d9fd380Sjfb8856606 if (strcmp(file_name_default, "none")) {
860*2d9fd380Sjfb8856606 file_default = fopen(file_name_default, "r");
861*2d9fd380Sjfb8856606 if (!file_default) {
862*2d9fd380Sjfb8856606 snprintf(out, out_size, "Cannot open file %s",
863*2d9fd380Sjfb8856606 file_name_default);
864*2d9fd380Sjfb8856606 goto error;
865*2d9fd380Sjfb8856606 }
866*2d9fd380Sjfb8856606 }
867*2d9fd380Sjfb8856606
868*2d9fd380Sjfb8856606 if (!file_add && !file_delete && !file_default) {
869*2d9fd380Sjfb8856606 snprintf(out, out_size, "Nothing to be done.");
870*2d9fd380Sjfb8856606 return;
871*2d9fd380Sjfb8856606 }
872*2d9fd380Sjfb8856606
873*2d9fd380Sjfb8856606 /* Buffer allocation. */
874*2d9fd380Sjfb8856606 line = malloc(2048);
875*2d9fd380Sjfb8856606 if (!line) {
876*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
877*2d9fd380Sjfb8856606 goto error;
878*2d9fd380Sjfb8856606 }
879*2d9fd380Sjfb8856606
880*2d9fd380Sjfb8856606 /* Add. */
881*2d9fd380Sjfb8856606 if (file_add)
882*2d9fd380Sjfb8856606 for (line_id = 1; ; line_id++) {
883*2d9fd380Sjfb8856606 struct rte_swx_table_entry *entry;
884*2d9fd380Sjfb8856606
885*2d9fd380Sjfb8856606 if (fgets(line, 2048, file_add) == NULL)
886*2d9fd380Sjfb8856606 break;
887*2d9fd380Sjfb8856606
888*2d9fd380Sjfb8856606 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
889*2d9fd380Sjfb8856606 table_name,
890*2d9fd380Sjfb8856606 line);
891*2d9fd380Sjfb8856606 if (!entry) {
892*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_FILE_ERR,
893*2d9fd380Sjfb8856606 file_name_add, line_id);
894*2d9fd380Sjfb8856606 goto error;
895*2d9fd380Sjfb8856606 }
896*2d9fd380Sjfb8856606
897*2d9fd380Sjfb8856606 status = rte_swx_ctl_pipeline_table_entry_add(p->ctl,
898*2d9fd380Sjfb8856606 table_name,
899*2d9fd380Sjfb8856606 entry);
900*2d9fd380Sjfb8856606 table_entry_free(entry);
901*2d9fd380Sjfb8856606 if (status) {
902*2d9fd380Sjfb8856606 snprintf(out, out_size,
903*2d9fd380Sjfb8856606 "Invalid entry in file %s at line %u",
904*2d9fd380Sjfb8856606 file_name_add, line_id);
905*2d9fd380Sjfb8856606 goto error;
906*2d9fd380Sjfb8856606 }
907*2d9fd380Sjfb8856606 }
908*2d9fd380Sjfb8856606
909*2d9fd380Sjfb8856606
910*2d9fd380Sjfb8856606 /* Delete. */
911*2d9fd380Sjfb8856606 if (file_delete)
912*2d9fd380Sjfb8856606 for (line_id = 1; ; line_id++) {
913*2d9fd380Sjfb8856606 struct rte_swx_table_entry *entry;
914*2d9fd380Sjfb8856606
915*2d9fd380Sjfb8856606 if (fgets(line, 2048, file_delete) == NULL)
916*2d9fd380Sjfb8856606 break;
917*2d9fd380Sjfb8856606
918*2d9fd380Sjfb8856606 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
919*2d9fd380Sjfb8856606 table_name,
920*2d9fd380Sjfb8856606 line);
921*2d9fd380Sjfb8856606 if (!entry) {
922*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_FILE_ERR,
923*2d9fd380Sjfb8856606 file_name_delete, line_id);
924*2d9fd380Sjfb8856606 goto error;
925*2d9fd380Sjfb8856606 }
926*2d9fd380Sjfb8856606
927*2d9fd380Sjfb8856606 status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl,
928*2d9fd380Sjfb8856606 table_name,
929*2d9fd380Sjfb8856606 entry);
930*2d9fd380Sjfb8856606 table_entry_free(entry);
931*2d9fd380Sjfb8856606 if (status) {
932*2d9fd380Sjfb8856606 snprintf(out, out_size,
933*2d9fd380Sjfb8856606 "Invalid entry in file %s at line %u",
934*2d9fd380Sjfb8856606 file_name_delete, line_id);
935*2d9fd380Sjfb8856606 goto error;
936*2d9fd380Sjfb8856606 }
937*2d9fd380Sjfb8856606 }
938*2d9fd380Sjfb8856606
939*2d9fd380Sjfb8856606 /* Default. */
940*2d9fd380Sjfb8856606 if (file_default)
941*2d9fd380Sjfb8856606 for (line_id = 1; ; line_id++) {
942*2d9fd380Sjfb8856606 struct rte_swx_table_entry *entry;
943*2d9fd380Sjfb8856606
944*2d9fd380Sjfb8856606 if (fgets(line, 2048, file_default) == NULL)
945*2d9fd380Sjfb8856606 break;
946*2d9fd380Sjfb8856606
947*2d9fd380Sjfb8856606 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
948*2d9fd380Sjfb8856606 table_name,
949*2d9fd380Sjfb8856606 line);
950*2d9fd380Sjfb8856606 if (!entry) {
951*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_FILE_ERR,
952*2d9fd380Sjfb8856606 file_name_default, line_id);
953*2d9fd380Sjfb8856606 goto error;
954*2d9fd380Sjfb8856606 }
955*2d9fd380Sjfb8856606
956*2d9fd380Sjfb8856606 status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl,
957*2d9fd380Sjfb8856606 table_name,
958*2d9fd380Sjfb8856606 entry);
959*2d9fd380Sjfb8856606 table_entry_free(entry);
960*2d9fd380Sjfb8856606 if (status) {
961*2d9fd380Sjfb8856606 snprintf(out, out_size,
962*2d9fd380Sjfb8856606 "Invalid entry in file %s at line %u",
963*2d9fd380Sjfb8856606 file_name_default, line_id);
964*2d9fd380Sjfb8856606 goto error;
965*2d9fd380Sjfb8856606 }
966*2d9fd380Sjfb8856606 }
967*2d9fd380Sjfb8856606
968*2d9fd380Sjfb8856606 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
969*2d9fd380Sjfb8856606 if (status) {
970*2d9fd380Sjfb8856606 snprintf(out, out_size, "Commit failed.");
971*2d9fd380Sjfb8856606 goto error;
972*2d9fd380Sjfb8856606 }
973*2d9fd380Sjfb8856606
974*2d9fd380Sjfb8856606
975*2d9fd380Sjfb8856606 rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
976*2d9fd380Sjfb8856606
977*2d9fd380Sjfb8856606 free(line);
978*2d9fd380Sjfb8856606 if (file_add)
979*2d9fd380Sjfb8856606 fclose(file_add);
980*2d9fd380Sjfb8856606 if (file_delete)
981*2d9fd380Sjfb8856606 fclose(file_delete);
982*2d9fd380Sjfb8856606 if (file_default)
983*2d9fd380Sjfb8856606 fclose(file_default);
984*2d9fd380Sjfb8856606 return;
985*2d9fd380Sjfb8856606
986*2d9fd380Sjfb8856606 error:
987*2d9fd380Sjfb8856606 rte_swx_ctl_pipeline_abort(p->ctl);
988*2d9fd380Sjfb8856606 free(line);
989*2d9fd380Sjfb8856606 if (file_add)
990*2d9fd380Sjfb8856606 fclose(file_add);
991*2d9fd380Sjfb8856606 if (file_delete)
992*2d9fd380Sjfb8856606 fclose(file_delete);
993*2d9fd380Sjfb8856606 if (file_default)
994*2d9fd380Sjfb8856606 fclose(file_default);
995*2d9fd380Sjfb8856606 }
996*2d9fd380Sjfb8856606
997*2d9fd380Sjfb8856606 static const char cmd_pipeline_stats_help[] =
998*2d9fd380Sjfb8856606 "pipeline <pipeline_name> stats\n";
999*2d9fd380Sjfb8856606
1000*2d9fd380Sjfb8856606 static void
cmd_pipeline_stats(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)1001*2d9fd380Sjfb8856606 cmd_pipeline_stats(char **tokens,
1002*2d9fd380Sjfb8856606 uint32_t n_tokens,
1003*2d9fd380Sjfb8856606 char *out,
1004*2d9fd380Sjfb8856606 size_t out_size,
1005*2d9fd380Sjfb8856606 void *obj)
1006*2d9fd380Sjfb8856606 {
1007*2d9fd380Sjfb8856606 struct rte_swx_ctl_pipeline_info info;
1008*2d9fd380Sjfb8856606 struct pipeline *p;
1009*2d9fd380Sjfb8856606 uint32_t i;
1010*2d9fd380Sjfb8856606 int status;
1011*2d9fd380Sjfb8856606
1012*2d9fd380Sjfb8856606 if (n_tokens != 3) {
1013*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1014*2d9fd380Sjfb8856606 return;
1015*2d9fd380Sjfb8856606 }
1016*2d9fd380Sjfb8856606
1017*2d9fd380Sjfb8856606 p = pipeline_find(obj, tokens[1]);
1018*2d9fd380Sjfb8856606 if (!p || !p->ctl) {
1019*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1020*2d9fd380Sjfb8856606 return;
1021*2d9fd380Sjfb8856606 }
1022*2d9fd380Sjfb8856606
1023*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "stats")) {
1024*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1025*2d9fd380Sjfb8856606 return;
1026*2d9fd380Sjfb8856606 }
1027*2d9fd380Sjfb8856606
1028*2d9fd380Sjfb8856606 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
1029*2d9fd380Sjfb8856606 if (status) {
1030*2d9fd380Sjfb8856606 snprintf(out, out_size, "Pipeline info get error.");
1031*2d9fd380Sjfb8856606 return;
1032*2d9fd380Sjfb8856606 }
1033*2d9fd380Sjfb8856606
1034*2d9fd380Sjfb8856606 snprintf(out, out_size, "Input ports:\n");
1035*2d9fd380Sjfb8856606 out_size -= strlen(out);
1036*2d9fd380Sjfb8856606 out += strlen(out);
1037*2d9fd380Sjfb8856606
1038*2d9fd380Sjfb8856606 for (i = 0; i < info.n_ports_in; i++) {
1039*2d9fd380Sjfb8856606 struct rte_swx_port_in_stats stats;
1040*2d9fd380Sjfb8856606
1041*2d9fd380Sjfb8856606 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
1042*2d9fd380Sjfb8856606
1043*2d9fd380Sjfb8856606 snprintf(out, out_size, "\tPort %u:"
1044*2d9fd380Sjfb8856606 " packets %" PRIu64
1045*2d9fd380Sjfb8856606 " bytes %" PRIu64
1046*2d9fd380Sjfb8856606 " empty %" PRIu64 "\n",
1047*2d9fd380Sjfb8856606 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
1048*2d9fd380Sjfb8856606 out_size -= strlen(out);
1049*2d9fd380Sjfb8856606 out += strlen(out);
1050*2d9fd380Sjfb8856606 }
1051*2d9fd380Sjfb8856606
1052*2d9fd380Sjfb8856606 snprintf(out, out_size, "Output ports:\n");
1053*2d9fd380Sjfb8856606 out_size -= strlen(out);
1054*2d9fd380Sjfb8856606 out += strlen(out);
1055*2d9fd380Sjfb8856606
1056*2d9fd380Sjfb8856606 for (i = 0; i < info.n_ports_out; i++) {
1057*2d9fd380Sjfb8856606 struct rte_swx_port_out_stats stats;
1058*2d9fd380Sjfb8856606
1059*2d9fd380Sjfb8856606 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
1060*2d9fd380Sjfb8856606
1061*2d9fd380Sjfb8856606 snprintf(out, out_size, "\tPort %u:"
1062*2d9fd380Sjfb8856606 " packets %" PRIu64
1063*2d9fd380Sjfb8856606 " bytes %" PRIu64 "\n",
1064*2d9fd380Sjfb8856606 i, stats.n_pkts, stats.n_bytes);
1065*2d9fd380Sjfb8856606 out_size -= strlen(out);
1066*2d9fd380Sjfb8856606 out += strlen(out);
1067*2d9fd380Sjfb8856606 }
1068*2d9fd380Sjfb8856606 }
1069*2d9fd380Sjfb8856606
1070*2d9fd380Sjfb8856606 static const char cmd_thread_pipeline_enable_help[] =
1071*2d9fd380Sjfb8856606 "thread <thread_id> pipeline <pipeline_name> enable\n";
1072*2d9fd380Sjfb8856606
1073*2d9fd380Sjfb8856606 static void
cmd_thread_pipeline_enable(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)1074*2d9fd380Sjfb8856606 cmd_thread_pipeline_enable(char **tokens,
1075*2d9fd380Sjfb8856606 uint32_t n_tokens,
1076*2d9fd380Sjfb8856606 char *out,
1077*2d9fd380Sjfb8856606 size_t out_size,
1078*2d9fd380Sjfb8856606 void *obj)
1079*2d9fd380Sjfb8856606 {
1080*2d9fd380Sjfb8856606 char *pipeline_name;
1081*2d9fd380Sjfb8856606 struct pipeline *p;
1082*2d9fd380Sjfb8856606 uint32_t thread_id;
1083*2d9fd380Sjfb8856606 int status;
1084*2d9fd380Sjfb8856606
1085*2d9fd380Sjfb8856606 if (n_tokens != 5) {
1086*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1087*2d9fd380Sjfb8856606 return;
1088*2d9fd380Sjfb8856606 }
1089*2d9fd380Sjfb8856606
1090*2d9fd380Sjfb8856606 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
1091*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
1092*2d9fd380Sjfb8856606 return;
1093*2d9fd380Sjfb8856606 }
1094*2d9fd380Sjfb8856606
1095*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "pipeline") != 0) {
1096*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
1097*2d9fd380Sjfb8856606 return;
1098*2d9fd380Sjfb8856606 }
1099*2d9fd380Sjfb8856606
1100*2d9fd380Sjfb8856606 pipeline_name = tokens[3];
1101*2d9fd380Sjfb8856606 p = pipeline_find(obj, pipeline_name);
1102*2d9fd380Sjfb8856606 if (!p || !p->ctl) {
1103*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1104*2d9fd380Sjfb8856606 return;
1105*2d9fd380Sjfb8856606 }
1106*2d9fd380Sjfb8856606
1107*2d9fd380Sjfb8856606 if (strcmp(tokens[4], "enable") != 0) {
1108*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1109*2d9fd380Sjfb8856606 return;
1110*2d9fd380Sjfb8856606 }
1111*2d9fd380Sjfb8856606
1112*2d9fd380Sjfb8856606 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
1113*2d9fd380Sjfb8856606 if (status) {
1114*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
1115*2d9fd380Sjfb8856606 return;
1116*2d9fd380Sjfb8856606 }
1117*2d9fd380Sjfb8856606 }
1118*2d9fd380Sjfb8856606
1119*2d9fd380Sjfb8856606 static const char cmd_thread_pipeline_disable_help[] =
1120*2d9fd380Sjfb8856606 "thread <thread_id> pipeline <pipeline_name> disable\n";
1121*2d9fd380Sjfb8856606
1122*2d9fd380Sjfb8856606 static void
cmd_thread_pipeline_disable(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * obj)1123*2d9fd380Sjfb8856606 cmd_thread_pipeline_disable(char **tokens,
1124*2d9fd380Sjfb8856606 uint32_t n_tokens,
1125*2d9fd380Sjfb8856606 char *out,
1126*2d9fd380Sjfb8856606 size_t out_size,
1127*2d9fd380Sjfb8856606 void *obj)
1128*2d9fd380Sjfb8856606 {
1129*2d9fd380Sjfb8856606 struct pipeline *p;
1130*2d9fd380Sjfb8856606 char *pipeline_name;
1131*2d9fd380Sjfb8856606 uint32_t thread_id;
1132*2d9fd380Sjfb8856606 int status;
1133*2d9fd380Sjfb8856606
1134*2d9fd380Sjfb8856606 if (n_tokens != 5) {
1135*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1136*2d9fd380Sjfb8856606 return;
1137*2d9fd380Sjfb8856606 }
1138*2d9fd380Sjfb8856606
1139*2d9fd380Sjfb8856606 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
1140*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
1141*2d9fd380Sjfb8856606 return;
1142*2d9fd380Sjfb8856606 }
1143*2d9fd380Sjfb8856606
1144*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "pipeline") != 0) {
1145*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
1146*2d9fd380Sjfb8856606 return;
1147*2d9fd380Sjfb8856606 }
1148*2d9fd380Sjfb8856606
1149*2d9fd380Sjfb8856606 pipeline_name = tokens[3];
1150*2d9fd380Sjfb8856606 p = pipeline_find(obj, pipeline_name);
1151*2d9fd380Sjfb8856606 if (!p || !p->ctl) {
1152*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1153*2d9fd380Sjfb8856606 return;
1154*2d9fd380Sjfb8856606 }
1155*2d9fd380Sjfb8856606
1156*2d9fd380Sjfb8856606 if (strcmp(tokens[4], "disable") != 0) {
1157*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1158*2d9fd380Sjfb8856606 return;
1159*2d9fd380Sjfb8856606 }
1160*2d9fd380Sjfb8856606
1161*2d9fd380Sjfb8856606 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
1162*2d9fd380Sjfb8856606 if (status) {
1163*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_CMD_FAIL,
1164*2d9fd380Sjfb8856606 "thread pipeline disable");
1165*2d9fd380Sjfb8856606 return;
1166*2d9fd380Sjfb8856606 }
1167*2d9fd380Sjfb8856606 }
1168*2d9fd380Sjfb8856606
1169*2d9fd380Sjfb8856606 static void
cmd_help(char ** tokens,uint32_t n_tokens,char * out,size_t out_size,void * arg __rte_unused)1170*2d9fd380Sjfb8856606 cmd_help(char **tokens,
1171*2d9fd380Sjfb8856606 uint32_t n_tokens,
1172*2d9fd380Sjfb8856606 char *out,
1173*2d9fd380Sjfb8856606 size_t out_size,
1174*2d9fd380Sjfb8856606 void *arg __rte_unused)
1175*2d9fd380Sjfb8856606 {
1176*2d9fd380Sjfb8856606 tokens++;
1177*2d9fd380Sjfb8856606 n_tokens--;
1178*2d9fd380Sjfb8856606
1179*2d9fd380Sjfb8856606 if (n_tokens == 0) {
1180*2d9fd380Sjfb8856606 snprintf(out, out_size,
1181*2d9fd380Sjfb8856606 "Type 'help <command>' for command details.\n\n"
1182*2d9fd380Sjfb8856606 "List of commands:\n"
1183*2d9fd380Sjfb8856606 "\tmempool\n"
1184*2d9fd380Sjfb8856606 "\tlink\n"
1185*2d9fd380Sjfb8856606 "\tpipeline create\n"
1186*2d9fd380Sjfb8856606 "\tpipeline port in\n"
1187*2d9fd380Sjfb8856606 "\tpipeline port out\n"
1188*2d9fd380Sjfb8856606 "\tpipeline build\n"
1189*2d9fd380Sjfb8856606 "\tpipeline table update\n"
1190*2d9fd380Sjfb8856606 "\tpipeline stats\n"
1191*2d9fd380Sjfb8856606 "\tthread pipeline enable\n"
1192*2d9fd380Sjfb8856606 "\tthread pipeline disable\n\n");
1193*2d9fd380Sjfb8856606 return;
1194*2d9fd380Sjfb8856606 }
1195*2d9fd380Sjfb8856606
1196*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "mempool") == 0) {
1197*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
1198*2d9fd380Sjfb8856606 return;
1199*2d9fd380Sjfb8856606 }
1200*2d9fd380Sjfb8856606
1201*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "link") == 0) {
1202*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n", cmd_link_help);
1203*2d9fd380Sjfb8856606 return;
1204*2d9fd380Sjfb8856606 }
1205*2d9fd380Sjfb8856606
1206*2d9fd380Sjfb8856606 if ((strcmp(tokens[0], "pipeline") == 0) &&
1207*2d9fd380Sjfb8856606 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
1208*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
1209*2d9fd380Sjfb8856606 return;
1210*2d9fd380Sjfb8856606 }
1211*2d9fd380Sjfb8856606
1212*2d9fd380Sjfb8856606 if ((strcmp(tokens[0], "pipeline") == 0) &&
1213*2d9fd380Sjfb8856606 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
1214*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "in") == 0) {
1215*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n",
1216*2d9fd380Sjfb8856606 cmd_pipeline_port_in_help);
1217*2d9fd380Sjfb8856606 return;
1218*2d9fd380Sjfb8856606 }
1219*2d9fd380Sjfb8856606
1220*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "out") == 0) {
1221*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n",
1222*2d9fd380Sjfb8856606 cmd_pipeline_port_out_help);
1223*2d9fd380Sjfb8856606 return;
1224*2d9fd380Sjfb8856606 }
1225*2d9fd380Sjfb8856606 }
1226*2d9fd380Sjfb8856606
1227*2d9fd380Sjfb8856606 if ((strcmp(tokens[0], "pipeline") == 0) &&
1228*2d9fd380Sjfb8856606 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
1229*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
1230*2d9fd380Sjfb8856606 return;
1231*2d9fd380Sjfb8856606 }
1232*2d9fd380Sjfb8856606
1233*2d9fd380Sjfb8856606 if ((strcmp(tokens[0], "pipeline") == 0) &&
1234*2d9fd380Sjfb8856606 (n_tokens == 3) &&
1235*2d9fd380Sjfb8856606 (strcmp(tokens[1], "table") == 0) &&
1236*2d9fd380Sjfb8856606 (strcmp(tokens[2], "update") == 0)) {
1237*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n",
1238*2d9fd380Sjfb8856606 cmd_pipeline_table_update_help);
1239*2d9fd380Sjfb8856606 return;
1240*2d9fd380Sjfb8856606 }
1241*2d9fd380Sjfb8856606
1242*2d9fd380Sjfb8856606 if ((strcmp(tokens[0], "pipeline") == 0) &&
1243*2d9fd380Sjfb8856606 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
1244*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
1245*2d9fd380Sjfb8856606 return;
1246*2d9fd380Sjfb8856606 }
1247*2d9fd380Sjfb8856606
1248*2d9fd380Sjfb8856606 if ((n_tokens == 3) &&
1249*2d9fd380Sjfb8856606 (strcmp(tokens[0], "thread") == 0) &&
1250*2d9fd380Sjfb8856606 (strcmp(tokens[1], "pipeline") == 0)) {
1251*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "enable") == 0) {
1252*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n",
1253*2d9fd380Sjfb8856606 cmd_thread_pipeline_enable_help);
1254*2d9fd380Sjfb8856606 return;
1255*2d9fd380Sjfb8856606 }
1256*2d9fd380Sjfb8856606
1257*2d9fd380Sjfb8856606 if (strcmp(tokens[2], "disable") == 0) {
1258*2d9fd380Sjfb8856606 snprintf(out, out_size, "\n%s\n",
1259*2d9fd380Sjfb8856606 cmd_thread_pipeline_disable_help);
1260*2d9fd380Sjfb8856606 return;
1261*2d9fd380Sjfb8856606 }
1262*2d9fd380Sjfb8856606 }
1263*2d9fd380Sjfb8856606
1264*2d9fd380Sjfb8856606 snprintf(out, out_size, "Invalid command\n");
1265*2d9fd380Sjfb8856606 }
1266*2d9fd380Sjfb8856606
1267*2d9fd380Sjfb8856606 void
cli_process(char * in,char * out,size_t out_size,void * obj)1268*2d9fd380Sjfb8856606 cli_process(char *in, char *out, size_t out_size, void *obj)
1269*2d9fd380Sjfb8856606 {
1270*2d9fd380Sjfb8856606 char *tokens[CMD_MAX_TOKENS];
1271*2d9fd380Sjfb8856606 uint32_t n_tokens = RTE_DIM(tokens);
1272*2d9fd380Sjfb8856606 int status;
1273*2d9fd380Sjfb8856606
1274*2d9fd380Sjfb8856606 if (is_comment(in))
1275*2d9fd380Sjfb8856606 return;
1276*2d9fd380Sjfb8856606
1277*2d9fd380Sjfb8856606 status = parse_tokenize_string(in, tokens, &n_tokens);
1278*2d9fd380Sjfb8856606 if (status) {
1279*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
1280*2d9fd380Sjfb8856606 return;
1281*2d9fd380Sjfb8856606 }
1282*2d9fd380Sjfb8856606
1283*2d9fd380Sjfb8856606 if (n_tokens == 0)
1284*2d9fd380Sjfb8856606 return;
1285*2d9fd380Sjfb8856606
1286*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "help") == 0) {
1287*2d9fd380Sjfb8856606 cmd_help(tokens, n_tokens, out, out_size, obj);
1288*2d9fd380Sjfb8856606 return;
1289*2d9fd380Sjfb8856606 }
1290*2d9fd380Sjfb8856606
1291*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "mempool") == 0) {
1292*2d9fd380Sjfb8856606 cmd_mempool(tokens, n_tokens, out, out_size, obj);
1293*2d9fd380Sjfb8856606 return;
1294*2d9fd380Sjfb8856606 }
1295*2d9fd380Sjfb8856606
1296*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "link") == 0) {
1297*2d9fd380Sjfb8856606 if (strcmp(tokens[1], "show") == 0) {
1298*2d9fd380Sjfb8856606 cmd_link_show(tokens, n_tokens, out, out_size, obj);
1299*2d9fd380Sjfb8856606 return;
1300*2d9fd380Sjfb8856606 }
1301*2d9fd380Sjfb8856606
1302*2d9fd380Sjfb8856606 cmd_link(tokens, n_tokens, out, out_size, obj);
1303*2d9fd380Sjfb8856606 return;
1304*2d9fd380Sjfb8856606 }
1305*2d9fd380Sjfb8856606
1306*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "pipeline") == 0) {
1307*2d9fd380Sjfb8856606 if ((n_tokens >= 3) &&
1308*2d9fd380Sjfb8856606 (strcmp(tokens[2], "create") == 0)) {
1309*2d9fd380Sjfb8856606 cmd_pipeline_create(tokens, n_tokens, out, out_size,
1310*2d9fd380Sjfb8856606 obj);
1311*2d9fd380Sjfb8856606 return;
1312*2d9fd380Sjfb8856606 }
1313*2d9fd380Sjfb8856606
1314*2d9fd380Sjfb8856606 if ((n_tokens >= 4) &&
1315*2d9fd380Sjfb8856606 (strcmp(tokens[2], "port") == 0) &&
1316*2d9fd380Sjfb8856606 (strcmp(tokens[3], "in") == 0)) {
1317*2d9fd380Sjfb8856606 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
1318*2d9fd380Sjfb8856606 obj);
1319*2d9fd380Sjfb8856606 return;
1320*2d9fd380Sjfb8856606 }
1321*2d9fd380Sjfb8856606
1322*2d9fd380Sjfb8856606 if ((n_tokens >= 4) &&
1323*2d9fd380Sjfb8856606 (strcmp(tokens[2], "port") == 0) &&
1324*2d9fd380Sjfb8856606 (strcmp(tokens[3], "out") == 0)) {
1325*2d9fd380Sjfb8856606 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
1326*2d9fd380Sjfb8856606 obj);
1327*2d9fd380Sjfb8856606 return;
1328*2d9fd380Sjfb8856606 }
1329*2d9fd380Sjfb8856606
1330*2d9fd380Sjfb8856606 if ((n_tokens >= 3) &&
1331*2d9fd380Sjfb8856606 (strcmp(tokens[2], "build") == 0)) {
1332*2d9fd380Sjfb8856606 cmd_pipeline_build(tokens, n_tokens, out, out_size,
1333*2d9fd380Sjfb8856606 obj);
1334*2d9fd380Sjfb8856606 return;
1335*2d9fd380Sjfb8856606 }
1336*2d9fd380Sjfb8856606
1337*2d9fd380Sjfb8856606 if ((n_tokens >= 3) &&
1338*2d9fd380Sjfb8856606 (strcmp(tokens[2], "table") == 0)) {
1339*2d9fd380Sjfb8856606 cmd_pipeline_table_update(tokens, n_tokens, out,
1340*2d9fd380Sjfb8856606 out_size, obj);
1341*2d9fd380Sjfb8856606 return;
1342*2d9fd380Sjfb8856606 }
1343*2d9fd380Sjfb8856606
1344*2d9fd380Sjfb8856606 if ((n_tokens >= 3) &&
1345*2d9fd380Sjfb8856606 (strcmp(tokens[2], "stats") == 0)) {
1346*2d9fd380Sjfb8856606 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
1347*2d9fd380Sjfb8856606 obj);
1348*2d9fd380Sjfb8856606 return;
1349*2d9fd380Sjfb8856606 }
1350*2d9fd380Sjfb8856606 }
1351*2d9fd380Sjfb8856606
1352*2d9fd380Sjfb8856606 if (strcmp(tokens[0], "thread") == 0) {
1353*2d9fd380Sjfb8856606 if ((n_tokens >= 5) &&
1354*2d9fd380Sjfb8856606 (strcmp(tokens[4], "enable") == 0)) {
1355*2d9fd380Sjfb8856606 cmd_thread_pipeline_enable(tokens, n_tokens,
1356*2d9fd380Sjfb8856606 out, out_size, obj);
1357*2d9fd380Sjfb8856606 return;
1358*2d9fd380Sjfb8856606 }
1359*2d9fd380Sjfb8856606
1360*2d9fd380Sjfb8856606 if ((n_tokens >= 5) &&
1361*2d9fd380Sjfb8856606 (strcmp(tokens[4], "disable") == 0)) {
1362*2d9fd380Sjfb8856606 cmd_thread_pipeline_disable(tokens, n_tokens,
1363*2d9fd380Sjfb8856606 out, out_size, obj);
1364*2d9fd380Sjfb8856606 return;
1365*2d9fd380Sjfb8856606 }
1366*2d9fd380Sjfb8856606 }
1367*2d9fd380Sjfb8856606
1368*2d9fd380Sjfb8856606 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
1369*2d9fd380Sjfb8856606 }
1370*2d9fd380Sjfb8856606
1371*2d9fd380Sjfb8856606 int
cli_script_process(const char * file_name,size_t msg_in_len_max,size_t msg_out_len_max,void * obj)1372*2d9fd380Sjfb8856606 cli_script_process(const char *file_name,
1373*2d9fd380Sjfb8856606 size_t msg_in_len_max,
1374*2d9fd380Sjfb8856606 size_t msg_out_len_max,
1375*2d9fd380Sjfb8856606 void *obj)
1376*2d9fd380Sjfb8856606 {
1377*2d9fd380Sjfb8856606 char *msg_in = NULL, *msg_out = NULL;
1378*2d9fd380Sjfb8856606 FILE *f = NULL;
1379*2d9fd380Sjfb8856606
1380*2d9fd380Sjfb8856606 /* Check input arguments */
1381*2d9fd380Sjfb8856606 if ((file_name == NULL) ||
1382*2d9fd380Sjfb8856606 (strlen(file_name) == 0) ||
1383*2d9fd380Sjfb8856606 (msg_in_len_max == 0) ||
1384*2d9fd380Sjfb8856606 (msg_out_len_max == 0))
1385*2d9fd380Sjfb8856606 return -EINVAL;
1386*2d9fd380Sjfb8856606
1387*2d9fd380Sjfb8856606 msg_in = malloc(msg_in_len_max + 1);
1388*2d9fd380Sjfb8856606 msg_out = malloc(msg_out_len_max + 1);
1389*2d9fd380Sjfb8856606 if ((msg_in == NULL) ||
1390*2d9fd380Sjfb8856606 (msg_out == NULL)) {
1391*2d9fd380Sjfb8856606 free(msg_out);
1392*2d9fd380Sjfb8856606 free(msg_in);
1393*2d9fd380Sjfb8856606 return -ENOMEM;
1394*2d9fd380Sjfb8856606 }
1395*2d9fd380Sjfb8856606
1396*2d9fd380Sjfb8856606 /* Open input file */
1397*2d9fd380Sjfb8856606 f = fopen(file_name, "r");
1398*2d9fd380Sjfb8856606 if (f == NULL) {
1399*2d9fd380Sjfb8856606 free(msg_out);
1400*2d9fd380Sjfb8856606 free(msg_in);
1401*2d9fd380Sjfb8856606 return -EIO;
1402*2d9fd380Sjfb8856606 }
1403*2d9fd380Sjfb8856606
1404*2d9fd380Sjfb8856606 /* Read file */
1405*2d9fd380Sjfb8856606 for ( ; ; ) {
1406*2d9fd380Sjfb8856606 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
1407*2d9fd380Sjfb8856606 break;
1408*2d9fd380Sjfb8856606
1409*2d9fd380Sjfb8856606 printf("%s", msg_in);
1410*2d9fd380Sjfb8856606 msg_out[0] = 0;
1411*2d9fd380Sjfb8856606
1412*2d9fd380Sjfb8856606 cli_process(msg_in,
1413*2d9fd380Sjfb8856606 msg_out,
1414*2d9fd380Sjfb8856606 msg_out_len_max,
1415*2d9fd380Sjfb8856606 obj);
1416*2d9fd380Sjfb8856606
1417*2d9fd380Sjfb8856606 if (strlen(msg_out))
1418*2d9fd380Sjfb8856606 printf("%s", msg_out);
1419*2d9fd380Sjfb8856606 }
1420*2d9fd380Sjfb8856606
1421*2d9fd380Sjfb8856606 /* Close file */
1422*2d9fd380Sjfb8856606 fclose(f);
1423*2d9fd380Sjfb8856606 free(msg_out);
1424*2d9fd380Sjfb8856606 free(msg_in);
1425*2d9fd380Sjfb8856606 return 0;
1426*2d9fd380Sjfb8856606 }
1427