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