Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2018 Intel Corporation
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <stdint.h>
7 : : #include <stdlib.h>
8 : : #include <string.h>
9 : : #include <unistd.h>
10 : :
11 : : #include <rte_common.h>
12 : : #include <rte_cycles.h>
13 : : #include <rte_string_fns.h>
14 : :
15 : : #include "rte_eth_softnic_internals.h"
16 : :
17 : : #ifndef CMD_MAX_TOKENS
18 : : #define CMD_MAX_TOKENS 256
19 : : #endif
20 : :
21 : : #ifndef MAX_LINE_SIZE
22 : : #define MAX_LINE_SIZE 2048
23 : : #endif
24 : :
25 : : #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
26 : : #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
27 : : #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
28 : : #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
29 : : #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
30 : : #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
31 : : #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
32 : : #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
33 : : #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
34 : : #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
35 : : #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
36 : :
37 : : static int
38 : 0 : parser_read_uint64(uint64_t *value, char *p)
39 : : {
40 : : uint64_t val = 0;
41 : :
42 [ # # # # ]: 0 : if (!value || !p || !p[0])
43 : : return -EINVAL;
44 : :
45 : 0 : val = strtoull(p, &p, 0);
46 [ # # ]: 0 : if (p[0])
47 : : return -EINVAL;
48 : :
49 : 0 : *value = val;
50 : 0 : return 0;
51 : : }
52 : :
53 : : static int
54 : 0 : parser_read_uint32(uint32_t *value, char *p)
55 : : {
56 : : uint32_t val = 0;
57 : :
58 [ # # # # ]: 0 : if (!value || !p || !p[0])
59 : : return -EINVAL;
60 : :
61 : 0 : val = strtoul(p, &p, 0);
62 [ # # ]: 0 : if (p[0])
63 : : return -EINVAL;
64 : :
65 : 0 : *value = val;
66 : 0 : return 0;
67 : : }
68 : :
69 : : #define PARSE_DELIMITER " \f\n\r\t\v"
70 : :
71 : : static int
72 : 0 : parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
73 : : {
74 : : uint32_t i;
75 : :
76 [ # # # # : 0 : if (!string || !tokens || !n_tokens || !*n_tokens)
# # ]
77 : : return -EINVAL;
78 : :
79 [ # # ]: 0 : for (i = 0; i < *n_tokens; i++) {
80 : 0 : tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
81 [ # # ]: 0 : if (!tokens[i])
82 : : break;
83 : : }
84 : :
85 [ # # # # ]: 0 : if (i == *n_tokens && strtok_r(string, PARSE_DELIMITER, &string))
86 : : return -E2BIG;
87 : :
88 : 0 : *n_tokens = i;
89 : 0 : return 0;
90 : : }
91 : :
92 : : static int
93 : 0 : is_comment(char *in)
94 : : {
95 [ # # # # ]: 0 : if ((strlen(in) && index("!#%;", in[0])) ||
96 [ # # ]: 0 : (strncmp(in, "//", 2) == 0) ||
97 [ # # ]: 0 : (strncmp(in, "--", 2) == 0))
98 : 0 : return 1;
99 : :
100 : : return 0;
101 : : }
102 : :
103 : : /**
104 : : * mempool <mempool_name>
105 : : * buffer <buffer_size>
106 : : * pool <pool_size>
107 : : * cache <cache_size>
108 : : */
109 : : static void
110 : 0 : cmd_mempool(struct pmd_internals *softnic,
111 : : char **tokens,
112 : : uint32_t n_tokens,
113 : : char *out,
114 : : size_t out_size)
115 : : {
116 : : struct softnic_mempool_params p;
117 : : char *name;
118 : : struct softnic_mempool *mempool;
119 : :
120 [ # # ]: 0 : if (n_tokens != 8) {
121 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
122 : 0 : return;
123 : : }
124 : :
125 : 0 : name = tokens[1];
126 : :
127 [ # # ]: 0 : if (strcmp(tokens[2], "buffer") != 0) {
128 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
129 : 0 : return;
130 : : }
131 : :
132 [ # # ]: 0 : if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
133 : : snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
134 : 0 : return;
135 : : }
136 : :
137 [ # # ]: 0 : if (strcmp(tokens[4], "pool") != 0) {
138 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
139 : 0 : return;
140 : : }
141 : :
142 [ # # ]: 0 : if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
143 : : snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
144 : 0 : return;
145 : : }
146 : :
147 [ # # ]: 0 : if (strcmp(tokens[6], "cache") != 0) {
148 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
149 : 0 : return;
150 : : }
151 : :
152 [ # # ]: 0 : if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
153 : : snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
154 : 0 : return;
155 : : }
156 : :
157 : 0 : mempool = softnic_mempool_create(softnic, name, &p);
158 [ # # ]: 0 : if (mempool == NULL) {
159 : 0 : snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
160 : 0 : return;
161 : : }
162 : : }
163 : :
164 : : /**
165 : : * swq <swq_name>
166 : : * size <size>
167 : : */
168 : : static void
169 : 0 : cmd_swq(struct pmd_internals *softnic,
170 : : char **tokens,
171 : : uint32_t n_tokens,
172 : : char *out,
173 : : size_t out_size)
174 : : {
175 : : struct softnic_swq_params p;
176 : : char *name;
177 : : struct softnic_swq *swq;
178 : :
179 [ # # ]: 0 : if (n_tokens != 4) {
180 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
181 : 0 : return;
182 : : }
183 : :
184 : 0 : name = tokens[1];
185 : :
186 [ # # ]: 0 : if (strcmp(tokens[2], "size") != 0) {
187 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
188 : 0 : return;
189 : : }
190 : :
191 [ # # ]: 0 : if (parser_read_uint32(&p.size, tokens[3]) != 0) {
192 : : snprintf(out, out_size, MSG_ARG_INVALID, "size");
193 : 0 : return;
194 : : }
195 : :
196 : 0 : swq = softnic_swq_create(softnic, name, &p);
197 [ # # ]: 0 : if (swq == NULL) {
198 : 0 : snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
199 : 0 : return;
200 : : }
201 : : }
202 : :
203 : : /**
204 : : * pipeline codegen <spec_file> <code_file>
205 : : */
206 : : static void
207 : 0 : cmd_softnic_pipeline_codegen(struct pmd_internals *softnic __rte_unused,
208 : : char **tokens,
209 : : uint32_t n_tokens,
210 : : char *out,
211 : : size_t out_size)
212 : : {
213 : : FILE *spec_file = NULL;
214 : : FILE *code_file = NULL;
215 : : uint32_t err_line;
216 : : const char *err_msg;
217 : : int status;
218 : :
219 [ # # ]: 0 : if (n_tokens != 4) {
220 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
221 : 0 : return;
222 : : }
223 : :
224 : 0 : spec_file = fopen(tokens[2], "r");
225 [ # # ]: 0 : if (!spec_file) {
226 : 0 : snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
227 : 0 : return;
228 : : }
229 : :
230 : 0 : code_file = fopen(tokens[3], "w");
231 [ # # ]: 0 : if (!code_file) {
232 : 0 : snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
233 : 0 : fclose(spec_file);
234 : 0 : return;
235 : : }
236 : :
237 : 0 : status = rte_swx_pipeline_codegen(spec_file,
238 : : code_file,
239 : : &err_line,
240 : : &err_msg);
241 : :
242 : 0 : fclose(spec_file);
243 : 0 : fclose(code_file);
244 : :
245 [ # # ]: 0 : if (status) {
246 : 0 : snprintf(out, out_size, "Error %d at line %u: %s\n.",
247 : : status, err_line, err_msg);
248 : 0 : return;
249 : : }
250 : : }
251 : :
252 : : /**
253 : : * pipeline libbuild <code_file> <lib_file>
254 : : */
255 : : static void
256 : 0 : cmd_softnic_pipeline_libbuild(struct pmd_internals *softnic __rte_unused,
257 : : char **tokens,
258 : : uint32_t n_tokens,
259 : : char *out,
260 : : size_t out_size)
261 : : {
262 : : char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
263 : : char *install_dir, *cwd = NULL, *buffer = NULL;
264 : : size_t length;
265 : : int status = 0;
266 : :
267 [ # # ]: 0 : if (n_tokens != 4) {
268 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
269 : 0 : goto free;
270 : : }
271 : :
272 : 0 : install_dir = getenv("RTE_INSTALL_DIR");
273 [ # # ]: 0 : if (!install_dir) {
274 : 0 : cwd = malloc(MAX_LINE_SIZE);
275 [ # # ]: 0 : if (!cwd) {
276 : : snprintf(out, out_size, MSG_OUT_OF_MEMORY);
277 : 0 : goto free;
278 : : }
279 : :
280 : : install_dir = getcwd(cwd, MAX_LINE_SIZE);
281 [ # # ]: 0 : if (!install_dir) {
282 : : snprintf(out, out_size, "Error: Path too long.\n");
283 : 0 : goto free;
284 : : }
285 : : }
286 : :
287 : : snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
288 : 0 : out_size -= strlen(out);
289 : 0 : out += strlen(out);
290 : :
291 : 0 : code_file = tokens[2];
292 : 0 : length = strnlen(code_file, MAX_LINE_SIZE);
293 [ # # ]: 0 : if (length < 3 ||
294 [ # # ]: 0 : code_file[length - 2] != '.' ||
295 [ # # ]: 0 : code_file[length - 1] != 'c') {
296 : : snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
297 : 0 : goto free;
298 : : }
299 : :
300 : 0 : lib_file = tokens[3];
301 : 0 : length = strnlen(lib_file, MAX_LINE_SIZE);
302 [ # # ]: 0 : if (length < 4 ||
303 [ # # ]: 0 : lib_file[length - 3] != '.' ||
304 [ # # ]: 0 : lib_file[length - 2] != 's' ||
305 [ # # ]: 0 : lib_file[length - 1] != 'o') {
306 : : snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
307 : 0 : goto free;
308 : : }
309 : :
310 : 0 : obj_file = malloc(length);
311 : 0 : log_file = malloc(length + 2);
312 [ # # ]: 0 : if (!obj_file || !log_file) {
313 : : snprintf(out, out_size, MSG_OUT_OF_MEMORY);
314 : 0 : goto free;
315 : : }
316 : :
317 : : memcpy(obj_file, lib_file, length - 2);
318 : 0 : obj_file[length - 2] = 'o';
319 : 0 : obj_file[length - 1] = 0;
320 : :
321 : : memcpy(log_file, lib_file, length - 2);
322 : 0 : log_file[length - 2] = 'l';
323 : 0 : log_file[length - 1] = 'o';
324 : 0 : log_file[length] = 'g';
325 : 0 : log_file[length + 1] = 0;
326 : :
327 : 0 : buffer = malloc(MAX_LINE_SIZE);
328 [ # # ]: 0 : if (!buffer) {
329 : : snprintf(out, out_size, MSG_OUT_OF_MEMORY);
330 : 0 : goto free;
331 : : }
332 : :
333 : : snprintf(buffer,
334 : : MAX_LINE_SIZE,
335 : : "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
336 : : "-I %s/lib/pipeline "
337 : : "-I %s/lib/eal/include "
338 : : "-I %s/lib/eal/x86/include "
339 : : "-I %s/lib/eal/include/generic "
340 : : "-I %s/lib/meter "
341 : : "-I %s/lib/port "
342 : : "-I %s/lib/table "
343 : : "-I %s/lib/pipeline "
344 : : "-I %s/config "
345 : : "-I %s/build "
346 : : "-I %s/lib/eal/linux/include "
347 : : ">%s 2>&1 "
348 : : "&& "
349 : : "gcc -shared %s -o %s "
350 : : ">>%s 2>&1",
351 : : obj_file,
352 : : code_file,
353 : : install_dir,
354 : : install_dir,
355 : : install_dir,
356 : : install_dir,
357 : : install_dir,
358 : : install_dir,
359 : : install_dir,
360 : : install_dir,
361 : : install_dir,
362 : : install_dir,
363 : : install_dir,
364 : : log_file,
365 : : obj_file,
366 : : lib_file,
367 : : log_file);
368 : :
369 : 0 : status = system(buffer);
370 [ # # ]: 0 : if (status) {
371 : : snprintf(out,
372 : : out_size,
373 : : "Library build failed, see file \"%s\" for details.\n",
374 : : log_file);
375 : 0 : goto free;
376 : : }
377 : :
378 : 0 : free:
379 : 0 : free(cwd);
380 : 0 : free(obj_file);
381 : 0 : free(log_file);
382 : 0 : free(buffer);
383 : 0 : }
384 : :
385 : : /**
386 : : * pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>
387 : : */
388 : : static void
389 : 0 : cmd_softnic_pipeline_build(struct pmd_internals *softnic,
390 : : char **tokens,
391 : : uint32_t n_tokens,
392 : : char *out,
393 : : size_t out_size)
394 : : {
395 : : struct pipeline *p = NULL;
396 : : char *pipeline_name, *lib_file_name, *iospec_file_name;
397 : 0 : uint32_t numa_node = 0;
398 : :
399 : : /* Parsing. */
400 [ # # ]: 0 : if (n_tokens != 9) {
401 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
402 : 0 : return;
403 : : }
404 : :
405 : 0 : pipeline_name = tokens[1];
406 : :
407 [ # # ]: 0 : if (strcmp(tokens[2], "build")) {
408 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
409 : 0 : return;
410 : : }
411 : :
412 [ # # ]: 0 : if (strcmp(tokens[3], "lib")) {
413 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
414 : 0 : return;
415 : : }
416 : :
417 : 0 : lib_file_name = tokens[4];
418 : :
419 [ # # ]: 0 : if (strcmp(tokens[5], "io")) {
420 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
421 : 0 : return;
422 : : }
423 : :
424 : 0 : iospec_file_name = tokens[6];
425 : :
426 [ # # ]: 0 : if (strcmp(tokens[7], "numa")) {
427 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
428 : 0 : return;
429 : : }
430 : :
431 [ # # ]: 0 : if (parser_read_uint32(&numa_node, tokens[8])) {
432 : : snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
433 : 0 : return;
434 : : }
435 : :
436 : : /* Pipeline create. */
437 : 0 : p = softnic_pipeline_create(softnic,
438 : : pipeline_name,
439 : : lib_file_name,
440 : : iospec_file_name,
441 : : (int)numa_node);
442 [ # # ]: 0 : if (!p)
443 : : snprintf(out, out_size, "Pipeline creation failed.\n");
444 : : }
445 : :
446 : : static void
447 : 0 : table_entry_free(struct rte_swx_table_entry *entry)
448 : : {
449 [ # # ]: 0 : if (!entry)
450 : : return;
451 : :
452 : 0 : free(entry->key);
453 : 0 : free(entry->key_mask);
454 : 0 : free(entry->action_data);
455 : 0 : free(entry);
456 : : }
457 : :
458 : : static int
459 : 0 : pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
460 : : const char *table_name,
461 : : FILE *file,
462 : : uint32_t *file_line_number)
463 : : {
464 : : char *line = NULL;
465 : : uint32_t line_id = 0;
466 : : int status = 0;
467 : :
468 : : /* Buffer allocation. */
469 : 0 : line = malloc(MAX_LINE_SIZE);
470 [ # # ]: 0 : if (!line)
471 : : return -ENOMEM;
472 : :
473 : : /* File read. */
474 : 0 : for (line_id = 1; ; line_id++) {
475 : : struct rte_swx_table_entry *entry;
476 : : int is_blank_or_comment;
477 : :
478 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
479 : : break;
480 : :
481 : 0 : entry = rte_swx_ctl_pipeline_table_entry_read(p,
482 : : table_name,
483 : : line,
484 : : &is_blank_or_comment);
485 [ # # ]: 0 : if (!entry) {
486 [ # # ]: 0 : if (is_blank_or_comment)
487 : 0 : continue;
488 : :
489 : : status = -EINVAL;
490 : 0 : goto error;
491 : : }
492 : :
493 : 0 : status = rte_swx_ctl_pipeline_table_entry_add(p,
494 : : table_name,
495 : : entry);
496 : 0 : table_entry_free(entry);
497 [ # # ]: 0 : if (status)
498 : 0 : goto error;
499 : : }
500 : :
501 : 0 : error:
502 : 0 : free(line);
503 : 0 : *file_line_number = line_id;
504 : 0 : return status;
505 : : }
506 : :
507 : : /**
508 : : * pipeline <pipeline_name> table <table_name> add <file_name>
509 : : */
510 : : static void
511 : 0 : cmd_softnic_pipeline_table_add(struct pmd_internals *softnic,
512 : : char **tokens,
513 : : uint32_t n_tokens,
514 : : char *out,
515 : : size_t out_size)
516 : : {
517 : : struct pipeline *p;
518 : : char *pipeline_name, *table_name, *file_name;
519 : : FILE *file = NULL;
520 : 0 : uint32_t file_line_number = 0;
521 : : int status;
522 : :
523 [ # # ]: 0 : if (n_tokens != 6) {
524 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
525 : 0 : return;
526 : : }
527 : :
528 : 0 : pipeline_name = tokens[1];
529 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
530 [ # # ]: 0 : if (!p) {
531 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
532 : 0 : return;
533 : : }
534 : :
535 : 0 : table_name = tokens[3];
536 : :
537 : 0 : file_name = tokens[5];
538 : 0 : file = fopen(file_name, "r");
539 [ # # ]: 0 : if (!file) {
540 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
541 : 0 : return;
542 : : }
543 : :
544 : 0 : status = pipeline_table_entries_add(p->ctl,
545 : : table_name,
546 : : file,
547 : : &file_line_number);
548 [ # # ]: 0 : if (status)
549 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
550 : : file_name,
551 : : file_line_number);
552 : :
553 : 0 : fclose(file);
554 : : }
555 : :
556 : : static int
557 : 0 : pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
558 : : const char *table_name,
559 : : FILE *file,
560 : : uint32_t *file_line_number)
561 : : {
562 : : char *line = NULL;
563 : : uint32_t line_id = 0;
564 : : int status = 0;
565 : :
566 : : /* Buffer allocation. */
567 : 0 : line = malloc(MAX_LINE_SIZE);
568 [ # # ]: 0 : if (!line)
569 : : return -ENOMEM;
570 : :
571 : : /* File read. */
572 : 0 : for (line_id = 1; ; line_id++) {
573 : : struct rte_swx_table_entry *entry;
574 : : int is_blank_or_comment;
575 : :
576 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
577 : : break;
578 : :
579 : 0 : entry = rte_swx_ctl_pipeline_table_entry_read(p,
580 : : table_name,
581 : : line,
582 : : &is_blank_or_comment);
583 [ # # ]: 0 : if (!entry) {
584 [ # # ]: 0 : if (is_blank_or_comment)
585 : 0 : continue;
586 : :
587 : : status = -EINVAL;
588 : 0 : goto error;
589 : : }
590 : :
591 : 0 : status = rte_swx_ctl_pipeline_table_entry_delete(p,
592 : : table_name,
593 : : entry);
594 : 0 : table_entry_free(entry);
595 [ # # ]: 0 : if (status)
596 : 0 : goto error;
597 : : }
598 : :
599 : 0 : error:
600 : 0 : *file_line_number = line_id;
601 : 0 : free(line);
602 : 0 : return status;
603 : : }
604 : :
605 : : /**
606 : : * pipeline <pipeline_name> table <table_name> delete <file_name>
607 : : */
608 : : static void
609 : 0 : cmd_softnic_pipeline_table_delete(struct pmd_internals *softnic,
610 : : char **tokens,
611 : : uint32_t n_tokens,
612 : : char *out,
613 : : size_t out_size)
614 : : {
615 : : struct pipeline *p;
616 : : char *pipeline_name, *table_name, *file_name;
617 : : FILE *file = NULL;
618 : 0 : uint32_t file_line_number = 0;
619 : : int status;
620 : :
621 [ # # ]: 0 : if (n_tokens != 6) {
622 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
623 : 0 : return;
624 : : }
625 : :
626 : 0 : pipeline_name = tokens[1];
627 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
628 [ # # ]: 0 : if (!p) {
629 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
630 : 0 : return;
631 : : }
632 : :
633 : 0 : table_name = tokens[3];
634 : :
635 : 0 : file_name = tokens[5];
636 : 0 : file = fopen(file_name, "r");
637 [ # # ]: 0 : if (!file) {
638 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
639 : 0 : return;
640 : : }
641 : :
642 : 0 : status = pipeline_table_entries_delete(p->ctl,
643 : : table_name,
644 : : file,
645 : : &file_line_number);
646 [ # # ]: 0 : if (status)
647 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
648 : : file_name,
649 : : file_line_number);
650 : :
651 : 0 : fclose(file);
652 : : }
653 : :
654 : : static int
655 : 0 : pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
656 : : const char *table_name,
657 : : FILE *file,
658 : : uint32_t *file_line_number)
659 : : {
660 : : char *line = NULL;
661 : : uint32_t line_id = 0;
662 : : int status = 0;
663 : :
664 : : /* Buffer allocation. */
665 : 0 : line = malloc(MAX_LINE_SIZE);
666 [ # # ]: 0 : if (!line)
667 : : return -ENOMEM;
668 : :
669 : : /* File read. */
670 : 0 : for (line_id = 1; ; line_id++) {
671 : : struct rte_swx_table_entry *entry;
672 : : int is_blank_or_comment;
673 : :
674 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
675 : : break;
676 : :
677 : 0 : entry = rte_swx_ctl_pipeline_table_entry_read(p,
678 : : table_name,
679 : : line,
680 : : &is_blank_or_comment);
681 [ # # ]: 0 : if (!entry) {
682 [ # # ]: 0 : if (is_blank_or_comment)
683 : 0 : continue;
684 : :
685 : : status = -EINVAL;
686 : 0 : goto error;
687 : : }
688 : :
689 : 0 : status = rte_swx_ctl_pipeline_table_default_entry_add(p,
690 : : table_name,
691 : : entry);
692 : 0 : table_entry_free(entry);
693 [ # # ]: 0 : if (status)
694 : 0 : goto error;
695 : : }
696 : :
697 : 0 : error:
698 : 0 : *file_line_number = line_id;
699 : 0 : free(line);
700 : 0 : return status;
701 : : }
702 : :
703 : : /**
704 : : * pipeline <pipeline_name> table <table_name> default <file_name>
705 : : */
706 : : static void
707 : 0 : cmd_softnic_pipeline_table_default(struct pmd_internals *softnic,
708 : : char **tokens,
709 : : uint32_t n_tokens,
710 : : char *out,
711 : : size_t out_size)
712 : : {
713 : : struct pipeline *p;
714 : : char *pipeline_name, *table_name, *file_name;
715 : : FILE *file = NULL;
716 : 0 : uint32_t file_line_number = 0;
717 : : int status;
718 : :
719 [ # # ]: 0 : if (n_tokens != 6) {
720 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
721 : 0 : return;
722 : : }
723 : :
724 : 0 : pipeline_name = tokens[1];
725 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
726 [ # # ]: 0 : if (!p) {
727 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
728 : 0 : return;
729 : : }
730 : :
731 : 0 : table_name = tokens[3];
732 : :
733 : 0 : file_name = tokens[5];
734 : 0 : file = fopen(file_name, "r");
735 [ # # ]: 0 : if (!file) {
736 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
737 : 0 : return;
738 : : }
739 : :
740 : 0 : status = pipeline_table_default_entry_add(p->ctl,
741 : : table_name,
742 : : file,
743 : : &file_line_number);
744 [ # # ]: 0 : if (status)
745 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
746 : : file_name,
747 : : file_line_number);
748 : :
749 : 0 : fclose(file);
750 : : }
751 : :
752 : : /**
753 : : * pipeline <pipeline_name> table <table_name> show [filename]
754 : : */
755 : : static void
756 : 0 : cmd_softnic_pipeline_table_show(struct pmd_internals *softnic __rte_unused,
757 : : char **tokens,
758 : : uint32_t n_tokens,
759 : : char *out,
760 : : size_t out_size)
761 : : {
762 : : struct pipeline *p;
763 : : char *pipeline_name, *table_name;
764 : : FILE *file = NULL;
765 : : int status;
766 : :
767 [ # # ]: 0 : if (n_tokens != 5 && n_tokens != 6) {
768 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
769 : 0 : return;
770 : : }
771 : :
772 : 0 : pipeline_name = tokens[1];
773 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
774 [ # # ]: 0 : if (!p) {
775 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
776 : 0 : return;
777 : : }
778 : :
779 : 0 : table_name = tokens[3];
780 [ # # ]: 0 : file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
781 [ # # ]: 0 : if (!file) {
782 : 0 : snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
783 : 0 : return;
784 : : }
785 : :
786 : 0 : status = rte_swx_ctl_pipeline_table_fprintf(file, p->ctl, table_name);
787 [ # # ]: 0 : if (status)
788 : : snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
789 : :
790 : : if (file)
791 : 0 : fclose(file);
792 : : }
793 : :
794 : : /**
795 : : * pipeline <pipeline_name> selector <selector_name> group add
796 : : */
797 : : static void
798 : 0 : cmd_softnic_pipeline_selector_group_add(struct pmd_internals *softnic,
799 : : char **tokens,
800 : : uint32_t n_tokens,
801 : : char *out,
802 : : size_t out_size)
803 : : {
804 : : struct pipeline *p;
805 : : char *pipeline_name, *selector_name;
806 : : uint32_t group_id;
807 : : int status;
808 : :
809 [ # # ]: 0 : if (n_tokens != 6) {
810 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
811 : 0 : return;
812 : : }
813 : :
814 : 0 : pipeline_name = tokens[1];
815 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
816 [ # # ]: 0 : if (!p) {
817 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
818 : 0 : return;
819 : : }
820 : :
821 [ # # ]: 0 : if (strcmp(tokens[2], "selector") != 0) {
822 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
823 : 0 : return;
824 : : }
825 : :
826 : 0 : selector_name = tokens[3];
827 : :
828 [ # # ]: 0 : if (strcmp(tokens[4], "group") ||
829 [ # # ]: 0 : strcmp(tokens[5], "add")) {
830 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
831 : 0 : return;
832 : : }
833 : :
834 : 0 : status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
835 : : selector_name,
836 : : &group_id);
837 [ # # ]: 0 : if (status)
838 : 0 : snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
839 : : else
840 : 0 : snprintf(out, out_size, "Group ID: %u\n", group_id);
841 : : }
842 : :
843 : : /**
844 : : * pipeline <pipeline_name> selector <selector_name> group delete <group_id>
845 : : */
846 : : static void
847 : 0 : cmd_softnic_pipeline_selector_group_delete(struct pmd_internals *softnic,
848 : : char **tokens,
849 : : uint32_t n_tokens,
850 : : char *out,
851 : : size_t out_size)
852 : : {
853 : : struct pipeline *p;
854 : : char *pipeline_name, *selector_name;
855 : : uint32_t group_id;
856 : : int status;
857 : :
858 [ # # ]: 0 : if (n_tokens != 7) {
859 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
860 : 0 : return;
861 : : }
862 : :
863 : 0 : pipeline_name = tokens[1];
864 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
865 [ # # ]: 0 : if (!p) {
866 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
867 : 0 : return;
868 : : }
869 : :
870 [ # # ]: 0 : if (strcmp(tokens[2], "selector") != 0) {
871 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
872 : 0 : return;
873 : : }
874 : :
875 : 0 : selector_name = tokens[3];
876 : :
877 [ # # ]: 0 : if (strcmp(tokens[4], "group") ||
878 [ # # ]: 0 : strcmp(tokens[5], "delete")) {
879 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
880 : 0 : return;
881 : : }
882 : :
883 [ # # ]: 0 : if (parser_read_uint32(&group_id, tokens[6]) != 0) {
884 : : snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
885 : 0 : return;
886 : : }
887 : :
888 : 0 : status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
889 : : selector_name,
890 : : group_id);
891 [ # # ]: 0 : if (status)
892 : 0 : snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
893 : : }
894 : :
895 : : #define GROUP_MEMBER_INFO_TOKENS_MAX 6
896 : :
897 : : static int
898 : : token_is_comment(const char *token)
899 : : {
900 [ # # ]: 0 : if ((token[0] == '#') ||
901 [ # # ]: 0 : (token[0] == ';') ||
902 [ # # ]: 0 : ((token[0] == '/') && (token[1] == '/')))
903 : : return 1; /* TRUE. */
904 : :
905 : : return 0; /* FALSE. */
906 : : }
907 : :
908 : : static int
909 : 0 : pipeline_selector_group_member_read(const char *string,
910 : : uint32_t *group_id,
911 : : uint32_t *member_id,
912 : : uint32_t *weight,
913 : : int *is_blank_or_comment)
914 : : {
915 : : char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
916 : : char *s0 = NULL, *s;
917 : 0 : uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
918 : : int blank_or_comment = 0;
919 : :
920 : : /* Check input arguments. */
921 [ # # # # ]: 0 : if (!string || !string[0])
922 : 0 : goto error;
923 : :
924 : : /* Memory allocation. */
925 : 0 : s0 = strdup(string);
926 [ # # ]: 0 : if (!s0)
927 : 0 : goto error;
928 : :
929 : : /* Parse the string into tokens. */
930 : 0 : for (s = s0; ; ) {
931 : : char *token;
932 : :
933 : 0 : token = strtok_r(s, " \f\n\r\t\v", &s);
934 [ # # ]: 0 : if (!token || token_is_comment(token))
935 : : break;
936 : :
937 [ # # ]: 0 : if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
938 : 0 : goto error;
939 : :
940 : 0 : token_array[n_tokens] = token;
941 : 0 : n_tokens++;
942 : : }
943 : :
944 [ # # ]: 0 : if (!n_tokens) {
945 : : blank_or_comment = 1;
946 : 0 : goto error;
947 : : }
948 : :
949 : : tokens = token_array;
950 : :
951 [ # # ]: 0 : if (n_tokens < 4 ||
952 [ # # ]: 0 : strcmp(tokens[0], "group") ||
953 [ # # ]: 0 : strcmp(tokens[2], "member"))
954 : 0 : goto error;
955 : :
956 : : /*
957 : : * Group ID.
958 : : */
959 [ # # ]: 0 : if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
960 : 0 : goto error;
961 : 0 : *group_id = group_id_val;
962 : :
963 : : /*
964 : : * Member ID.
965 : : */
966 [ # # ]: 0 : if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
967 : 0 : goto error;
968 : 0 : *member_id = member_id_val;
969 : :
970 : : tokens += 4;
971 : 0 : n_tokens -= 4;
972 : :
973 : : /*
974 : : * Weight.
975 : : */
976 [ # # # # ]: 0 : if (n_tokens && !strcmp(tokens[0], "weight")) {
977 [ # # ]: 0 : if (n_tokens < 2)
978 : 0 : goto error;
979 : :
980 [ # # ]: 0 : if (parser_read_uint32(&weight_val, tokens[1]) != 0)
981 : 0 : goto error;
982 : 0 : *weight = weight_val;
983 : :
984 : : tokens += 2;
985 : : n_tokens -= 2;
986 : : }
987 : :
988 [ # # ]: 0 : if (n_tokens)
989 : 0 : goto error;
990 : :
991 : 0 : free(s0);
992 : 0 : return 0;
993 : :
994 : 0 : error:
995 : 0 : free(s0);
996 [ # # ]: 0 : if (is_blank_or_comment)
997 : 0 : *is_blank_or_comment = blank_or_comment;
998 : : return -EINVAL;
999 : : }
1000 : :
1001 : : static int
1002 : 0 : pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1003 : : const char *selector_name,
1004 : : FILE *file,
1005 : : uint32_t *file_line_number)
1006 : : {
1007 : : char *line = NULL;
1008 : : uint32_t line_id = 0;
1009 : : int status = 0;
1010 : :
1011 : : /* Buffer allocation. */
1012 : 0 : line = malloc(MAX_LINE_SIZE);
1013 [ # # ]: 0 : if (!line)
1014 : : return -ENOMEM;
1015 : :
1016 : : /* File read. */
1017 : 0 : for (line_id = 1; ; line_id++) {
1018 : : uint32_t group_id, member_id, weight;
1019 : : int is_blank_or_comment;
1020 : :
1021 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1022 : : break;
1023 : :
1024 : 0 : status = pipeline_selector_group_member_read(line,
1025 : : &group_id,
1026 : : &member_id,
1027 : : &weight,
1028 : : &is_blank_or_comment);
1029 [ # # ]: 0 : if (status) {
1030 [ # # ]: 0 : if (is_blank_or_comment)
1031 : 0 : continue;
1032 : :
1033 : 0 : goto error;
1034 : : }
1035 : :
1036 : 0 : status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1037 : : selector_name,
1038 : : group_id,
1039 : : member_id,
1040 : : weight);
1041 [ # # ]: 0 : if (status)
1042 : 0 : goto error;
1043 : : }
1044 : :
1045 : 0 : error:
1046 : 0 : free(line);
1047 : 0 : *file_line_number = line_id;
1048 : 0 : return status;
1049 : : }
1050 : :
1051 : : /**
1052 : : * pipeline <pipeline_name> selector <selector_name> group member add <file_name>
1053 : : */
1054 : : static void
1055 : 0 : cmd_softnic_pipeline_selector_group_member_add(struct pmd_internals *softnic,
1056 : : char **tokens,
1057 : : uint32_t n_tokens,
1058 : : char *out,
1059 : : size_t out_size)
1060 : : {
1061 : : struct pipeline *p;
1062 : : char *pipeline_name, *selector_name, *file_name;
1063 : : FILE *file = NULL;
1064 : 0 : uint32_t file_line_number = 0;
1065 : : int status;
1066 : :
1067 [ # # ]: 0 : if (n_tokens != 8) {
1068 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1069 : 0 : return;
1070 : : }
1071 : :
1072 : 0 : pipeline_name = tokens[1];
1073 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1074 [ # # ]: 0 : if (!p) {
1075 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1076 : 0 : return;
1077 : : }
1078 : :
1079 [ # # ]: 0 : if (strcmp(tokens[2], "selector") != 0) {
1080 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1081 : 0 : return;
1082 : : }
1083 : :
1084 : 0 : selector_name = tokens[3];
1085 : :
1086 [ # # ]: 0 : if (strcmp(tokens[4], "group") ||
1087 [ # # ]: 0 : strcmp(tokens[5], "member") ||
1088 [ # # ]: 0 : strcmp(tokens[6], "add")) {
1089 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1090 : 0 : return;
1091 : : }
1092 : :
1093 : 0 : file_name = tokens[7];
1094 : 0 : file = fopen(file_name, "r");
1095 [ # # ]: 0 : if (!file) {
1096 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1097 : 0 : return;
1098 : : }
1099 : :
1100 : 0 : status = pipeline_selector_group_members_add(p->ctl,
1101 : : selector_name,
1102 : : file,
1103 : : &file_line_number);
1104 [ # # ]: 0 : if (status)
1105 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1106 : : file_name,
1107 : : file_line_number);
1108 : :
1109 : 0 : fclose(file);
1110 : : }
1111 : :
1112 : : static int
1113 : 0 : pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1114 : : const char *selector_name,
1115 : : FILE *file,
1116 : : uint32_t *file_line_number)
1117 : : {
1118 : : char *line = NULL;
1119 : : uint32_t line_id = 0;
1120 : : int status = 0;
1121 : :
1122 : : /* Buffer allocation. */
1123 : 0 : line = malloc(MAX_LINE_SIZE);
1124 [ # # ]: 0 : if (!line)
1125 : : return -ENOMEM;
1126 : :
1127 : : /* File read. */
1128 : 0 : for (line_id = 1; ; line_id++) {
1129 : : uint32_t group_id, member_id, weight;
1130 : : int is_blank_or_comment;
1131 : :
1132 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1133 : : break;
1134 : :
1135 : 0 : status = pipeline_selector_group_member_read(line,
1136 : : &group_id,
1137 : : &member_id,
1138 : : &weight,
1139 : : &is_blank_or_comment);
1140 [ # # ]: 0 : if (status) {
1141 [ # # ]: 0 : if (is_blank_or_comment)
1142 : 0 : continue;
1143 : :
1144 : 0 : goto error;
1145 : : }
1146 : :
1147 : 0 : status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1148 : : selector_name,
1149 : : group_id,
1150 : : member_id);
1151 [ # # ]: 0 : if (status)
1152 : 0 : goto error;
1153 : : }
1154 : :
1155 : 0 : error:
1156 : 0 : free(line);
1157 : 0 : *file_line_number = line_id;
1158 : 0 : return status;
1159 : : }
1160 : :
1161 : : /**
1162 : : * pipeline <pipeline_name> selector <selector_name> group member delete <file_name>
1163 : : */
1164 : : static void
1165 : 0 : cmd_softnic_pipeline_selector_group_member_delete(struct pmd_internals *softnic,
1166 : : char **tokens,
1167 : : uint32_t n_tokens,
1168 : : char *out,
1169 : : size_t out_size)
1170 : : {
1171 : : struct pipeline *p;
1172 : : char *pipeline_name, *selector_name, *file_name;
1173 : : FILE *file = NULL;
1174 : 0 : uint32_t file_line_number = 0;
1175 : : int status;
1176 : :
1177 [ # # ]: 0 : if (n_tokens != 8) {
1178 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1179 : 0 : return;
1180 : : }
1181 : :
1182 : 0 : pipeline_name = tokens[1];
1183 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1184 [ # # ]: 0 : if (!p) {
1185 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1186 : 0 : return;
1187 : : }
1188 : :
1189 [ # # ]: 0 : if (strcmp(tokens[2], "selector") != 0) {
1190 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1191 : 0 : return;
1192 : : }
1193 : :
1194 : 0 : selector_name = tokens[3];
1195 : :
1196 [ # # ]: 0 : if (strcmp(tokens[4], "group") ||
1197 [ # # ]: 0 : strcmp(tokens[5], "member") ||
1198 [ # # ]: 0 : strcmp(tokens[6], "delete")) {
1199 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1200 : 0 : return;
1201 : : }
1202 : :
1203 : 0 : file_name = tokens[7];
1204 : 0 : file = fopen(file_name, "r");
1205 [ # # ]: 0 : if (!file) {
1206 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1207 : 0 : return;
1208 : : }
1209 : :
1210 : 0 : status = pipeline_selector_group_members_delete(p->ctl,
1211 : : selector_name,
1212 : : file,
1213 : : &file_line_number);
1214 [ # # ]: 0 : if (status)
1215 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1216 : : file_name,
1217 : : file_line_number);
1218 : :
1219 : 0 : fclose(file);
1220 : : }
1221 : :
1222 : : /**
1223 : : * pipeline <pipeline_name> selector <selector_name> show [filename]
1224 : : */
1225 : : static void
1226 : 0 : cmd_softnic_pipeline_selector_show(struct pmd_internals *softnic,
1227 : : char **tokens,
1228 : : uint32_t n_tokens,
1229 : : char *out,
1230 : : size_t out_size)
1231 : : {
1232 : : struct pipeline *p;
1233 : : char *pipeline_name, *selector_name;
1234 : : FILE *file = NULL;
1235 : : int status;
1236 : :
1237 [ # # ]: 0 : if (n_tokens != 5 && n_tokens != 6) {
1238 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1239 : 0 : return;
1240 : : }
1241 : :
1242 : 0 : pipeline_name = tokens[1];
1243 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1244 [ # # ]: 0 : if (!p) {
1245 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1246 : 0 : return;
1247 : : }
1248 : :
1249 : 0 : selector_name = tokens[3];
1250 : :
1251 [ # # ]: 0 : file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1252 [ # # ]: 0 : if (!file) {
1253 : 0 : snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1254 : 0 : return;
1255 : : }
1256 : :
1257 : 0 : status = rte_swx_ctl_pipeline_selector_fprintf(file, p->ctl, selector_name);
1258 [ # # ]: 0 : if (status)
1259 : : snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1260 : :
1261 : : if (file)
1262 : 0 : fclose(file);
1263 : : }
1264 : :
1265 : : static int
1266 : 0 : pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
1267 : : const char *learner_name,
1268 : : FILE *file,
1269 : : uint32_t *file_line_number)
1270 : : {
1271 : : char *line = NULL;
1272 : : uint32_t line_id = 0;
1273 : : int status = 0;
1274 : :
1275 : : /* Buffer allocation. */
1276 : 0 : line = malloc(MAX_LINE_SIZE);
1277 [ # # ]: 0 : if (!line)
1278 : : return -ENOMEM;
1279 : :
1280 : : /* File read. */
1281 : 0 : for (line_id = 1; ; line_id++) {
1282 : : struct rte_swx_table_entry *entry;
1283 : : int is_blank_or_comment;
1284 : :
1285 [ # # ]: 0 : if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1286 : : break;
1287 : :
1288 : 0 : entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
1289 : : learner_name,
1290 : : line,
1291 : : &is_blank_or_comment);
1292 [ # # ]: 0 : if (!entry) {
1293 [ # # ]: 0 : if (is_blank_or_comment)
1294 : 0 : continue;
1295 : :
1296 : : status = -EINVAL;
1297 : 0 : goto error;
1298 : : }
1299 : :
1300 : 0 : status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
1301 : : learner_name,
1302 : : entry);
1303 : 0 : table_entry_free(entry);
1304 [ # # ]: 0 : if (status)
1305 : 0 : goto error;
1306 : : }
1307 : :
1308 : 0 : error:
1309 : 0 : *file_line_number = line_id;
1310 : 0 : free(line);
1311 : 0 : return status;
1312 : : }
1313 : :
1314 : : /**
1315 : : * pipeline <pipeline_name> learner <learner_name> default <file_name>
1316 : : */
1317 : : static void
1318 : 0 : cmd_softnic_pipeline_learner_default(struct pmd_internals *softnic,
1319 : : char **tokens,
1320 : : uint32_t n_tokens,
1321 : : char *out,
1322 : : size_t out_size)
1323 : : {
1324 : : struct pipeline *p;
1325 : : char *pipeline_name, *learner_name, *file_name;
1326 : : FILE *file = NULL;
1327 : 0 : uint32_t file_line_number = 0;
1328 : : int status;
1329 : :
1330 [ # # ]: 0 : if (n_tokens != 6) {
1331 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1332 : 0 : return;
1333 : : }
1334 : :
1335 : 0 : pipeline_name = tokens[1];
1336 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1337 [ # # ]: 0 : if (!p) {
1338 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1339 : 0 : return;
1340 : : }
1341 : :
1342 : 0 : learner_name = tokens[3];
1343 : :
1344 : 0 : file_name = tokens[5];
1345 : 0 : file = fopen(file_name, "r");
1346 [ # # ]: 0 : if (!file) {
1347 : : snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1348 : 0 : return;
1349 : : }
1350 : :
1351 : 0 : status = pipeline_learner_default_entry_add(p->ctl,
1352 : : learner_name,
1353 : : file,
1354 : : &file_line_number);
1355 [ # # ]: 0 : if (status)
1356 : 0 : snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1357 : : file_name,
1358 : : file_line_number);
1359 : :
1360 : 0 : fclose(file);
1361 : : }
1362 : :
1363 : : /**
1364 : : * pipeline <pipeline_name> commit
1365 : : */
1366 : : static void
1367 : 0 : cmd_softnic_pipeline_commit(struct pmd_internals *softnic,
1368 : : char **tokens,
1369 : : uint32_t n_tokens,
1370 : : char *out,
1371 : : size_t out_size)
1372 : : {
1373 : : struct pipeline *p;
1374 : : char *pipeline_name;
1375 : : int status;
1376 : :
1377 [ # # ]: 0 : if (n_tokens != 3) {
1378 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1379 : 0 : return;
1380 : : }
1381 : :
1382 : 0 : pipeline_name = tokens[1];
1383 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1384 [ # # ]: 0 : if (!p) {
1385 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1386 : 0 : return;
1387 : : }
1388 : :
1389 : 0 : status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1390 [ # # ]: 0 : if (status)
1391 : : snprintf(out, out_size, "Commit failed. "
1392 : : "Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1393 : : }
1394 : :
1395 : : /**
1396 : : * pipeline <pipeline_name> abort
1397 : : */
1398 : : static void
1399 : 0 : cmd_softnic_pipeline_abort(struct pmd_internals *softnic,
1400 : : char **tokens,
1401 : : uint32_t n_tokens,
1402 : : char *out,
1403 : : size_t out_size)
1404 : : {
1405 : : struct pipeline *p;
1406 : : char *pipeline_name;
1407 : :
1408 [ # # ]: 0 : if (n_tokens != 3) {
1409 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1410 : 0 : return;
1411 : : }
1412 : :
1413 : 0 : pipeline_name = tokens[1];
1414 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1415 [ # # ]: 0 : if (!p) {
1416 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1417 : 0 : return;
1418 : : }
1419 : :
1420 : 0 : rte_swx_ctl_pipeline_abort(p->ctl);
1421 : : }
1422 : :
1423 : : /**
1424 : : * pipeline <pipeline_name> regrd <register_array_name> <index>
1425 : : */
1426 : : static void
1427 : 0 : cmd_softnic_pipeline_regrd(struct pmd_internals *softnic,
1428 : : char **tokens,
1429 : : uint32_t n_tokens,
1430 : : char *out,
1431 : : size_t out_size)
1432 : : {
1433 : : struct pipeline *p;
1434 : : const char *pipeline_name, *name;
1435 : : uint64_t value;
1436 : : uint32_t idx;
1437 : : int status;
1438 : :
1439 [ # # ]: 0 : if (n_tokens != 5) {
1440 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1441 : 0 : return;
1442 : : }
1443 : :
1444 : 0 : pipeline_name = tokens[1];
1445 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1446 [ # # ]: 0 : if (!p) {
1447 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1448 : 0 : return;
1449 : : }
1450 : :
1451 [ # # ]: 0 : if (strcmp(tokens[2], "regrd")) {
1452 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
1453 : 0 : return;
1454 : : }
1455 : :
1456 : 0 : name = tokens[3];
1457 : :
1458 [ # # ]: 0 : if (parser_read_uint32(&idx, tokens[4])) {
1459 : : snprintf(out, out_size, MSG_ARG_INVALID, "index");
1460 : 0 : return;
1461 : : }
1462 : :
1463 : 0 : status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
1464 [ # # ]: 0 : if (status) {
1465 : : snprintf(out, out_size, "Command failed.\n");
1466 : 0 : return;
1467 : : }
1468 : :
1469 : 0 : snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1470 : : }
1471 : :
1472 : : /**
1473 : : * pipeline <pipeline_name> regwr <register_array_name> <index> <value>
1474 : : */
1475 : : static void
1476 : 0 : cmd_softnic_pipeline_regwr(struct pmd_internals *softnic,
1477 : : char **tokens,
1478 : : uint32_t n_tokens,
1479 : : char *out,
1480 : : size_t out_size)
1481 : : {
1482 : : struct pipeline *p;
1483 : : const char *pipeline_name, *name;
1484 : : uint64_t value;
1485 : : uint32_t idx;
1486 : : int status;
1487 : :
1488 [ # # ]: 0 : if (n_tokens != 6) {
1489 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1490 : 0 : return;
1491 : : }
1492 : :
1493 : 0 : pipeline_name = tokens[1];
1494 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
1495 [ # # ]: 0 : if (!p) {
1496 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1497 : 0 : return;
1498 : : }
1499 : :
1500 [ # # ]: 0 : if (strcmp(tokens[2], "regwr")) {
1501 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
1502 : 0 : return;
1503 : : }
1504 : :
1505 : 0 : name = tokens[3];
1506 : :
1507 [ # # ]: 0 : if (parser_read_uint32(&idx, tokens[4])) {
1508 : : snprintf(out, out_size, MSG_ARG_INVALID, "index");
1509 : 0 : return;
1510 : : }
1511 : :
1512 [ # # ]: 0 : if (parser_read_uint64(&value, tokens[5])) {
1513 : : snprintf(out, out_size, MSG_ARG_INVALID, "value");
1514 : 0 : return;
1515 : : }
1516 : :
1517 : 0 : status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
1518 [ # # ]: 0 : if (status) {
1519 : : snprintf(out, out_size, "Command failed.\n");
1520 : 0 : return;
1521 : : }
1522 : : }
1523 : :
1524 : : /**
1525 : : * pipeline <pipeline_name> meter profile <profile_name> add cir <cir> pir <pir> cbs <cbs> pbs <pbs>
1526 : : */
1527 : : static void
1528 : 0 : cmd_softnic_pipeline_meter_profile_add(struct pmd_internals *softnic,
1529 : : char **tokens,
1530 : : uint32_t n_tokens,
1531 : : char *out,
1532 : : size_t out_size)
1533 : : {
1534 : : struct rte_meter_trtcm_params params;
1535 : : struct pipeline *p;
1536 : : const char *profile_name;
1537 : : int status;
1538 : :
1539 [ # # ]: 0 : if (n_tokens != 14) {
1540 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1541 : 0 : return;
1542 : : }
1543 : :
1544 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1545 [ # # ]: 0 : if (!p) {
1546 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1547 : 0 : return;
1548 : : }
1549 : :
1550 [ # # ]: 0 : if (strcmp(tokens[2], "meter")) {
1551 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1552 : 0 : return;
1553 : : }
1554 : :
1555 [ # # ]: 0 : if (strcmp(tokens[3], "profile")) {
1556 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1557 : 0 : return;
1558 : : }
1559 : :
1560 : 0 : profile_name = tokens[4];
1561 : :
1562 [ # # ]: 0 : if (strcmp(tokens[5], "add")) {
1563 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
1564 : 0 : return;
1565 : : }
1566 : :
1567 [ # # ]: 0 : if (strcmp(tokens[6], "cir")) {
1568 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
1569 : 0 : return;
1570 : : }
1571 : :
1572 [ # # ]: 0 : if (parser_read_uint64(¶ms.cir, tokens[7])) {
1573 : : snprintf(out, out_size, MSG_ARG_INVALID, "cir");
1574 : 0 : return;
1575 : : }
1576 : :
1577 [ # # ]: 0 : if (strcmp(tokens[8], "pir")) {
1578 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
1579 : 0 : return;
1580 : : }
1581 : :
1582 [ # # ]: 0 : if (parser_read_uint64(¶ms.pir, tokens[9])) {
1583 : : snprintf(out, out_size, MSG_ARG_INVALID, "pir");
1584 : 0 : return;
1585 : : }
1586 : :
1587 [ # # ]: 0 : if (strcmp(tokens[10], "cbs")) {
1588 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
1589 : 0 : return;
1590 : : }
1591 : :
1592 [ # # ]: 0 : if (parser_read_uint64(¶ms.cbs, tokens[11])) {
1593 : : snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
1594 : 0 : return;
1595 : : }
1596 : :
1597 [ # # ]: 0 : if (strcmp(tokens[12], "pbs")) {
1598 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
1599 : 0 : return;
1600 : : }
1601 : :
1602 [ # # ]: 0 : if (parser_read_uint64(¶ms.pbs, tokens[13])) {
1603 : : snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
1604 : 0 : return;
1605 : : }
1606 : :
1607 : 0 : status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
1608 [ # # ]: 0 : if (status) {
1609 : : snprintf(out, out_size, "Command failed.\n");
1610 : 0 : return;
1611 : : }
1612 : : }
1613 : :
1614 : : /**
1615 : : * pipeline <pipeline_name> meter profile <profile_name> delete
1616 : : */
1617 : : static void
1618 : 0 : cmd_softnic_pipeline_meter_profile_delete(struct pmd_internals *softnic,
1619 : : char **tokens,
1620 : : uint32_t n_tokens,
1621 : : char *out,
1622 : : size_t out_size)
1623 : : {
1624 : : struct pipeline *p;
1625 : : const char *profile_name;
1626 : : int status;
1627 : :
1628 [ # # ]: 0 : if (n_tokens != 6) {
1629 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1630 : 0 : return;
1631 : : }
1632 : :
1633 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1634 [ # # ]: 0 : if (!p) {
1635 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1636 : 0 : return;
1637 : : }
1638 : :
1639 [ # # ]: 0 : if (strcmp(tokens[2], "meter")) {
1640 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1641 : 0 : return;
1642 : : }
1643 : :
1644 [ # # ]: 0 : if (strcmp(tokens[3], "profile")) {
1645 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1646 : 0 : return;
1647 : : }
1648 : :
1649 : 0 : profile_name = tokens[4];
1650 : :
1651 [ # # ]: 0 : if (strcmp(tokens[5], "delete")) {
1652 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
1653 : 0 : return;
1654 : : }
1655 : :
1656 : 0 : status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
1657 [ # # ]: 0 : if (status) {
1658 : : snprintf(out, out_size, "Command failed.\n");
1659 : 0 : return;
1660 : : }
1661 : : }
1662 : :
1663 : : /**
1664 : : * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> reset
1665 : : */
1666 : : static void
1667 : 0 : cmd_softnic_pipeline_meter_reset(struct pmd_internals *softnic,
1668 : : char **tokens,
1669 : : uint32_t n_tokens,
1670 : : char *out,
1671 : : size_t out_size)
1672 : : {
1673 : : struct pipeline *p;
1674 : : const char *name;
1675 : 0 : uint32_t idx0 = 0, idx1 = 0;
1676 : :
1677 [ # # ]: 0 : if (n_tokens != 9) {
1678 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1679 : 0 : return;
1680 : : }
1681 : :
1682 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1683 [ # # ]: 0 : if (!p) {
1684 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1685 : 0 : return;
1686 : : }
1687 : :
1688 [ # # ]: 0 : if (strcmp(tokens[2], "meter")) {
1689 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1690 : 0 : return;
1691 : : }
1692 : :
1693 : 0 : name = tokens[3];
1694 : :
1695 [ # # ]: 0 : if (strcmp(tokens[4], "from")) {
1696 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
1697 : 0 : return;
1698 : : }
1699 : :
1700 [ # # ]: 0 : if (parser_read_uint32(&idx0, tokens[5])) {
1701 : : snprintf(out, out_size, MSG_ARG_INVALID, "index0");
1702 : 0 : return;
1703 : : }
1704 : :
1705 [ # # ]: 0 : if (strcmp(tokens[6], "to")) {
1706 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
1707 : 0 : return;
1708 : : }
1709 : :
1710 [ # # # # ]: 0 : if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
1711 : : snprintf(out, out_size, MSG_ARG_INVALID, "index1");
1712 : 0 : return;
1713 : : }
1714 : :
1715 [ # # ]: 0 : if (strcmp(tokens[8], "reset")) {
1716 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
1717 : 0 : return;
1718 : : }
1719 : :
1720 [ # # ]: 0 : for ( ; idx0 <= idx1; idx0++) {
1721 : : int status;
1722 : :
1723 : 0 : status = rte_swx_ctl_meter_reset(p->p, name, idx0);
1724 [ # # ]: 0 : if (status) {
1725 : : snprintf(out, out_size, "Command failed for index %u.\n", idx0);
1726 : 0 : return;
1727 : : }
1728 : : }
1729 : : }
1730 : :
1731 : : /**
1732 : : * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> set
1733 : : * profile <profile_name>
1734 : : */
1735 : : static void
1736 : 0 : cmd_softnic_pipeline_meter_set(struct pmd_internals *softnic,
1737 : : char **tokens,
1738 : : uint32_t n_tokens,
1739 : : char *out,
1740 : : size_t out_size)
1741 : : {
1742 : : struct pipeline *p;
1743 : : const char *name, *profile_name;
1744 : 0 : uint32_t idx0 = 0, idx1 = 0;
1745 : :
1746 [ # # ]: 0 : if (n_tokens != 11) {
1747 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1748 : 0 : return;
1749 : : }
1750 : :
1751 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1752 [ # # ]: 0 : if (!p) {
1753 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1754 : 0 : return;
1755 : : }
1756 : :
1757 [ # # ]: 0 : if (strcmp(tokens[2], "meter")) {
1758 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1759 : 0 : return;
1760 : : }
1761 : :
1762 : 0 : name = tokens[3];
1763 : :
1764 [ # # ]: 0 : if (strcmp(tokens[4], "from")) {
1765 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
1766 : 0 : return;
1767 : : }
1768 : :
1769 [ # # ]: 0 : if (parser_read_uint32(&idx0, tokens[5])) {
1770 : : snprintf(out, out_size, MSG_ARG_INVALID, "index0");
1771 : 0 : return;
1772 : : }
1773 : :
1774 [ # # ]: 0 : if (strcmp(tokens[6], "to")) {
1775 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
1776 : 0 : return;
1777 : : }
1778 : :
1779 [ # # # # ]: 0 : if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
1780 : : snprintf(out, out_size, MSG_ARG_INVALID, "index1");
1781 : 0 : return;
1782 : : }
1783 : :
1784 [ # # ]: 0 : if (strcmp(tokens[8], "set")) {
1785 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
1786 : 0 : return;
1787 : : }
1788 : :
1789 [ # # ]: 0 : if (strcmp(tokens[9], "profile")) {
1790 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1791 : 0 : return;
1792 : : }
1793 : :
1794 : 0 : profile_name = tokens[10];
1795 : :
1796 [ # # ]: 0 : for ( ; idx0 <= idx1; idx0++) {
1797 : : int status;
1798 : :
1799 : 0 : status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
1800 [ # # ]: 0 : if (status) {
1801 : : snprintf(out, out_size, "Command failed for index %u.\n", idx0);
1802 : 0 : return;
1803 : : }
1804 : : }
1805 : : }
1806 : :
1807 : : /**
1808 : : * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> stats
1809 : : */
1810 : : static void
1811 : 0 : cmd_softnic_pipeline_meter_stats(struct pmd_internals *softnic,
1812 : : char **tokens,
1813 : : uint32_t n_tokens,
1814 : : char *out,
1815 : : size_t out_size)
1816 : : {
1817 : : struct rte_swx_ctl_meter_stats stats;
1818 : : struct pipeline *p;
1819 : : const char *name;
1820 : 0 : uint32_t idx0 = 0, idx1 = 0;
1821 : :
1822 [ # # ]: 0 : if (n_tokens != 9) {
1823 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1824 : 0 : return;
1825 : : }
1826 : :
1827 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1828 [ # # ]: 0 : if (!p) {
1829 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1830 : 0 : return;
1831 : : }
1832 : :
1833 [ # # ]: 0 : if (strcmp(tokens[2], "meter")) {
1834 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1835 : 0 : return;
1836 : : }
1837 : :
1838 : 0 : name = tokens[3];
1839 : :
1840 [ # # ]: 0 : if (strcmp(tokens[4], "from")) {
1841 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
1842 : 0 : return;
1843 : : }
1844 : :
1845 [ # # ]: 0 : if (parser_read_uint32(&idx0, tokens[5])) {
1846 : : snprintf(out, out_size, MSG_ARG_INVALID, "index0");
1847 : 0 : return;
1848 : : }
1849 : :
1850 [ # # ]: 0 : if (strcmp(tokens[6], "to")) {
1851 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
1852 : 0 : return;
1853 : : }
1854 : :
1855 [ # # # # ]: 0 : if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
1856 : : snprintf(out, out_size, MSG_ARG_INVALID, "index1");
1857 : 0 : return;
1858 : : }
1859 : :
1860 [ # # ]: 0 : if (strcmp(tokens[8], "stats")) {
1861 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1862 : 0 : return;
1863 : : }
1864 : :
1865 : : /* Table header. */
1866 : : snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
1867 : : "-------",
1868 : : "----------------", "----------------", "----------------",
1869 : : "----------------", "----------------", "----------------");
1870 : 0 : out_size -= strlen(out);
1871 : 0 : out += strlen(out);
1872 : :
1873 : : snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
1874 : : "METER #",
1875 : : "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
1876 : : "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
1877 : 0 : out_size -= strlen(out);
1878 : 0 : out += strlen(out);
1879 : :
1880 : : snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
1881 : : "-------",
1882 : : "----------------", "----------------", "----------------",
1883 : : "----------------", "----------------", "----------------");
1884 : 0 : out_size -= strlen(out);
1885 : 0 : out += strlen(out);
1886 : :
1887 : : /* Table rows. */
1888 [ # # ]: 0 : for ( ; idx0 <= idx1; idx0++) {
1889 : : int status;
1890 : :
1891 : 0 : status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
1892 [ # # ]: 0 : if (status) {
1893 : : snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
1894 : : out_size -= strlen(out);
1895 : : out += strlen(out);
1896 : 0 : return;
1897 : : }
1898 : :
1899 : 0 : snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
1900 : : " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
1901 : : idx0,
1902 : : stats.n_pkts[RTE_COLOR_GREEN],
1903 : : stats.n_pkts[RTE_COLOR_YELLOW],
1904 : : stats.n_pkts[RTE_COLOR_RED],
1905 : : stats.n_bytes[RTE_COLOR_GREEN],
1906 : : stats.n_bytes[RTE_COLOR_YELLOW],
1907 : : stats.n_bytes[RTE_COLOR_RED]);
1908 : 0 : out_size -= strlen(out);
1909 : 0 : out += strlen(out);
1910 : : }
1911 : : }
1912 : :
1913 : : /**
1914 : : * pipeline <pipeline_name> stats
1915 : : */
1916 : : static void
1917 : 0 : cmd_softnic_pipeline_stats(struct pmd_internals *softnic,
1918 : : char **tokens,
1919 : : uint32_t n_tokens,
1920 : : char *out,
1921 : : size_t out_size)
1922 : : {
1923 : : struct rte_swx_ctl_pipeline_info info;
1924 : : struct pipeline *p;
1925 : : uint32_t i;
1926 : : int status;
1927 : :
1928 [ # # ]: 0 : if (n_tokens != 3) {
1929 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1930 : 0 : return;
1931 : : }
1932 : :
1933 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
1934 [ # # ]: 0 : if (!p) {
1935 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1936 : 0 : return;
1937 : : }
1938 : :
1939 [ # # ]: 0 : if (strcmp(tokens[2], "stats")) {
1940 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1941 : 0 : return;
1942 : : }
1943 : :
1944 : 0 : status = rte_swx_ctl_pipeline_info_get(p->p, &info);
1945 [ # # ]: 0 : if (status) {
1946 : : snprintf(out, out_size, "Pipeline info get error.");
1947 : 0 : return;
1948 : : }
1949 : :
1950 : : snprintf(out, out_size, "Input ports:\n");
1951 : 0 : out_size -= strlen(out);
1952 : 0 : out += strlen(out);
1953 : :
1954 [ # # ]: 0 : for (i = 0; i < info.n_ports_in; i++) {
1955 : : struct rte_swx_port_in_stats stats;
1956 : :
1957 : 0 : rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
1958 : :
1959 : 0 : snprintf(out, out_size, "\tPort %u:"
1960 : : " packets %" PRIu64
1961 : : " bytes %" PRIu64
1962 : : " empty %" PRIu64 "\n",
1963 : : i, stats.n_pkts, stats.n_bytes, stats.n_empty);
1964 : 0 : out_size -= strlen(out);
1965 : 0 : out += strlen(out);
1966 : : }
1967 : :
1968 : : snprintf(out, out_size, "\nOutput ports:\n");
1969 : 0 : out_size -= strlen(out);
1970 : 0 : out += strlen(out);
1971 : :
1972 [ # # ]: 0 : for (i = 0; i < info.n_ports_out; i++) {
1973 : : struct rte_swx_port_out_stats stats;
1974 : :
1975 : 0 : rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
1976 : :
1977 [ # # ]: 0 : if (i != info.n_ports_out - 1)
1978 : : snprintf(out, out_size, "\tPort %u:", i);
1979 : : else
1980 : : snprintf(out, out_size, "\tDROP:");
1981 : :
1982 : 0 : out_size -= strlen(out);
1983 : 0 : out += strlen(out);
1984 : :
1985 : 0 : snprintf(out,
1986 : : out_size,
1987 : : " packets %" PRIu64
1988 : : " bytes %" PRIu64
1989 : : " packets dropped %" PRIu64
1990 : : " bytes dropped %" PRIu64
1991 : : " clone %" PRIu64
1992 : : " clonerr %" PRIu64 "\n",
1993 : : stats.n_pkts,
1994 : : stats.n_bytes,
1995 : : stats.n_pkts_drop,
1996 : : stats.n_bytes_drop,
1997 : : stats.n_pkts_clone,
1998 : : stats.n_pkts_clone_err);
1999 : :
2000 : 0 : out_size -= strlen(out);
2001 : 0 : out += strlen(out);
2002 : : }
2003 : :
2004 : : snprintf(out, out_size, "\nTables:\n");
2005 : 0 : out_size -= strlen(out);
2006 : 0 : out += strlen(out);
2007 : :
2008 [ # # ]: 0 : for (i = 0; i < info.n_tables; i++) {
2009 : : struct rte_swx_ctl_table_info table_info;
2010 : 0 : uint64_t n_pkts_action[info.n_actions];
2011 : 0 : struct rte_swx_table_stats stats = {
2012 : : .n_pkts_hit = 0,
2013 : : .n_pkts_miss = 0,
2014 : : .n_pkts_action = n_pkts_action,
2015 : : };
2016 : : uint32_t j;
2017 : :
2018 : 0 : status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2019 [ # # ]: 0 : if (status) {
2020 : : snprintf(out, out_size, "Table info get error.");
2021 : 0 : return;
2022 : : }
2023 : :
2024 : 0 : status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2025 [ # # ]: 0 : if (status) {
2026 : : snprintf(out, out_size, "Table stats read error.");
2027 : 0 : return;
2028 : : }
2029 : :
2030 : 0 : snprintf(out, out_size, "\tTable %s:\n"
2031 : : "\t\tHit (packets): %" PRIu64 "\n"
2032 : : "\t\tMiss (packets): %" PRIu64 "\n",
2033 : : table_info.name,
2034 : : stats.n_pkts_hit,
2035 : : stats.n_pkts_miss);
2036 : 0 : out_size -= strlen(out);
2037 : 0 : out += strlen(out);
2038 : :
2039 [ # # ]: 0 : for (j = 0; j < info.n_actions; j++) {
2040 : : struct rte_swx_ctl_action_info action_info;
2041 : :
2042 : 0 : status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2043 [ # # ]: 0 : if (status) {
2044 : : snprintf(out, out_size, "Action info get error.");
2045 : 0 : return;
2046 : : }
2047 : :
2048 : 0 : snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2049 : : action_info.name,
2050 : 0 : stats.n_pkts_action[j]);
2051 : 0 : out_size -= strlen(out);
2052 : 0 : out += strlen(out);
2053 : : }
2054 : : }
2055 : :
2056 : : snprintf(out, out_size, "\nLearner tables:\n");
2057 : 0 : out_size -= strlen(out);
2058 : 0 : out += strlen(out);
2059 : :
2060 [ # # ]: 0 : for (i = 0; i < info.n_learners; i++) {
2061 : : struct rte_swx_ctl_learner_info learner_info;
2062 : 0 : uint64_t n_pkts_action[info.n_actions];
2063 : 0 : struct rte_swx_learner_stats stats = {
2064 : : .n_pkts_hit = 0,
2065 : : .n_pkts_miss = 0,
2066 : : .n_pkts_action = n_pkts_action,
2067 : : };
2068 : : uint32_t j;
2069 : :
2070 : 0 : status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
2071 [ # # ]: 0 : if (status) {
2072 : : snprintf(out, out_size, "Learner table info get error.");
2073 : 0 : return;
2074 : : }
2075 : :
2076 : 0 : status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
2077 [ # # ]: 0 : if (status) {
2078 : : snprintf(out, out_size, "Learner table stats read error.");
2079 : 0 : return;
2080 : : }
2081 : :
2082 : 0 : snprintf(out, out_size, "\tLearner table %s:\n"
2083 : : "\t\tHit (packets): %" PRIu64 "\n"
2084 : : "\t\tMiss (packets): %" PRIu64 "\n"
2085 : : "\t\tLearn OK (packets): %" PRIu64 "\n"
2086 : : "\t\tLearn error (packets): %" PRIu64 "\n"
2087 : : "\t\tRearm (packets): %" PRIu64 "\n"
2088 : : "\t\tForget (packets): %" PRIu64 "\n",
2089 : : learner_info.name,
2090 : : stats.n_pkts_hit,
2091 : : stats.n_pkts_miss,
2092 : : stats.n_pkts_learn_ok,
2093 : : stats.n_pkts_learn_err,
2094 : : stats.n_pkts_rearm,
2095 : : stats.n_pkts_forget);
2096 : 0 : out_size -= strlen(out);
2097 : 0 : out += strlen(out);
2098 : :
2099 [ # # ]: 0 : for (j = 0; j < info.n_actions; j++) {
2100 : : struct rte_swx_ctl_action_info action_info;
2101 : :
2102 : 0 : status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2103 [ # # ]: 0 : if (status) {
2104 : : snprintf(out, out_size, "Action info get error.");
2105 : 0 : return;
2106 : : }
2107 : :
2108 : 0 : snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2109 : : action_info.name,
2110 : 0 : stats.n_pkts_action[j]);
2111 : 0 : out_size -= strlen(out);
2112 : 0 : out += strlen(out);
2113 : : }
2114 : : }
2115 : : }
2116 : :
2117 : : /**
2118 : : * pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow
2119 : : * truncate <truncation_length>
2120 : : */
2121 : : static void
2122 : 0 : cmd_softnic_pipeline_mirror_session(struct pmd_internals *softnic,
2123 : : char **tokens,
2124 : : uint32_t n_tokens,
2125 : : char *out,
2126 : : size_t out_size)
2127 : : {
2128 : : struct rte_swx_pipeline_mirroring_session_params params;
2129 : : struct pipeline *p;
2130 : 0 : uint32_t session_id = 0;
2131 : : int status;
2132 : :
2133 [ # # ]: 0 : if (n_tokens != 11) {
2134 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2135 : 0 : return;
2136 : : }
2137 : :
2138 [ # # ]: 0 : if (strcmp(tokens[0], "pipeline")) {
2139 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2140 : 0 : return;
2141 : : }
2142 : :
2143 : 0 : p = softnic_pipeline_find(softnic, tokens[1]);
2144 [ # # ]: 0 : if (!p) {
2145 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2146 : 0 : return;
2147 : : }
2148 : :
2149 [ # # ]: 0 : if (strcmp(tokens[2], "mirror")) {
2150 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
2151 : 0 : return;
2152 : : }
2153 : :
2154 [ # # ]: 0 : if (strcmp(tokens[3], "session")) {
2155 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
2156 : 0 : return;
2157 : : }
2158 : :
2159 [ # # ]: 0 : if (parser_read_uint32(&session_id, tokens[4])) {
2160 : : snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
2161 : 0 : return;
2162 : : }
2163 : :
2164 [ # # ]: 0 : if (strcmp(tokens[5], "port")) {
2165 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2166 : 0 : return;
2167 : : }
2168 : :
2169 [ # # ]: 0 : if (parser_read_uint32(¶ms.port_id, tokens[6])) {
2170 : : snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2171 : 0 : return;
2172 : : }
2173 : :
2174 [ # # ]: 0 : if (strcmp(tokens[7], "clone")) {
2175 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
2176 : 0 : return;
2177 : : }
2178 : :
2179 [ # # ]: 0 : if (!strcmp(tokens[8], "fast")) {
2180 : 0 : params.fast_clone = 1;
2181 [ # # ]: 0 : } else if (!strcmp(tokens[8], "slow")) {
2182 : 0 : params.fast_clone = 0;
2183 : : } else {
2184 : : snprintf(out, out_size, MSG_ARG_INVALID, "clone");
2185 : 0 : return;
2186 : : }
2187 : :
2188 [ # # ]: 0 : if (strcmp(tokens[9], "truncate")) {
2189 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
2190 : 0 : return;
2191 : : }
2192 : :
2193 [ # # ]: 0 : if (parser_read_uint32(¶ms.truncation_length, tokens[10])) {
2194 : : snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
2195 : 0 : return;
2196 : : }
2197 : :
2198 : 0 : status = rte_swx_ctl_pipeline_mirroring_session_set(p->p, session_id, ¶ms);
2199 [ # # ]: 0 : if (status) {
2200 : : snprintf(out, out_size, "Command failed!\n");
2201 : 0 : return;
2202 : : }
2203 : : }
2204 : :
2205 : : /**
2206 : : * thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]
2207 : : */
2208 : : static void
2209 : 0 : cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
2210 : : char **tokens,
2211 : : uint32_t n_tokens,
2212 : : char *out,
2213 : : size_t out_size)
2214 : : {
2215 : : char *pipeline_name;
2216 : : struct pipeline *p;
2217 : : uint32_t thread_id;
2218 : : int status;
2219 : :
2220 [ # # ]: 0 : if (n_tokens != 5) {
2221 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2222 : 0 : return;
2223 : : }
2224 : :
2225 [ # # ]: 0 : if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2226 : : snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2227 : 0 : return;
2228 : : }
2229 : :
2230 [ # # ]: 0 : if (strcmp(tokens[2], "pipeline") != 0) {
2231 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2232 : 0 : return;
2233 : : }
2234 : :
2235 : 0 : pipeline_name = tokens[3];
2236 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
2237 [ # # ]: 0 : if (!p) {
2238 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2239 : 0 : return;
2240 : : }
2241 : :
2242 [ # # ]: 0 : if (strcmp(tokens[4], "enable") != 0) {
2243 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2244 : 0 : return;
2245 : : }
2246 : :
2247 : 0 : status = softnic_thread_pipeline_enable(softnic, thread_id, p);
2248 [ # # ]: 0 : if (status) {
2249 : : snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
2250 : 0 : return;
2251 : : }
2252 : : }
2253 : :
2254 : : /**
2255 : : * thread <thread_id> pipeline <pipeline_name> disable
2256 : : */
2257 : : static void
2258 : 0 : cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
2259 : : char **tokens,
2260 : : uint32_t n_tokens,
2261 : : char *out,
2262 : : size_t out_size)
2263 : : {
2264 : : char *pipeline_name;
2265 : : struct pipeline *p;
2266 : : uint32_t thread_id;
2267 : : int status;
2268 : :
2269 [ # # ]: 0 : if (n_tokens != 5) {
2270 : 0 : snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2271 : 0 : return;
2272 : : }
2273 : :
2274 [ # # ]: 0 : if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2275 : : snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2276 : 0 : return;
2277 : : }
2278 : :
2279 [ # # ]: 0 : if (strcmp(tokens[2], "pipeline") != 0) {
2280 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2281 : 0 : return;
2282 : : }
2283 : :
2284 : 0 : pipeline_name = tokens[3];
2285 : 0 : p = softnic_pipeline_find(softnic, pipeline_name);
2286 [ # # ]: 0 : if (!p) {
2287 : : snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2288 : 0 : return;
2289 : : }
2290 : :
2291 [ # # ]: 0 : if (strcmp(tokens[4], "disable") != 0) {
2292 : : snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2293 : 0 : return;
2294 : : }
2295 : :
2296 : 0 : status = softnic_thread_pipeline_disable(softnic, thread_id, p);
2297 [ # # ]: 0 : if (status) {
2298 : : snprintf(out, out_size, MSG_CMD_FAIL,
2299 : : "thread pipeline disable");
2300 : 0 : return;
2301 : : }
2302 : : }
2303 : :
2304 : : void
2305 : 0 : softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
2306 : : {
2307 : : char *tokens[CMD_MAX_TOKENS];
2308 : 0 : uint32_t n_tokens = RTE_DIM(tokens);
2309 : : struct pmd_internals *softnic = arg;
2310 : : int status;
2311 : :
2312 [ # # ]: 0 : if (is_comment(in))
2313 : 0 : return;
2314 : :
2315 : 0 : status = parse_tokenize_string(in, tokens, &n_tokens);
2316 [ # # ]: 0 : if (status) {
2317 : : snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
2318 : 0 : return;
2319 : : }
2320 : :
2321 [ # # ]: 0 : if (n_tokens == 0)
2322 : : return;
2323 : :
2324 [ # # ]: 0 : if (strcmp(tokens[0], "mempool") == 0) {
2325 : 0 : cmd_mempool(softnic, tokens, n_tokens, out, out_size);
2326 : 0 : return;
2327 : : }
2328 : :
2329 [ # # ]: 0 : if (strcmp(tokens[0], "swq") == 0) {
2330 : 0 : cmd_swq(softnic, tokens, n_tokens, out, out_size);
2331 : 0 : return;
2332 : : }
2333 : :
2334 [ # # ]: 0 : if (!strcmp(tokens[0], "pipeline")) {
2335 [ # # # # ]: 0 : if (n_tokens >= 2 && !strcmp(tokens[1], "codegen")) {
2336 : 0 : cmd_softnic_pipeline_codegen(softnic, tokens, n_tokens, out, out_size);
2337 : 0 : return;
2338 : : }
2339 : :
2340 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[1], "libbuild")) {
2341 : 0 : cmd_softnic_pipeline_libbuild(softnic, tokens, n_tokens, out, out_size);
2342 : 0 : return;
2343 : : }
2344 : :
2345 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "build")) {
2346 : 0 : cmd_softnic_pipeline_build(softnic, tokens, n_tokens, out, out_size);
2347 : 0 : return;
2348 : : }
2349 : :
2350 [ # # # # : 0 : if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "add")) {
# # ]
2351 : 0 : cmd_softnic_pipeline_table_add(softnic, tokens, n_tokens, out, out_size);
2352 : 0 : return;
2353 : : }
2354 : :
2355 [ # # # # : 0 : if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "delete")) {
# # ]
2356 : 0 : cmd_softnic_pipeline_table_delete(softnic, tokens, n_tokens,
2357 : : out, out_size);
2358 : 0 : return;
2359 : : }
2360 : :
2361 [ # # # # : 0 : if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "default")) {
# # ]
2362 : 0 : cmd_softnic_pipeline_table_default(softnic, tokens, n_tokens,
2363 : : out, out_size);
2364 : 0 : return;
2365 : : }
2366 : :
2367 [ # # # # : 0 : if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "show")) {
# # ]
2368 : 0 : cmd_softnic_pipeline_table_show(softnic, tokens, n_tokens, out, out_size);
2369 : 0 : return;
2370 : : }
2371 : :
2372 [ # # ]: 0 : if (n_tokens >= 6 &&
2373 [ # # ]: 0 : !strcmp(tokens[2], "selector") &&
2374 [ # # ]: 0 : !strcmp(tokens[4], "group") &&
2375 [ # # ]: 0 : !strcmp(tokens[5], "add")) {
2376 : 0 : cmd_softnic_pipeline_selector_group_add(softnic, tokens, n_tokens,
2377 : : out, out_size);
2378 : 0 : return;
2379 : : }
2380 : :
2381 [ # # ]: 0 : if (n_tokens >= 6 &&
2382 [ # # ]: 0 : !strcmp(tokens[2], "selector") &&
2383 [ # # ]: 0 : !strcmp(tokens[4], "group") &&
2384 [ # # ]: 0 : !strcmp(tokens[5], "delete")) {
2385 : 0 : cmd_softnic_pipeline_selector_group_delete(softnic, tokens, n_tokens,
2386 : : out, out_size);
2387 : 0 : return;
2388 : : }
2389 : :
2390 [ # # ]: 0 : if (n_tokens >= 7 &&
2391 [ # # ]: 0 : !strcmp(tokens[2], "selector") &&
2392 [ # # ]: 0 : !strcmp(tokens[4], "group") &&
2393 [ # # ]: 0 : !strcmp(tokens[5], "member") &&
2394 [ # # ]: 0 : !strcmp(tokens[6], "add")) {
2395 : 0 : cmd_softnic_pipeline_selector_group_member_add(softnic, tokens, n_tokens,
2396 : : out, out_size);
2397 : 0 : return;
2398 : : }
2399 : :
2400 [ # # ]: 0 : if (n_tokens >= 7 &&
2401 [ # # ]: 0 : !strcmp(tokens[2], "selector") &&
2402 [ # # ]: 0 : !strcmp(tokens[4], "group") &&
2403 [ # # ]: 0 : !strcmp(tokens[5], "member") &&
2404 [ # # ]: 0 : !strcmp(tokens[6], "delete")) {
2405 : 0 : cmd_softnic_pipeline_selector_group_member_delete(softnic, tokens, n_tokens,
2406 : : out, out_size);
2407 : 0 : return;
2408 : : }
2409 : :
2410 [ # # ]: 0 : if (n_tokens >= 5 &&
2411 [ # # ]: 0 : !strcmp(tokens[2], "selector") &&
2412 [ # # ]: 0 : !strcmp(tokens[4], "show")) {
2413 : 0 : cmd_softnic_pipeline_selector_show(softnic, tokens, n_tokens,
2414 : : out, out_size);
2415 : 0 : return;
2416 : : }
2417 : :
2418 [ # # ]: 0 : if (n_tokens >= 5 &&
2419 [ # # ]: 0 : !strcmp(tokens[2], "learner") &&
2420 [ # # ]: 0 : !strcmp(tokens[4], "default")) {
2421 : 0 : cmd_softnic_pipeline_learner_default(softnic, tokens, n_tokens,
2422 : : out, out_size);
2423 : 0 : return;
2424 : : }
2425 : :
2426 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "commit")) {
2427 : 0 : cmd_softnic_pipeline_commit(softnic, tokens, n_tokens, out, out_size);
2428 : 0 : return;
2429 : : }
2430 : :
2431 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "abort")) {
2432 : 0 : cmd_softnic_pipeline_abort(softnic, tokens, n_tokens, out, out_size);
2433 : 0 : return;
2434 : : }
2435 : :
2436 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "regrd")) {
2437 : 0 : cmd_softnic_pipeline_regrd(softnic, tokens, n_tokens, out, out_size);
2438 : 0 : return;
2439 : : }
2440 : :
2441 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "regwr")) {
2442 : 0 : cmd_softnic_pipeline_regwr(softnic, tokens, n_tokens, out, out_size);
2443 : 0 : return;
2444 : : }
2445 : :
2446 [ # # ]: 0 : if (n_tokens >= 6 &&
2447 [ # # ]: 0 : !strcmp(tokens[2], "meter") &&
2448 [ # # ]: 0 : !strcmp(tokens[3], "profile") &&
2449 [ # # ]: 0 : !strcmp(tokens[5], "add")) {
2450 : 0 : cmd_softnic_pipeline_meter_profile_add(softnic, tokens, n_tokens,
2451 : : out, out_size);
2452 : 0 : return;
2453 : : }
2454 : :
2455 [ # # ]: 0 : if (n_tokens >= 6 &&
2456 [ # # ]: 0 : !strcmp(tokens[2], "meter") &&
2457 [ # # ]: 0 : !strcmp(tokens[3], "profile") &&
2458 [ # # ]: 0 : !strcmp(tokens[5], "delete")) {
2459 : 0 : cmd_softnic_pipeline_meter_profile_delete(softnic, tokens, n_tokens,
2460 : : out, out_size);
2461 : 0 : return;
2462 : : }
2463 : :
2464 [ # # # # : 0 : if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "reset")) {
# # ]
2465 : 0 : cmd_softnic_pipeline_meter_reset(softnic, tokens, n_tokens, out, out_size);
2466 : 0 : return;
2467 : : }
2468 : :
2469 [ # # # # : 0 : if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "set")) {
# # ]
2470 : 0 : cmd_softnic_pipeline_meter_set(softnic, tokens, n_tokens, out, out_size);
2471 : 0 : return;
2472 : : }
2473 : :
2474 [ # # # # : 0 : if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "stats")) {
# # ]
2475 : 0 : cmd_softnic_pipeline_meter_stats(softnic, tokens, n_tokens, out, out_size);
2476 : 0 : return;
2477 : : }
2478 : :
2479 [ # # # # ]: 0 : if (n_tokens >= 3 && !strcmp(tokens[2], "stats")) {
2480 : 0 : cmd_softnic_pipeline_stats(softnic, tokens, n_tokens, out, out_size);
2481 : 0 : return;
2482 : : }
2483 : :
2484 [ # # ]: 0 : if (n_tokens >= 4 &&
2485 [ # # ]: 0 : !strcmp(tokens[2], "mirror") &&
2486 [ # # ]: 0 : !strcmp(tokens[3], "session")) {
2487 : 0 : cmd_softnic_pipeline_mirror_session(softnic, tokens, n_tokens,
2488 : : out, out_size);
2489 : 0 : return;
2490 : : }
2491 : : }
2492 : :
2493 [ # # ]: 0 : if (strcmp(tokens[0], "thread") == 0) {
2494 [ # # ]: 0 : if (n_tokens >= 5 &&
2495 [ # # ]: 0 : (strcmp(tokens[4], "enable") == 0)) {
2496 : 0 : cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
2497 : : out, out_size);
2498 : 0 : return;
2499 : : }
2500 : :
2501 [ # # ]: 0 : if (n_tokens >= 5 &&
2502 [ # # ]: 0 : (strcmp(tokens[4], "disable") == 0)) {
2503 : 0 : cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
2504 : : out, out_size);
2505 : 0 : return;
2506 : : }
2507 : : }
2508 : :
2509 : : snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
2510 : : }
2511 : :
2512 : : int
2513 : 0 : softnic_cli_script_process(struct pmd_internals *softnic,
2514 : : const char *file_name,
2515 : : size_t msg_in_len_max,
2516 : : size_t msg_out_len_max)
2517 : : {
2518 : : char *msg_in = NULL, *msg_out = NULL;
2519 : : FILE *f = NULL;
2520 : :
2521 : : /* Check input arguments */
2522 [ # # ]: 0 : if (file_name == NULL ||
2523 [ # # ]: 0 : (strlen(file_name) == 0) ||
2524 : 0 : msg_in_len_max == 0 ||
2525 [ # # ]: 0 : msg_out_len_max == 0)
2526 : : return -EINVAL;
2527 : :
2528 : 0 : msg_in = malloc(msg_in_len_max + 1);
2529 : 0 : msg_out = malloc(msg_out_len_max + 1);
2530 : 0 : if (msg_in == NULL ||
2531 [ # # ]: 0 : msg_out == NULL) {
2532 : 0 : free(msg_out);
2533 : 0 : free(msg_in);
2534 : 0 : return -ENOMEM;
2535 : : }
2536 : :
2537 : : /* Open input file */
2538 : 0 : f = fopen(file_name, "r");
2539 [ # # ]: 0 : if (f == NULL) {
2540 : 0 : free(msg_out);
2541 : 0 : free(msg_in);
2542 : 0 : return -EIO;
2543 : : }
2544 : :
2545 : : /* Read file */
2546 : : for ( ; ; ) {
2547 [ # # # # ]: 0 : if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
2548 : : break;
2549 : :
2550 : : printf("%s", msg_in);
2551 : 0 : msg_out[0] = 0;
2552 : :
2553 : 0 : softnic_cli_process(msg_in,
2554 : : msg_out,
2555 : : msg_out_len_max,
2556 : : softnic);
2557 : :
2558 [ # # ]: 0 : if (strlen(msg_out))
2559 : : printf("%s", msg_out);
2560 : : }
2561 : :
2562 : : /* Close file */
2563 : 0 : fclose(f);
2564 : 0 : free(msg_out);
2565 : 0 : free(msg_in);
2566 : 0 : return 0;
2567 : : }
|