1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_ethdev.h>
12 #include <rte_swx_port_ethdev.h>
13 #include <rte_swx_port_ring.h>
14 #include <rte_swx_port_source_sink.h>
15 #include <rte_swx_port_fd.h>
16 #include <rte_swx_pipeline.h>
17 #include <rte_swx_ctl.h>
24 #ifndef CMD_MAX_TOKENS
25 #define CMD_MAX_TOKENS 256
28 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
29 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
30 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
31 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
32 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
33 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
34 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
35 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
36 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
37 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
38 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
40 #define skip_white_spaces(pos) \
42 __typeof__(pos) _p = (pos); \
43 for ( ; isspace(*_p); _p++) \
49 parser_read_uint64(uint64_t *value, const char *p)
54 p = skip_white_spaces(p);
58 val = strtoul(p, &next, 0);
80 p = skip_white_spaces(p);
89 parser_read_uint32(uint32_t *value, const char *p)
92 int ret = parser_read_uint64(&val, p);
105 parser_read_uint16(uint16_t *value, const char *p)
108 int ret = parser_read_uint64(&val, p);
113 if (val > UINT16_MAX)
120 #define PARSE_DELIMITER " \f\n\r\t\v"
123 parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
127 if ((string == NULL) ||
132 for (i = 0; i < *n_tokens; i++) {
133 tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
134 if (tokens[i] == NULL)
138 if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
148 if ((strlen(in) && index("!#%;", in[0])) ||
149 (strncmp(in, "//", 2) == 0) ||
150 (strncmp(in, "--", 2) == 0))
156 static const char cmd_mempool_help[] =
157 "mempool <mempool_name>\n"
158 " buffer <buffer_size>\n"
159 " pool <pool_size>\n"
160 " cache <cache_size>\n"
164 cmd_mempool(char **tokens,
170 struct mempool_params p;
172 struct mempool *mempool;
174 if (n_tokens != 10) {
175 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
181 if (strcmp(tokens[2], "buffer") != 0) {
182 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
186 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
187 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
191 if (strcmp(tokens[4], "pool") != 0) {
192 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
196 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
197 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
201 if (strcmp(tokens[6], "cache") != 0) {
202 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
206 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
207 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
211 if (strcmp(tokens[8], "cpu") != 0) {
212 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
216 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
217 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
221 mempool = mempool_create(obj, name, &p);
222 if (mempool == NULL) {
223 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
228 static const char cmd_link_help[] =
230 " dev <device_name> | port <port_id>\n"
231 " rxq <n_queues> <queue_size> <mempool_name>\n"
232 " txq <n_queues> <queue_size>\n"
233 " promiscuous on | off\n"
234 " [rss <qid_0> ... <qid_n>]\n";
237 cmd_link(char **tokens,
243 struct link_params p;
244 struct link_params_rss rss;
248 memset(&p, 0, sizeof(p));
250 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
251 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
256 if (strcmp(tokens[2], "dev") == 0)
257 p.dev_name = tokens[3];
258 else if (strcmp(tokens[2], "port") == 0) {
261 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
262 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
266 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
270 if (strcmp(tokens[4], "rxq") != 0) {
271 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
275 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
276 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
279 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
280 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
284 p.rx.mempool_name = tokens[7];
286 if (strcmp(tokens[8], "txq") != 0) {
287 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
291 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
292 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
296 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
297 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
301 if (strcmp(tokens[11], "promiscuous") != 0) {
302 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
306 if (strcmp(tokens[12], "on") == 0)
308 else if (strcmp(tokens[12], "off") == 0)
311 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
318 uint32_t queue_id, i;
320 if (strcmp(tokens[13], "rss") != 0) {
321 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
328 for (i = 14; i < n_tokens; i++) {
329 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
330 snprintf(out, out_size, MSG_ARG_INVALID,
335 rss.queue_id[rss.n_queues] = queue_id;
340 link = link_create(obj, name, &p);
342 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
347 /* Print the link stats and info */
349 print_link_info(struct link *link, char *out, size_t out_size)
351 struct rte_eth_stats stats;
352 struct rte_ether_addr mac_addr;
353 struct rte_eth_link eth_link;
357 memset(&stats, 0, sizeof(stats));
358 rte_eth_stats_get(link->port_id, &stats);
360 ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
362 snprintf(out, out_size, "\n%s: MAC address get failed: %s",
363 link->name, rte_strerror(-ret));
367 ret = rte_eth_link_get(link->port_id, ð_link);
369 snprintf(out, out_size, "\n%s: link get failed: %s",
370 link->name, rte_strerror(-ret));
374 rte_eth_dev_get_mtu(link->port_id, &mtu);
376 snprintf(out, out_size,
378 "%s: flags=<%s> mtu %u\n"
379 "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
380 "\tport# %u speed %s\n"
381 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
382 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
383 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
384 "\tTX errors %" PRIu64"\n",
386 eth_link.link_status == 0 ? "DOWN" : "UP",
388 RTE_ETHER_ADDR_BYTES(&mac_addr),
392 rte_eth_link_speed_to_str(eth_link.link_speed),
404 * link show [<link_name>]
407 cmd_link_show(char **tokens,
416 if (n_tokens != 2 && n_tokens != 3) {
417 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
422 link = link_next(obj, NULL);
424 while (link != NULL) {
425 out_size = out_size - strlen(out);
426 out = &out[strlen(out)];
428 print_link_info(link, out, out_size);
429 link = link_next(obj, link);
432 out_size = out_size - strlen(out);
433 out = &out[strlen(out)];
435 link_name = tokens[2];
436 link = link_find(obj, link_name);
439 snprintf(out, out_size, MSG_ARG_INVALID,
440 "Link does not exist");
443 print_link_info(link, out, out_size);
447 static const char cmd_ring_help[] =
448 "ring <ring_name> size <size> numa <numa_node>\n";
451 cmd_ring(char **tokens,
457 struct ring_params p;
462 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
468 if (strcmp(tokens[2], "size") != 0) {
469 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
473 if (parser_read_uint32(&p.size, tokens[3]) != 0) {
474 snprintf(out, out_size, MSG_ARG_INVALID, "size");
478 if (strcmp(tokens[4], "numa") != 0) {
479 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
483 if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
484 snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
488 ring = ring_create(obj, name, &p);
490 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
495 static const char cmd_tap_help[] =
499 cmd_tap(char **tokens,
509 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
514 tap = tap_create(obj, name);
516 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
521 static const char cmd_pipeline_create_help[] =
522 "pipeline <pipeline_name> create <numa_node>\n";
525 cmd_pipeline_create(char **tokens,
536 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
542 if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
543 snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
547 p = pipeline_create(obj, name, (int)numa_node);
549 snprintf(out, out_size, "pipeline create error.");
554 static const char cmd_pipeline_port_in_help[] =
555 "pipeline <pipeline_name> port in <port_id>\n"
556 " link <link_name> rxq <queue_id> bsz <burst_size>\n"
557 " ring <ring_name> bsz <burst_size>\n"
558 " | source <mempool_name> <file_name> loop <n_loops>\n"
559 " | tap <tap_name> mempool <mempool_name> mtu <mtu> bsz <burst_size>\n";
562 cmd_pipeline_port_in(char **tokens,
570 uint32_t port_id = 0, t0;
573 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
577 p = pipeline_find(obj, tokens[1]);
579 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
583 if (strcmp(tokens[2], "port") != 0) {
584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
588 if (strcmp(tokens[3], "in") != 0) {
589 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
593 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
594 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
600 if (strcmp(tokens[t0], "link") == 0) {
601 struct rte_swx_port_ethdev_reader_params params;
604 if (n_tokens < t0 + 6) {
605 snprintf(out, out_size, MSG_ARG_MISMATCH,
606 "pipeline port in link");
610 link = link_find(obj, tokens[t0 + 1]);
612 snprintf(out, out_size, MSG_ARG_INVALID,
616 params.dev_name = link->dev_name;
618 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
619 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
623 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
624 snprintf(out, out_size, MSG_ARG_INVALID,
629 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
630 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
634 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
635 snprintf(out, out_size, MSG_ARG_INVALID,
642 status = rte_swx_pipeline_port_in_config(p->p,
646 } else if (strcmp(tokens[t0], "ring") == 0) {
647 struct rte_swx_port_ring_reader_params params;
650 if (n_tokens < t0 + 4) {
651 snprintf(out, out_size, MSG_ARG_MISMATCH,
652 "pipeline port in ring");
656 ring = ring_find(obj, tokens[t0 + 1]);
658 snprintf(out, out_size, MSG_ARG_INVALID,
662 params.name = ring->name;
664 if (strcmp(tokens[t0 + 2], "bsz") != 0) {
665 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
669 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 3])) {
670 snprintf(out, out_size, MSG_ARG_INVALID,
677 status = rte_swx_pipeline_port_in_config(p->p,
681 } else if (strcmp(tokens[t0], "source") == 0) {
682 struct rte_swx_port_source_params params;
685 if (n_tokens < t0 + 5) {
686 snprintf(out, out_size, MSG_ARG_MISMATCH,
687 "pipeline port in source");
691 mp = mempool_find(obj, tokens[t0 + 1]);
693 snprintf(out, out_size, MSG_ARG_INVALID,
699 params.file_name = tokens[t0 + 2];
701 if (strcmp(tokens[t0 + 3], "loop") != 0) {
702 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "loop");
706 if (parser_read_uint64(¶ms.n_loops, tokens[t0 + 4])) {
707 snprintf(out, out_size, MSG_ARG_INVALID,
714 status = rte_swx_pipeline_port_in_config(p->p,
718 } else if (strcmp(tokens[t0], "tap") == 0) {
719 struct rte_swx_port_fd_reader_params params;
723 if (n_tokens < t0 + 8) {
724 snprintf(out, out_size, MSG_ARG_MISMATCH,
725 "pipeline port in tap");
729 tap = tap_find(obj, tokens[t0 + 1]);
731 snprintf(out, out_size, MSG_ARG_INVALID,
737 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
738 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
743 mp = mempool_find(obj, tokens[t0 + 3]);
745 snprintf(out, out_size, MSG_ARG_INVALID,
749 params.mempool = mp->m;
751 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
752 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
757 if (parser_read_uint32(¶ms.mtu, tokens[t0 + 5]) != 0) {
758 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
762 if (strcmp(tokens[t0 + 6], "bsz") != 0) {
763 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
767 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 7])) {
768 snprintf(out, out_size, MSG_ARG_INVALID,
775 status = rte_swx_pipeline_port_in_config(p->p,
781 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
786 snprintf(out, out_size, "port in error.");
790 if (n_tokens != t0) {
791 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
796 static const char cmd_pipeline_port_out_help[] =
797 "pipeline <pipeline_name> port out <port_id>\n"
798 " link <link_name> txq <txq_id> bsz <burst_size>\n"
799 " ring <ring_name> bsz <burst_size>\n"
800 " | sink <file_name> | none\n"
801 " | tap <tap_name> bsz <burst_size>\n";
804 cmd_pipeline_port_out(char **tokens,
812 uint32_t port_id = 0, t0;
815 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
819 p = pipeline_find(obj, tokens[1]);
821 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
825 if (strcmp(tokens[2], "port") != 0) {
826 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
830 if (strcmp(tokens[3], "out") != 0) {
831 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
835 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
836 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
842 if (strcmp(tokens[t0], "link") == 0) {
843 struct rte_swx_port_ethdev_writer_params params;
846 if (n_tokens < t0 + 6) {
847 snprintf(out, out_size, MSG_ARG_MISMATCH,
848 "pipeline port out link");
852 link = link_find(obj, tokens[t0 + 1]);
854 snprintf(out, out_size, MSG_ARG_INVALID,
858 params.dev_name = link->dev_name;
860 if (strcmp(tokens[t0 + 2], "txq") != 0) {
861 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
865 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
866 snprintf(out, out_size, MSG_ARG_INVALID,
871 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
872 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
876 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
877 snprintf(out, out_size, MSG_ARG_INVALID,
884 status = rte_swx_pipeline_port_out_config(p->p,
888 } else if (strcmp(tokens[t0], "ring") == 0) {
889 struct rte_swx_port_ring_writer_params params;
892 if (n_tokens < t0 + 4) {
893 snprintf(out, out_size, MSG_ARG_MISMATCH,
894 "pipeline port out link");
898 ring = ring_find(obj, tokens[t0 + 1]);
900 snprintf(out, out_size, MSG_ARG_INVALID,
904 params.name = ring->name;
906 if (strcmp(tokens[t0 + 2], "bsz") != 0) {
907 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
911 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 3])) {
912 snprintf(out, out_size, MSG_ARG_INVALID,
919 status = rte_swx_pipeline_port_out_config(p->p,
923 } else if (strcmp(tokens[t0], "sink") == 0) {
924 struct rte_swx_port_sink_params params;
926 params.file_name = strcmp(tokens[t0 + 1], "none") ?
927 tokens[t0 + 1] : NULL;
931 status = rte_swx_pipeline_port_out_config(p->p,
935 } else if (strcmp(tokens[t0], "tap") == 0) {
936 struct rte_swx_port_fd_writer_params params;
939 if (n_tokens < t0 + 4) {
940 snprintf(out, out_size, MSG_ARG_MISMATCH,
941 "pipeline port out tap");
945 tap = tap_find(obj, tokens[t0 + 1]);
947 snprintf(out, out_size, MSG_ARG_INVALID,
953 if (strcmp(tokens[t0 + 2], "bsz") != 0) {
954 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
958 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 3])) {
959 snprintf(out, out_size, MSG_ARG_INVALID,
966 status = rte_swx_pipeline_port_out_config(p->p,
971 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
976 snprintf(out, out_size, "port out error.");
980 if (n_tokens != t0) {
981 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
986 static const char cmd_pipeline_build_help[] =
987 "pipeline <pipeline_name> build <spec_file>\n";
990 cmd_pipeline_build(char **tokens,
996 struct pipeline *p = NULL;
1002 if (n_tokens != 4) {
1003 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1007 p = pipeline_find(obj, tokens[1]);
1009 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1013 spec = fopen(tokens[3], "r");
1015 snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
1019 status = rte_swx_pipeline_build_from_spec(p->p,
1025 snprintf(out, out_size, "Error %d at line %u: %s\n.",
1026 status, err_line, err_msg);
1030 p->ctl = rte_swx_ctl_pipeline_create(p->p);
1032 snprintf(out, out_size, "Pipeline control create failed.");
1033 rte_swx_pipeline_free(p->p);
1039 table_entry_free(struct rte_swx_table_entry *entry)
1045 free(entry->key_mask);
1046 free(entry->action_data);
1050 #ifndef MAX_LINE_SIZE
1051 #define MAX_LINE_SIZE 2048
1055 pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
1056 const char *table_name,
1058 uint32_t *file_line_number)
1061 uint32_t line_id = 0;
1064 /* Buffer allocation. */
1065 line = malloc(MAX_LINE_SIZE);
1070 for (line_id = 1; ; line_id++) {
1071 struct rte_swx_table_entry *entry;
1072 int is_blank_or_comment;
1074 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1077 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1080 &is_blank_or_comment);
1082 if (is_blank_or_comment)
1089 status = rte_swx_ctl_pipeline_table_entry_add(p,
1092 table_entry_free(entry);
1099 *file_line_number = line_id;
1103 static const char cmd_pipeline_table_add_help[] =
1104 "pipeline <pipeline_name> table <table_name> add <file_name>\n";
1107 cmd_pipeline_table_add(char **tokens,
1114 char *pipeline_name, *table_name, *file_name;
1116 uint32_t file_line_number = 0;
1119 if (n_tokens != 6) {
1120 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1124 pipeline_name = tokens[1];
1125 p = pipeline_find(obj, pipeline_name);
1126 if (!p || !p->ctl) {
1127 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1131 table_name = tokens[3];
1133 file_name = tokens[5];
1134 file = fopen(file_name, "r");
1136 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1140 status = pipeline_table_entries_add(p->ctl,
1145 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1153 pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
1154 const char *table_name,
1156 uint32_t *file_line_number)
1159 uint32_t line_id = 0;
1162 /* Buffer allocation. */
1163 line = malloc(MAX_LINE_SIZE);
1168 for (line_id = 1; ; line_id++) {
1169 struct rte_swx_table_entry *entry;
1170 int is_blank_or_comment;
1172 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1175 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1178 &is_blank_or_comment);
1180 if (is_blank_or_comment)
1187 status = rte_swx_ctl_pipeline_table_entry_delete(p,
1190 table_entry_free(entry);
1196 *file_line_number = line_id;
1201 static const char cmd_pipeline_table_delete_help[] =
1202 "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
1205 cmd_pipeline_table_delete(char **tokens,
1212 char *pipeline_name, *table_name, *file_name;
1214 uint32_t file_line_number = 0;
1217 if (n_tokens != 6) {
1218 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1222 pipeline_name = tokens[1];
1223 p = pipeline_find(obj, pipeline_name);
1224 if (!p || !p->ctl) {
1225 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1229 table_name = tokens[3];
1231 file_name = tokens[5];
1232 file = fopen(file_name, "r");
1234 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1238 status = pipeline_table_entries_delete(p->ctl,
1243 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1251 pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
1252 const char *table_name,
1254 uint32_t *file_line_number)
1257 uint32_t line_id = 0;
1260 /* Buffer allocation. */
1261 line = malloc(MAX_LINE_SIZE);
1266 for (line_id = 1; ; line_id++) {
1267 struct rte_swx_table_entry *entry;
1268 int is_blank_or_comment;
1270 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1273 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1276 &is_blank_or_comment);
1278 if (is_blank_or_comment)
1285 status = rte_swx_ctl_pipeline_table_default_entry_add(p,
1288 table_entry_free(entry);
1294 *file_line_number = line_id;
1299 static const char cmd_pipeline_table_default_help[] =
1300 "pipeline <pipeline_name> table <table_name> default <file_name>\n";
1303 cmd_pipeline_table_default(char **tokens,
1310 char *pipeline_name, *table_name, *file_name;
1312 uint32_t file_line_number = 0;
1315 if (n_tokens != 6) {
1316 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1320 pipeline_name = tokens[1];
1321 p = pipeline_find(obj, pipeline_name);
1322 if (!p || !p->ctl) {
1323 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1327 table_name = tokens[3];
1329 file_name = tokens[5];
1330 file = fopen(file_name, "r");
1332 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1336 status = pipeline_table_default_entry_add(p->ctl,
1341 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1348 static const char cmd_pipeline_table_show_help[] =
1349 "pipeline <pipeline_name> table <table_name> show [filename]\n";
1352 cmd_pipeline_table_show(char **tokens,
1359 char *pipeline_name, *table_name;
1363 if (n_tokens != 5 && n_tokens != 6) {
1364 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1368 pipeline_name = tokens[1];
1369 p = pipeline_find(obj, pipeline_name);
1370 if (!p || !p->ctl) {
1371 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1375 table_name = tokens[3];
1376 file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1378 snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1382 status = rte_swx_ctl_pipeline_table_fprintf(file, p->ctl, table_name);
1384 snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1390 static const char cmd_pipeline_selector_group_add_help[] =
1391 "pipeline <pipeline_name> selector <selector_name> group add\n";
1394 cmd_pipeline_selector_group_add(char **tokens,
1401 char *pipeline_name, *selector_name;
1405 if (n_tokens != 6) {
1406 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1410 pipeline_name = tokens[1];
1411 p = pipeline_find(obj, pipeline_name);
1412 if (!p || !p->ctl) {
1413 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1417 if (strcmp(tokens[2], "selector") != 0) {
1418 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1422 selector_name = tokens[3];
1424 if (strcmp(tokens[4], "group") ||
1425 strcmp(tokens[5], "add")) {
1426 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1430 status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
1434 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1436 snprintf(out, out_size, "Group ID: %u\n", group_id);
1439 static const char cmd_pipeline_selector_group_delete_help[] =
1440 "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1443 cmd_pipeline_selector_group_delete(char **tokens,
1450 char *pipeline_name, *selector_name;
1454 if (n_tokens != 7) {
1455 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1459 pipeline_name = tokens[1];
1460 p = pipeline_find(obj, pipeline_name);
1461 if (!p || !p->ctl) {
1462 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1466 if (strcmp(tokens[2], "selector") != 0) {
1467 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1471 selector_name = tokens[3];
1473 if (strcmp(tokens[4], "group") ||
1474 strcmp(tokens[5], "delete")) {
1475 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1479 if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1480 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1484 status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
1488 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1491 #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1494 token_is_comment(const char *token)
1496 if ((token[0] == '#') ||
1497 (token[0] == ';') ||
1498 ((token[0] == '/') && (token[1] == '/')))
1499 return 1; /* TRUE. */
1501 return 0; /* FALSE. */
1505 pipeline_selector_group_member_read(const char *string,
1507 uint32_t *member_id,
1509 int *is_blank_or_comment)
1511 char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1512 char *s0 = NULL, *s;
1513 uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1514 int blank_or_comment = 0;
1516 /* Check input arguments. */
1517 if (!string || !string[0])
1520 /* Memory allocation. */
1521 s0 = strdup(string);
1525 /* Parse the string into tokens. */
1529 token = strtok_r(s, " \f\n\r\t\v", &s);
1530 if (!token || token_is_comment(token))
1533 if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1536 token_array[n_tokens] = token;
1541 blank_or_comment = 1;
1545 tokens = token_array;
1548 strcmp(tokens[0], "group") ||
1549 strcmp(tokens[2], "member"))
1555 if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1557 *group_id = group_id_val;
1562 if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1564 *member_id = member_id_val;
1572 if (n_tokens && !strcmp(tokens[0], "weight")) {
1576 if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1578 *weight = weight_val;
1592 if (is_blank_or_comment)
1593 *is_blank_or_comment = blank_or_comment;
1598 pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1599 const char *selector_name,
1601 uint32_t *file_line_number)
1604 uint32_t line_id = 0;
1607 /* Buffer allocation. */
1608 line = malloc(MAX_LINE_SIZE);
1613 for (line_id = 1; ; line_id++) {
1614 uint32_t group_id, member_id, weight;
1615 int is_blank_or_comment;
1617 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1620 status = pipeline_selector_group_member_read(line,
1624 &is_blank_or_comment);
1626 if (is_blank_or_comment)
1632 status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1643 *file_line_number = line_id;
1647 static const char cmd_pipeline_selector_group_member_add_help[] =
1648 "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1651 cmd_pipeline_selector_group_member_add(char **tokens,
1658 char *pipeline_name, *selector_name, *file_name;
1660 uint32_t file_line_number = 0;
1663 if (n_tokens != 8) {
1664 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1668 pipeline_name = tokens[1];
1669 p = pipeline_find(obj, pipeline_name);
1670 if (!p || !p->ctl) {
1671 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1675 if (strcmp(tokens[2], "selector") != 0) {
1676 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1680 selector_name = tokens[3];
1682 if (strcmp(tokens[4], "group") ||
1683 strcmp(tokens[5], "member") ||
1684 strcmp(tokens[6], "add")) {
1685 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1689 file_name = tokens[7];
1690 file = fopen(file_name, "r");
1692 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1696 status = pipeline_selector_group_members_add(p->ctl,
1701 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1709 pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1710 const char *selector_name,
1712 uint32_t *file_line_number)
1715 uint32_t line_id = 0;
1718 /* Buffer allocation. */
1719 line = malloc(MAX_LINE_SIZE);
1724 for (line_id = 1; ; line_id++) {
1725 uint32_t group_id, member_id, weight;
1726 int is_blank_or_comment;
1728 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1731 status = pipeline_selector_group_member_read(line,
1735 &is_blank_or_comment);
1737 if (is_blank_or_comment)
1743 status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1753 *file_line_number = line_id;
1757 static const char cmd_pipeline_selector_group_member_delete_help[] =
1758 "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1761 cmd_pipeline_selector_group_member_delete(char **tokens,
1768 char *pipeline_name, *selector_name, *file_name;
1770 uint32_t file_line_number = 0;
1773 if (n_tokens != 8) {
1774 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1778 pipeline_name = tokens[1];
1779 p = pipeline_find(obj, pipeline_name);
1780 if (!p || !p->ctl) {
1781 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1785 if (strcmp(tokens[2], "selector") != 0) {
1786 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1790 selector_name = tokens[3];
1792 if (strcmp(tokens[4], "group") ||
1793 strcmp(tokens[5], "member") ||
1794 strcmp(tokens[6], "delete")) {
1795 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1799 file_name = tokens[7];
1800 file = fopen(file_name, "r");
1802 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1806 status = pipeline_selector_group_members_delete(p->ctl,
1811 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1818 static const char cmd_pipeline_selector_show_help[] =
1819 "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1822 cmd_pipeline_selector_show(char **tokens,
1829 char *pipeline_name, *selector_name;
1833 if (n_tokens != 5 && n_tokens != 6) {
1834 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1838 pipeline_name = tokens[1];
1839 p = pipeline_find(obj, pipeline_name);
1840 if (!p || !p->ctl) {
1841 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1845 selector_name = tokens[3];
1847 file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1849 snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1853 status = rte_swx_ctl_pipeline_selector_fprintf(file, p->ctl, selector_name);
1855 snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1862 pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
1863 const char *learner_name,
1865 uint32_t *file_line_number)
1868 uint32_t line_id = 0;
1871 /* Buffer allocation. */
1872 line = malloc(MAX_LINE_SIZE);
1877 for (line_id = 1; ; line_id++) {
1878 struct rte_swx_table_entry *entry;
1879 int is_blank_or_comment;
1881 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1884 entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
1887 &is_blank_or_comment);
1889 if (is_blank_or_comment)
1896 status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
1899 table_entry_free(entry);
1905 *file_line_number = line_id;
1910 static const char cmd_pipeline_learner_default_help[] =
1911 "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
1914 cmd_pipeline_learner_default(char **tokens,
1921 char *pipeline_name, *learner_name, *file_name;
1923 uint32_t file_line_number = 0;
1926 if (n_tokens != 6) {
1927 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1931 pipeline_name = tokens[1];
1932 p = pipeline_find(obj, pipeline_name);
1933 if (!p || !p->ctl) {
1934 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1938 learner_name = tokens[3];
1940 file_name = tokens[5];
1941 file = fopen(file_name, "r");
1943 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1947 status = pipeline_learner_default_entry_add(p->ctl,
1952 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1959 static const char cmd_pipeline_commit_help[] =
1960 "pipeline <pipeline_name> commit\n";
1963 cmd_pipeline_commit(char **tokens,
1970 char *pipeline_name;
1973 if (n_tokens != 3) {
1974 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1978 pipeline_name = tokens[1];
1979 p = pipeline_find(obj, pipeline_name);
1980 if (!p || !p->ctl) {
1981 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1985 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1987 snprintf(out, out_size, "Commit failed. "
1988 "Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1991 static const char cmd_pipeline_abort_help[] =
1992 "pipeline <pipeline_name> abort\n";
1995 cmd_pipeline_abort(char **tokens,
2002 char *pipeline_name;
2004 if (n_tokens != 3) {
2005 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2009 pipeline_name = tokens[1];
2010 p = pipeline_find(obj, pipeline_name);
2011 if (!p || !p->ctl) {
2012 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2016 rte_swx_ctl_pipeline_abort(p->ctl);
2019 static const char cmd_pipeline_regrd_help[] =
2020 "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
2023 cmd_pipeline_regrd(char **tokens,
2035 if (n_tokens != 5) {
2036 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2040 p = pipeline_find(obj, tokens[1]);
2041 if (!p || !p->ctl) {
2042 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2046 if (strcmp(tokens[2], "regrd")) {
2047 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
2053 if (parser_read_uint32(&idx, tokens[4])) {
2054 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2058 status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
2060 snprintf(out, out_size, "Command failed.\n");
2064 snprintf(out, out_size, "0x%" PRIx64 "\n", value);
2067 static const char cmd_pipeline_regwr_help[] =
2068 "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
2071 cmd_pipeline_regwr(char **tokens,
2083 if (n_tokens != 6) {
2084 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2088 p = pipeline_find(obj, tokens[1]);
2089 if (!p || !p->ctl) {
2090 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2094 if (strcmp(tokens[2], "regwr")) {
2095 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
2101 if (parser_read_uint32(&idx, tokens[4])) {
2102 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2106 if (parser_read_uint64(&value, tokens[5])) {
2107 snprintf(out, out_size, MSG_ARG_INVALID, "value");
2111 status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
2113 snprintf(out, out_size, "Command failed.\n");
2118 static const char cmd_pipeline_meter_profile_add_help[] =
2119 "pipeline <pipeline_name> meter profile <profile_name> add "
2120 "cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
2123 cmd_pipeline_meter_profile_add(char **tokens,
2129 struct rte_meter_trtcm_params params;
2131 const char *profile_name;
2134 if (n_tokens != 14) {
2135 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2139 p = pipeline_find(obj, tokens[1]);
2140 if (!p || !p->ctl) {
2141 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2145 if (strcmp(tokens[2], "meter")) {
2146 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2150 if (strcmp(tokens[3], "profile")) {
2151 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2155 profile_name = tokens[4];
2157 if (strcmp(tokens[5], "add")) {
2158 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2162 if (strcmp(tokens[6], "cir")) {
2163 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2167 if (parser_read_uint64(¶ms.cir, tokens[7])) {
2168 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2172 if (strcmp(tokens[8], "pir")) {
2173 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2177 if (parser_read_uint64(¶ms.pir, tokens[9])) {
2178 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2182 if (strcmp(tokens[10], "cbs")) {
2183 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2187 if (parser_read_uint64(¶ms.cbs, tokens[11])) {
2188 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2192 if (strcmp(tokens[12], "pbs")) {
2193 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2197 if (parser_read_uint64(¶ms.pbs, tokens[13])) {
2198 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2202 status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
2204 snprintf(out, out_size, "Command failed.\n");
2209 static const char cmd_pipeline_meter_profile_delete_help[] =
2210 "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2213 cmd_pipeline_meter_profile_delete(char **tokens,
2220 const char *profile_name;
2223 if (n_tokens != 6) {
2224 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2228 p = pipeline_find(obj, tokens[1]);
2229 if (!p || !p->ctl) {
2230 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2234 if (strcmp(tokens[2], "meter")) {
2235 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2239 if (strcmp(tokens[3], "profile")) {
2240 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2244 profile_name = tokens[4];
2246 if (strcmp(tokens[5], "delete")) {
2247 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2251 status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
2253 snprintf(out, out_size, "Command failed.\n");
2258 static const char cmd_pipeline_meter_reset_help[] =
2259 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2263 cmd_pipeline_meter_reset(char **tokens,
2271 uint32_t idx0 = 0, idx1 = 0;
2273 if (n_tokens != 9) {
2274 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2278 p = pipeline_find(obj, tokens[1]);
2279 if (!p || !p->ctl) {
2280 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2284 if (strcmp(tokens[2], "meter")) {
2285 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2291 if (strcmp(tokens[4], "from")) {
2292 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2296 if (parser_read_uint32(&idx0, tokens[5])) {
2297 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2301 if (strcmp(tokens[6], "to")) {
2302 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2306 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2307 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2311 if (strcmp(tokens[8], "reset")) {
2312 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2316 for ( ; idx0 <= idx1; idx0++) {
2319 status = rte_swx_ctl_meter_reset(p->p, name, idx0);
2321 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2327 static const char cmd_pipeline_meter_set_help[] =
2328 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2329 "set profile <profile_name>\n";
2332 cmd_pipeline_meter_set(char **tokens,
2339 const char *name, *profile_name;
2340 uint32_t idx0 = 0, idx1 = 0;
2342 if (n_tokens != 11) {
2343 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2347 p = pipeline_find(obj, tokens[1]);
2348 if (!p || !p->ctl) {
2349 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2353 if (strcmp(tokens[2], "meter")) {
2354 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2360 if (strcmp(tokens[4], "from")) {
2361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2365 if (parser_read_uint32(&idx0, tokens[5])) {
2366 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2370 if (strcmp(tokens[6], "to")) {
2371 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2375 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2376 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2380 if (strcmp(tokens[8], "set")) {
2381 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2385 if (strcmp(tokens[9], "profile")) {
2386 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2390 profile_name = tokens[10];
2392 for ( ; idx0 <= idx1; idx0++) {
2395 status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
2397 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2403 static const char cmd_pipeline_meter_stats_help[] =
2404 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2408 cmd_pipeline_meter_stats(char **tokens,
2414 struct rte_swx_ctl_meter_stats stats;
2417 uint32_t idx0 = 0, idx1 = 0;
2419 if (n_tokens != 9) {
2420 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2424 p = pipeline_find(obj, tokens[1]);
2425 if (!p || !p->ctl) {
2426 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2430 if (strcmp(tokens[2], "meter")) {
2431 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2437 if (strcmp(tokens[4], "from")) {
2438 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2442 if (parser_read_uint32(&idx0, tokens[5])) {
2443 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2447 if (strcmp(tokens[6], "to")) {
2448 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2452 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2453 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2457 if (strcmp(tokens[8], "stats")) {
2458 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2463 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2465 "----------------", "----------------", "----------------",
2466 "----------------", "----------------", "----------------");
2467 out_size -= strlen(out);
2470 snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2472 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2473 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2474 out_size -= strlen(out);
2477 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2479 "----------------", "----------------", "----------------",
2480 "----------------", "----------------", "----------------");
2481 out_size -= strlen(out);
2485 for ( ; idx0 <= idx1; idx0++) {
2488 status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
2490 snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2491 out_size -= strlen(out);
2496 snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2497 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2499 stats.n_pkts[RTE_COLOR_GREEN],
2500 stats.n_pkts[RTE_COLOR_YELLOW],
2501 stats.n_pkts[RTE_COLOR_RED],
2502 stats.n_bytes[RTE_COLOR_GREEN],
2503 stats.n_bytes[RTE_COLOR_YELLOW],
2504 stats.n_bytes[RTE_COLOR_RED]);
2505 out_size -= strlen(out);
2510 static const char cmd_pipeline_stats_help[] =
2511 "pipeline <pipeline_name> stats\n";
2514 cmd_pipeline_stats(char **tokens,
2520 struct rte_swx_ctl_pipeline_info info;
2525 if (n_tokens != 3) {
2526 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2530 p = pipeline_find(obj, tokens[1]);
2531 if (!p || !p->ctl) {
2532 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2536 if (strcmp(tokens[2], "stats")) {
2537 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2541 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
2543 snprintf(out, out_size, "Pipeline info get error.");
2547 snprintf(out, out_size, "Input ports:\n");
2548 out_size -= strlen(out);
2551 for (i = 0; i < info.n_ports_in; i++) {
2552 struct rte_swx_port_in_stats stats;
2554 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
2556 snprintf(out, out_size, "\tPort %u:"
2559 " empty %" PRIu64 "\n",
2560 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
2561 out_size -= strlen(out);
2565 snprintf(out, out_size, "\nOutput ports:\n");
2566 out_size -= strlen(out);
2569 for (i = 0; i < info.n_ports_out; i++) {
2570 struct rte_swx_port_out_stats stats;
2572 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
2574 if (i != info.n_ports_out - 1)
2575 snprintf(out, out_size, "\tPort %u:", i);
2577 snprintf(out, out_size, "\tDROP:");
2579 out_size -= strlen(out);
2587 " clonerr %" PRIu64 "\n",
2591 stats.n_pkts_clone_err);
2593 out_size -= strlen(out);
2597 snprintf(out, out_size, "\nTables:\n");
2598 out_size -= strlen(out);
2601 for (i = 0; i < info.n_tables; i++) {
2602 struct rte_swx_ctl_table_info table_info;
2603 uint64_t n_pkts_action[info.n_actions];
2604 struct rte_swx_table_stats stats = {
2607 .n_pkts_action = n_pkts_action,
2611 status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2613 snprintf(out, out_size, "Table info get error.");
2617 status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2619 snprintf(out, out_size, "Table stats read error.");
2623 snprintf(out, out_size, "\tTable %s:\n"
2624 "\t\tHit (packets): %" PRIu64 "\n"
2625 "\t\tMiss (packets): %" PRIu64 "\n",
2629 out_size -= strlen(out);
2632 for (j = 0; j < info.n_actions; j++) {
2633 struct rte_swx_ctl_action_info action_info;
2635 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2637 snprintf(out, out_size, "Action info get error.");
2641 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2643 stats.n_pkts_action[j]);
2644 out_size -= strlen(out);
2649 snprintf(out, out_size, "\nLearner tables:\n");
2650 out_size -= strlen(out);
2653 for (i = 0; i < info.n_learners; i++) {
2654 struct rte_swx_ctl_learner_info learner_info;
2655 uint64_t n_pkts_action[info.n_actions];
2656 struct rte_swx_learner_stats stats = {
2659 .n_pkts_action = n_pkts_action,
2663 status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
2665 snprintf(out, out_size, "Learner table info get error.");
2669 status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
2671 snprintf(out, out_size, "Learner table stats read error.");
2675 snprintf(out, out_size, "\tLearner table %s:\n"
2676 "\t\tHit (packets): %" PRIu64 "\n"
2677 "\t\tMiss (packets): %" PRIu64 "\n"
2678 "\t\tLearn OK (packets): %" PRIu64 "\n"
2679 "\t\tLearn error (packets): %" PRIu64 "\n"
2680 "\t\tRearm (packets): %" PRIu64 "\n"
2681 "\t\tForget (packets): %" PRIu64 "\n",
2685 stats.n_pkts_learn_ok,
2686 stats.n_pkts_learn_err,
2688 stats.n_pkts_forget);
2689 out_size -= strlen(out);
2692 for (j = 0; j < info.n_actions; j++) {
2693 struct rte_swx_ctl_action_info action_info;
2695 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2697 snprintf(out, out_size, "Action info get error.");
2701 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2703 stats.n_pkts_action[j]);
2704 out_size -= strlen(out);
2710 static const char cmd_pipeline_mirror_help[] =
2711 "pipeline <pipeline_name> mirror slots <n_slots> sessions <n_sessions>\n";
2714 cmd_pipeline_mirror(char **tokens,
2720 struct rte_swx_pipeline_mirroring_params params;
2724 if (n_tokens != 7) {
2725 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2729 if (strcmp(tokens[0], "pipeline")) {
2730 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2734 p = pipeline_find(obj, tokens[1]);
2736 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2740 if (strcmp(tokens[2], "mirror")) {
2741 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
2745 if (strcmp(tokens[3], "slots")) {
2746 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "slots");
2750 if (parser_read_uint32(¶ms.n_slots, tokens[4])) {
2751 snprintf(out, out_size, MSG_ARG_INVALID, "n_slots");
2755 if (strcmp(tokens[5], "sessions")) {
2756 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "sessions");
2760 if (parser_read_uint32(¶ms.n_sessions, tokens[6])) {
2761 snprintf(out, out_size, MSG_ARG_INVALID, "n_sessions");
2765 status = rte_swx_pipeline_mirroring_config(p->p, ¶ms);
2767 snprintf(out, out_size, "Command failed!\n");
2772 static const char cmd_pipeline_mirror_session_help[] =
2773 "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
2774 "truncate <truncation_length>\n";
2777 cmd_pipeline_mirror_session(char **tokens,
2783 struct rte_swx_pipeline_mirroring_session_params params;
2785 uint32_t session_id = 0;
2788 if (n_tokens != 11) {
2789 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2793 if (strcmp(tokens[0], "pipeline")) {
2794 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2798 p = pipeline_find(obj, tokens[1]);
2799 if (!p || !p->ctl) {
2800 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2804 if (strcmp(tokens[2], "mirror")) {
2805 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
2809 if (strcmp(tokens[3], "session")) {
2810 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
2814 if (parser_read_uint32(&session_id, tokens[4])) {
2815 snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
2819 if (strcmp(tokens[5], "port")) {
2820 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2824 if (parser_read_uint32(¶ms.port_id, tokens[6])) {
2825 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2829 if (strcmp(tokens[7], "clone")) {
2830 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
2834 if (!strcmp(tokens[8], "fast"))
2835 params.fast_clone = 1;
2836 else if (!strcmp(tokens[8], "slow"))
2837 params.fast_clone = 0;
2839 snprintf(out, out_size, MSG_ARG_INVALID, "clone");
2843 if (strcmp(tokens[9], "truncate")) {
2844 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
2848 if (parser_read_uint32(¶ms.truncation_length, tokens[10])) {
2849 snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
2853 status = rte_swx_ctl_pipeline_mirroring_session_set(p->p, session_id, ¶ms);
2855 snprintf(out, out_size, "Command failed!\n");
2860 static const char cmd_thread_pipeline_enable_help[] =
2861 "thread <thread_id> pipeline <pipeline_name> enable\n";
2864 cmd_thread_pipeline_enable(char **tokens,
2870 char *pipeline_name;
2875 if (n_tokens != 5) {
2876 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2880 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2881 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2885 if (strcmp(tokens[2], "pipeline") != 0) {
2886 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2890 pipeline_name = tokens[3];
2891 p = pipeline_find(obj, pipeline_name);
2892 if (!p || !p->ctl) {
2893 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2897 if (strcmp(tokens[4], "enable") != 0) {
2898 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2902 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
2904 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
2909 static const char cmd_thread_pipeline_disable_help[] =
2910 "thread <thread_id> pipeline <pipeline_name> disable\n";
2913 cmd_thread_pipeline_disable(char **tokens,
2920 char *pipeline_name;
2924 if (n_tokens != 5) {
2925 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2929 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2930 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2934 if (strcmp(tokens[2], "pipeline") != 0) {
2935 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2939 pipeline_name = tokens[3];
2940 p = pipeline_find(obj, pipeline_name);
2941 if (!p || !p->ctl) {
2942 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2946 if (strcmp(tokens[4], "disable") != 0) {
2947 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2951 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
2953 snprintf(out, out_size, MSG_CMD_FAIL,
2954 "thread pipeline disable");
2960 cmd_help(char **tokens,
2964 void *arg __rte_unused)
2969 if (n_tokens == 0) {
2970 snprintf(out, out_size,
2971 "Type 'help <command>' for command details.\n\n"
2972 "List of commands:\n"
2976 "\tpipeline create\n"
2977 "\tpipeline port in\n"
2978 "\tpipeline port out\n"
2979 "\tpipeline build\n"
2980 "\tpipeline table add\n"
2981 "\tpipeline table delete\n"
2982 "\tpipeline table default\n"
2983 "\tpipeline table show\n"
2984 "\tpipeline selector group add\n"
2985 "\tpipeline selector group delete\n"
2986 "\tpipeline selector group member add\n"
2987 "\tpipeline selector group member delete\n"
2988 "\tpipeline selector show\n"
2989 "\tpipeline learner default\n"
2990 "\tpipeline commit\n"
2991 "\tpipeline abort\n"
2992 "\tpipeline regrd\n"
2993 "\tpipeline regwr\n"
2994 "\tpipeline meter profile add\n"
2995 "\tpipeline meter profile delete\n"
2996 "\tpipeline meter reset\n"
2997 "\tpipeline meter set\n"
2998 "\tpipeline meter stats\n"
2999 "\tpipeline stats\n"
3000 "\tpipeline mirror\n"
3001 "\tpipeline mirror session\n"
3002 "\tthread pipeline enable\n"
3003 "\tthread pipeline disable\n\n");
3007 if (strcmp(tokens[0], "mempool") == 0) {
3008 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
3012 if (strcmp(tokens[0], "link") == 0) {
3013 snprintf(out, out_size, "\n%s\n", cmd_link_help);
3017 if (strcmp(tokens[0], "ring") == 0) {
3018 snprintf(out, out_size, "\n%s\n", cmd_ring_help);
3022 if (strcmp(tokens[0], "tap") == 0) {
3023 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
3027 if ((strcmp(tokens[0], "pipeline") == 0) &&
3028 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
3029 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
3033 if ((strcmp(tokens[0], "pipeline") == 0) &&
3034 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
3035 if (strcmp(tokens[2], "in") == 0) {
3036 snprintf(out, out_size, "\n%s\n",
3037 cmd_pipeline_port_in_help);
3041 if (strcmp(tokens[2], "out") == 0) {
3042 snprintf(out, out_size, "\n%s\n",
3043 cmd_pipeline_port_out_help);
3048 if ((strcmp(tokens[0], "pipeline") == 0) &&
3049 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
3050 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
3054 if ((strcmp(tokens[0], "pipeline") == 0) &&
3056 (strcmp(tokens[1], "table") == 0) &&
3057 (strcmp(tokens[2], "add") == 0)) {
3058 snprintf(out, out_size, "\n%s\n",
3059 cmd_pipeline_table_add_help);
3063 if ((strcmp(tokens[0], "pipeline") == 0) &&
3065 (strcmp(tokens[1], "table") == 0) &&
3066 (strcmp(tokens[2], "delete") == 0)) {
3067 snprintf(out, out_size, "\n%s\n",
3068 cmd_pipeline_table_delete_help);
3072 if ((strcmp(tokens[0], "pipeline") == 0) &&
3074 (strcmp(tokens[1], "table") == 0) &&
3075 (strcmp(tokens[2], "default") == 0)) {
3076 snprintf(out, out_size, "\n%s\n",
3077 cmd_pipeline_table_default_help);
3081 if ((strcmp(tokens[0], "pipeline") == 0) &&
3083 (strcmp(tokens[1], "table") == 0) &&
3084 (strcmp(tokens[2], "show") == 0)) {
3085 snprintf(out, out_size, "\n%s\n",
3086 cmd_pipeline_table_show_help);
3090 if ((strcmp(tokens[0], "pipeline") == 0) &&
3092 (strcmp(tokens[1], "selector") == 0) &&
3093 (strcmp(tokens[2], "group") == 0) &&
3094 (strcmp(tokens[3], "add") == 0)) {
3095 snprintf(out, out_size, "\n%s\n",
3096 cmd_pipeline_selector_group_add_help);
3100 if ((strcmp(tokens[0], "pipeline") == 0) &&
3102 (strcmp(tokens[1], "selector") == 0) &&
3103 (strcmp(tokens[2], "group") == 0) &&
3104 (strcmp(tokens[3], "delete") == 0)) {
3105 snprintf(out, out_size, "\n%s\n",
3106 cmd_pipeline_selector_group_delete_help);
3110 if ((strcmp(tokens[0], "pipeline") == 0) &&
3112 (strcmp(tokens[1], "selector") == 0) &&
3113 (strcmp(tokens[2], "group") == 0) &&
3114 (strcmp(tokens[3], "member") == 0) &&
3115 (strcmp(tokens[4], "add") == 0)) {
3116 snprintf(out, out_size, "\n%s\n",
3117 cmd_pipeline_selector_group_member_add_help);
3121 if ((strcmp(tokens[0], "pipeline") == 0) &&
3123 (strcmp(tokens[1], "selector") == 0) &&
3124 (strcmp(tokens[2], "group") == 0) &&
3125 (strcmp(tokens[3], "member") == 0) &&
3126 (strcmp(tokens[4], "delete") == 0)) {
3127 snprintf(out, out_size, "\n%s\n",
3128 cmd_pipeline_selector_group_member_delete_help);
3132 if ((strcmp(tokens[0], "pipeline") == 0) &&
3134 (strcmp(tokens[1], "selector") == 0) &&
3135 (strcmp(tokens[2], "show") == 0)) {
3136 snprintf(out, out_size, "\n%s\n",
3137 cmd_pipeline_selector_show_help);
3141 if ((strcmp(tokens[0], "pipeline") == 0) &&
3143 (strcmp(tokens[1], "learner") == 0) &&
3144 (strcmp(tokens[2], "default") == 0)) {
3145 snprintf(out, out_size, "\n%s\n",
3146 cmd_pipeline_learner_default_help);
3150 if ((strcmp(tokens[0], "pipeline") == 0) &&
3152 (strcmp(tokens[1], "commit") == 0)) {
3153 snprintf(out, out_size, "\n%s\n",
3154 cmd_pipeline_commit_help);
3158 if ((strcmp(tokens[0], "pipeline") == 0) &&
3160 (strcmp(tokens[1], "abort") == 0)) {
3161 snprintf(out, out_size, "\n%s\n",
3162 cmd_pipeline_abort_help);
3166 if ((strcmp(tokens[0], "pipeline") == 0) &&
3167 (n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
3168 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
3172 if ((strcmp(tokens[0], "pipeline") == 0) &&
3173 (n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
3174 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
3178 if (!strcmp(tokens[0], "pipeline") &&
3179 (n_tokens == 4) && !strcmp(tokens[1], "meter")
3180 && !strcmp(tokens[2], "profile")
3181 && !strcmp(tokens[3], "add")) {
3182 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
3186 if (!strcmp(tokens[0], "pipeline") &&
3187 (n_tokens == 4) && !strcmp(tokens[1], "meter")
3188 && !strcmp(tokens[2], "profile")
3189 && !strcmp(tokens[3], "delete")) {
3190 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
3194 if (!strcmp(tokens[0], "pipeline") &&
3195 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3196 && !strcmp(tokens[2], "reset")) {
3197 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3201 if (!strcmp(tokens[0], "pipeline") &&
3202 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3203 && !strcmp(tokens[2], "set")) {
3204 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3208 if (!strcmp(tokens[0], "pipeline") &&
3209 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3210 && !strcmp(tokens[2], "stats")) {
3211 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3215 if ((strcmp(tokens[0], "pipeline") == 0) &&
3216 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
3217 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
3221 if (!strcmp(tokens[0], "pipeline") &&
3222 (n_tokens == 2) && !strcmp(tokens[1], "mirror")) {
3223 snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_help);
3227 if (!strcmp(tokens[0], "pipeline") &&
3228 (n_tokens == 3) && !strcmp(tokens[1], "mirror")
3229 && !strcmp(tokens[2], "session")) {
3230 snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
3234 if ((n_tokens == 3) &&
3235 (strcmp(tokens[0], "thread") == 0) &&
3236 (strcmp(tokens[1], "pipeline") == 0)) {
3237 if (strcmp(tokens[2], "enable") == 0) {
3238 snprintf(out, out_size, "\n%s\n",
3239 cmd_thread_pipeline_enable_help);
3243 if (strcmp(tokens[2], "disable") == 0) {
3244 snprintf(out, out_size, "\n%s\n",
3245 cmd_thread_pipeline_disable_help);
3250 snprintf(out, out_size, "Invalid command\n");
3254 cli_process(char *in, char *out, size_t out_size, void *obj)
3256 char *tokens[CMD_MAX_TOKENS];
3257 uint32_t n_tokens = RTE_DIM(tokens);
3263 status = parse_tokenize_string(in, tokens, &n_tokens);
3265 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
3272 if (strcmp(tokens[0], "help") == 0) {
3273 cmd_help(tokens, n_tokens, out, out_size, obj);
3277 if (strcmp(tokens[0], "mempool") == 0) {
3278 cmd_mempool(tokens, n_tokens, out, out_size, obj);
3282 if (strcmp(tokens[0], "link") == 0) {
3283 if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3284 cmd_link_show(tokens, n_tokens, out, out_size, obj);
3288 cmd_link(tokens, n_tokens, out, out_size, obj);
3292 if (strcmp(tokens[0], "ring") == 0) {
3293 cmd_ring(tokens, n_tokens, out, out_size, obj);
3297 if (strcmp(tokens[0], "tap") == 0) {
3298 cmd_tap(tokens, n_tokens, out, out_size, obj);
3302 if (strcmp(tokens[0], "pipeline") == 0) {
3303 if ((n_tokens >= 3) &&
3304 (strcmp(tokens[2], "create") == 0)) {
3305 cmd_pipeline_create(tokens, n_tokens, out, out_size,
3310 if ((n_tokens >= 4) &&
3311 (strcmp(tokens[2], "port") == 0) &&
3312 (strcmp(tokens[3], "in") == 0)) {
3313 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
3318 if ((n_tokens >= 4) &&
3319 (strcmp(tokens[2], "port") == 0) &&
3320 (strcmp(tokens[3], "out") == 0)) {
3321 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
3326 if ((n_tokens >= 3) &&
3327 (strcmp(tokens[2], "build") == 0)) {
3328 cmd_pipeline_build(tokens, n_tokens, out, out_size,
3333 if ((n_tokens >= 5) &&
3334 (strcmp(tokens[2], "table") == 0) &&
3335 (strcmp(tokens[4], "add") == 0)) {
3336 cmd_pipeline_table_add(tokens, n_tokens, out,
3341 if ((n_tokens >= 5) &&
3342 (strcmp(tokens[2], "table") == 0) &&
3343 (strcmp(tokens[4], "delete") == 0)) {
3344 cmd_pipeline_table_delete(tokens, n_tokens, out,
3349 if ((n_tokens >= 5) &&
3350 (strcmp(tokens[2], "table") == 0) &&
3351 (strcmp(tokens[4], "default") == 0)) {
3352 cmd_pipeline_table_default(tokens, n_tokens, out,
3357 if ((n_tokens >= 5) &&
3358 (strcmp(tokens[2], "table") == 0) &&
3359 (strcmp(tokens[4], "show") == 0)) {
3360 cmd_pipeline_table_show(tokens, n_tokens, out,
3365 if ((n_tokens >= 6) &&
3366 (strcmp(tokens[2], "selector") == 0) &&
3367 (strcmp(tokens[4], "group") == 0) &&
3368 (strcmp(tokens[5], "add") == 0)) {
3369 cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3374 if ((n_tokens >= 6) &&
3375 (strcmp(tokens[2], "selector") == 0) &&
3376 (strcmp(tokens[4], "group") == 0) &&
3377 (strcmp(tokens[5], "delete") == 0)) {
3378 cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3383 if ((n_tokens >= 7) &&
3384 (strcmp(tokens[2], "selector") == 0) &&
3385 (strcmp(tokens[4], "group") == 0) &&
3386 (strcmp(tokens[5], "member") == 0) &&
3387 (strcmp(tokens[6], "add") == 0)) {
3388 cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3393 if ((n_tokens >= 7) &&
3394 (strcmp(tokens[2], "selector") == 0) &&
3395 (strcmp(tokens[4], "group") == 0) &&
3396 (strcmp(tokens[5], "member") == 0) &&
3397 (strcmp(tokens[6], "delete") == 0)) {
3398 cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3403 if ((n_tokens >= 5) &&
3404 (strcmp(tokens[2], "selector") == 0) &&
3405 (strcmp(tokens[4], "show") == 0)) {
3406 cmd_pipeline_selector_show(tokens, n_tokens, out,
3411 if ((n_tokens >= 5) &&
3412 (strcmp(tokens[2], "learner") == 0) &&
3413 (strcmp(tokens[4], "default") == 0)) {
3414 cmd_pipeline_learner_default(tokens, n_tokens, out,
3419 if ((n_tokens >= 3) &&
3420 (strcmp(tokens[2], "commit") == 0)) {
3421 cmd_pipeline_commit(tokens, n_tokens, out,
3426 if ((n_tokens >= 3) &&
3427 (strcmp(tokens[2], "abort") == 0)) {
3428 cmd_pipeline_abort(tokens, n_tokens, out,
3433 if ((n_tokens >= 3) &&
3434 (strcmp(tokens[2], "regrd") == 0)) {
3435 cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
3439 if ((n_tokens >= 3) &&
3440 (strcmp(tokens[2], "regwr") == 0)) {
3441 cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
3445 if ((n_tokens >= 6) &&
3446 (strcmp(tokens[2], "meter") == 0) &&
3447 (strcmp(tokens[3], "profile") == 0) &&
3448 (strcmp(tokens[5], "add") == 0)) {
3449 cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3453 if ((n_tokens >= 6) &&
3454 (strcmp(tokens[2], "meter") == 0) &&
3455 (strcmp(tokens[3], "profile") == 0) &&
3456 (strcmp(tokens[5], "delete") == 0)) {
3457 cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3461 if ((n_tokens >= 9) &&
3462 (strcmp(tokens[2], "meter") == 0) &&
3463 (strcmp(tokens[8], "reset") == 0)) {
3464 cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3468 if ((n_tokens >= 9) &&
3469 (strcmp(tokens[2], "meter") == 0) &&
3470 (strcmp(tokens[8], "set") == 0)) {
3471 cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3475 if ((n_tokens >= 9) &&
3476 (strcmp(tokens[2], "meter") == 0) &&
3477 (strcmp(tokens[8], "stats") == 0)) {
3478 cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3482 if ((n_tokens >= 3) &&
3483 (strcmp(tokens[2], "stats") == 0)) {
3484 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
3489 if ((n_tokens >= 4) &&
3490 (strcmp(tokens[2], "mirror") == 0) &&
3491 (strcmp(tokens[3], "slots") == 0)) {
3492 cmd_pipeline_mirror(tokens, n_tokens, out, out_size, obj);
3496 if ((n_tokens >= 4) &&
3497 (strcmp(tokens[2], "mirror") == 0) &&
3498 (strcmp(tokens[3], "session") == 0)) {
3499 cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
3504 if (strcmp(tokens[0], "thread") == 0) {
3505 if ((n_tokens >= 5) &&
3506 (strcmp(tokens[4], "enable") == 0)) {
3507 cmd_thread_pipeline_enable(tokens, n_tokens,
3508 out, out_size, obj);
3512 if ((n_tokens >= 5) &&
3513 (strcmp(tokens[4], "disable") == 0)) {
3514 cmd_thread_pipeline_disable(tokens, n_tokens,
3515 out, out_size, obj);
3520 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
3524 cli_script_process(const char *file_name,
3525 size_t msg_in_len_max,
3526 size_t msg_out_len_max,
3529 char *msg_in = NULL, *msg_out = NULL;
3532 /* Check input arguments */
3533 if ((file_name == NULL) ||
3534 (strlen(file_name) == 0) ||
3535 (msg_in_len_max == 0) ||
3536 (msg_out_len_max == 0))
3539 msg_in = malloc(msg_in_len_max + 1);
3540 msg_out = malloc(msg_out_len_max + 1);
3541 if ((msg_in == NULL) ||
3542 (msg_out == NULL)) {
3548 /* Open input file */
3549 f = fopen(file_name, "r");
3558 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
3561 printf("%s", msg_in);
3569 if (strlen(msg_out))
3570 printf("%s", msg_out);