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>\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 + 3) {
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];
703 status = rte_swx_pipeline_port_in_config(p->p,
707 } else if (strcmp(tokens[t0], "tap") == 0) {
708 struct rte_swx_port_fd_reader_params params;
712 if (n_tokens < t0 + 8) {
713 snprintf(out, out_size, MSG_ARG_MISMATCH,
714 "pipeline port in tap");
718 tap = tap_find(obj, tokens[t0 + 1]);
720 snprintf(out, out_size, MSG_ARG_INVALID,
726 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
727 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
732 mp = mempool_find(obj, tokens[t0 + 3]);
734 snprintf(out, out_size, MSG_ARG_INVALID,
738 params.mempool = mp->m;
740 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
741 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
746 if (parser_read_uint32(¶ms.mtu, tokens[t0 + 5]) != 0) {
747 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
751 if (strcmp(tokens[t0 + 6], "bsz") != 0) {
752 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
756 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 7])) {
757 snprintf(out, out_size, MSG_ARG_INVALID,
764 status = rte_swx_pipeline_port_in_config(p->p,
770 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
775 snprintf(out, out_size, "port in error.");
779 if (n_tokens != t0) {
780 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
785 static const char cmd_pipeline_port_out_help[] =
786 "pipeline <pipeline_name> port out <port_id>\n"
787 " link <link_name> txq <txq_id> bsz <burst_size>\n"
788 " ring <ring_name> bsz <burst_size>\n"
789 " | sink <file_name> | none\n"
790 " | tap <tap_name> bsz <burst_size>\n";
793 cmd_pipeline_port_out(char **tokens,
801 uint32_t port_id = 0, t0;
804 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
808 p = pipeline_find(obj, tokens[1]);
810 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
814 if (strcmp(tokens[2], "port") != 0) {
815 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
819 if (strcmp(tokens[3], "out") != 0) {
820 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
824 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
825 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
831 if (strcmp(tokens[t0], "link") == 0) {
832 struct rte_swx_port_ethdev_writer_params params;
835 if (n_tokens < t0 + 6) {
836 snprintf(out, out_size, MSG_ARG_MISMATCH,
837 "pipeline port out link");
841 link = link_find(obj, tokens[t0 + 1]);
843 snprintf(out, out_size, MSG_ARG_INVALID,
847 params.dev_name = link->dev_name;
849 if (strcmp(tokens[t0 + 2], "txq") != 0) {
850 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
854 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
855 snprintf(out, out_size, MSG_ARG_INVALID,
860 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
861 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
865 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
866 snprintf(out, out_size, MSG_ARG_INVALID,
873 status = rte_swx_pipeline_port_out_config(p->p,
877 } else if (strcmp(tokens[t0], "ring") == 0) {
878 struct rte_swx_port_ring_writer_params params;
881 if (n_tokens < t0 + 4) {
882 snprintf(out, out_size, MSG_ARG_MISMATCH,
883 "pipeline port out link");
887 ring = ring_find(obj, tokens[t0 + 1]);
889 snprintf(out, out_size, MSG_ARG_INVALID,
893 params.name = ring->name;
895 if (strcmp(tokens[t0 + 2], "bsz") != 0) {
896 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
900 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 3])) {
901 snprintf(out, out_size, MSG_ARG_INVALID,
908 status = rte_swx_pipeline_port_out_config(p->p,
912 } else if (strcmp(tokens[t0], "sink") == 0) {
913 struct rte_swx_port_sink_params params;
915 params.file_name = strcmp(tokens[t0 + 1], "none") ?
916 tokens[t0 + 1] : NULL;
920 status = rte_swx_pipeline_port_out_config(p->p,
924 } else if (strcmp(tokens[t0], "tap") == 0) {
925 struct rte_swx_port_fd_writer_params params;
928 if (n_tokens < t0 + 4) {
929 snprintf(out, out_size, MSG_ARG_MISMATCH,
930 "pipeline port out tap");
934 tap = tap_find(obj, tokens[t0 + 1]);
936 snprintf(out, out_size, MSG_ARG_INVALID,
942 if (strcmp(tokens[t0 + 2], "bsz") != 0) {
943 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
947 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 3])) {
948 snprintf(out, out_size, MSG_ARG_INVALID,
955 status = rte_swx_pipeline_port_out_config(p->p,
960 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
965 snprintf(out, out_size, "port out error.");
969 if (n_tokens != t0) {
970 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
975 static const char cmd_pipeline_build_help[] =
976 "pipeline <pipeline_name> build <spec_file>\n";
979 cmd_pipeline_build(char **tokens,
985 struct pipeline *p = NULL;
992 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
996 p = pipeline_find(obj, tokens[1]);
998 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1002 spec = fopen(tokens[3], "r");
1004 snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
1008 status = rte_swx_pipeline_build_from_spec(p->p,
1014 snprintf(out, out_size, "Error %d at line %u: %s\n.",
1015 status, err_line, err_msg);
1019 p->ctl = rte_swx_ctl_pipeline_create(p->p);
1021 snprintf(out, out_size, "Pipeline control create failed.");
1022 rte_swx_pipeline_free(p->p);
1028 table_entry_free(struct rte_swx_table_entry *entry)
1034 free(entry->key_mask);
1035 free(entry->action_data);
1039 #ifndef MAX_LINE_SIZE
1040 #define MAX_LINE_SIZE 2048
1044 pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
1045 const char *table_name,
1047 uint32_t *file_line_number)
1050 uint32_t line_id = 0;
1053 /* Buffer allocation. */
1054 line = malloc(MAX_LINE_SIZE);
1059 for (line_id = 1; ; line_id++) {
1060 struct rte_swx_table_entry *entry;
1061 int is_blank_or_comment;
1063 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1066 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1069 &is_blank_or_comment);
1071 if (is_blank_or_comment)
1078 status = rte_swx_ctl_pipeline_table_entry_add(p,
1081 table_entry_free(entry);
1088 *file_line_number = line_id;
1092 static const char cmd_pipeline_table_add_help[] =
1093 "pipeline <pipeline_name> table <table_name> add <file_name>\n";
1096 cmd_pipeline_table_add(char **tokens,
1103 char *pipeline_name, *table_name, *file_name;
1105 uint32_t file_line_number = 0;
1108 if (n_tokens != 6) {
1109 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1113 pipeline_name = tokens[1];
1114 p = pipeline_find(obj, pipeline_name);
1115 if (!p || !p->ctl) {
1116 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1120 table_name = tokens[3];
1122 file_name = tokens[5];
1123 file = fopen(file_name, "r");
1125 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1129 status = pipeline_table_entries_add(p->ctl,
1134 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1142 pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
1143 const char *table_name,
1145 uint32_t *file_line_number)
1148 uint32_t line_id = 0;
1151 /* Buffer allocation. */
1152 line = malloc(MAX_LINE_SIZE);
1157 for (line_id = 1; ; line_id++) {
1158 struct rte_swx_table_entry *entry;
1159 int is_blank_or_comment;
1161 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1164 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1167 &is_blank_or_comment);
1169 if (is_blank_or_comment)
1176 status = rte_swx_ctl_pipeline_table_entry_delete(p,
1179 table_entry_free(entry);
1185 *file_line_number = line_id;
1190 static const char cmd_pipeline_table_delete_help[] =
1191 "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
1194 cmd_pipeline_table_delete(char **tokens,
1201 char *pipeline_name, *table_name, *file_name;
1203 uint32_t file_line_number = 0;
1206 if (n_tokens != 6) {
1207 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1211 pipeline_name = tokens[1];
1212 p = pipeline_find(obj, pipeline_name);
1213 if (!p || !p->ctl) {
1214 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1218 table_name = tokens[3];
1220 file_name = tokens[5];
1221 file = fopen(file_name, "r");
1223 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1227 status = pipeline_table_entries_delete(p->ctl,
1232 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1240 pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
1241 const char *table_name,
1243 uint32_t *file_line_number)
1246 uint32_t line_id = 0;
1249 /* Buffer allocation. */
1250 line = malloc(MAX_LINE_SIZE);
1255 for (line_id = 1; ; line_id++) {
1256 struct rte_swx_table_entry *entry;
1257 int is_blank_or_comment;
1259 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1262 entry = rte_swx_ctl_pipeline_table_entry_read(p,
1265 &is_blank_or_comment);
1267 if (is_blank_or_comment)
1274 status = rte_swx_ctl_pipeline_table_default_entry_add(p,
1277 table_entry_free(entry);
1283 *file_line_number = line_id;
1288 static const char cmd_pipeline_table_default_help[] =
1289 "pipeline <pipeline_name> table <table_name> default <file_name>\n";
1292 cmd_pipeline_table_default(char **tokens,
1299 char *pipeline_name, *table_name, *file_name;
1301 uint32_t file_line_number = 0;
1304 if (n_tokens != 6) {
1305 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1309 pipeline_name = tokens[1];
1310 p = pipeline_find(obj, pipeline_name);
1311 if (!p || !p->ctl) {
1312 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1316 table_name = tokens[3];
1318 file_name = tokens[5];
1319 file = fopen(file_name, "r");
1321 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1325 status = pipeline_table_default_entry_add(p->ctl,
1330 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1337 static const char cmd_pipeline_table_show_help[] =
1338 "pipeline <pipeline_name> table <table_name> show\n";
1341 cmd_pipeline_table_show(char **tokens,
1348 char *pipeline_name, *table_name;
1351 if (n_tokens != 5) {
1352 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1356 pipeline_name = tokens[1];
1357 p = pipeline_find(obj, pipeline_name);
1358 if (!p || !p->ctl) {
1359 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1363 table_name = tokens[3];
1364 status = rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
1366 snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1369 static const char cmd_pipeline_selector_group_add_help[] =
1370 "pipeline <pipeline_name> selector <selector_name> group add\n";
1373 cmd_pipeline_selector_group_add(char **tokens,
1380 char *pipeline_name, *selector_name;
1384 if (n_tokens != 6) {
1385 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1389 pipeline_name = tokens[1];
1390 p = pipeline_find(obj, pipeline_name);
1391 if (!p || !p->ctl) {
1392 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1396 if (strcmp(tokens[2], "selector") != 0) {
1397 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1401 selector_name = tokens[3];
1403 if (strcmp(tokens[4], "group") ||
1404 strcmp(tokens[5], "add")) {
1405 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1409 status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
1413 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1415 snprintf(out, out_size, "Group ID: %u\n", group_id);
1418 static const char cmd_pipeline_selector_group_delete_help[] =
1419 "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1422 cmd_pipeline_selector_group_delete(char **tokens,
1429 char *pipeline_name, *selector_name;
1433 if (n_tokens != 7) {
1434 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1438 pipeline_name = tokens[1];
1439 p = pipeline_find(obj, pipeline_name);
1440 if (!p || !p->ctl) {
1441 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1445 if (strcmp(tokens[2], "selector") != 0) {
1446 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1450 selector_name = tokens[3];
1452 if (strcmp(tokens[4], "group") ||
1453 strcmp(tokens[5], "delete")) {
1454 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1458 if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1459 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1463 status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
1467 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1470 #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1473 token_is_comment(const char *token)
1475 if ((token[0] == '#') ||
1476 (token[0] == ';') ||
1477 ((token[0] == '/') && (token[1] == '/')))
1478 return 1; /* TRUE. */
1480 return 0; /* FALSE. */
1484 pipeline_selector_group_member_read(const char *string,
1486 uint32_t *member_id,
1488 int *is_blank_or_comment)
1490 char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1491 char *s0 = NULL, *s;
1492 uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1493 int blank_or_comment = 0;
1495 /* Check input arguments. */
1496 if (!string || !string[0])
1499 /* Memory allocation. */
1500 s0 = strdup(string);
1504 /* Parse the string into tokens. */
1508 token = strtok_r(s, " \f\n\r\t\v", &s);
1509 if (!token || token_is_comment(token))
1512 if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1515 token_array[n_tokens] = token;
1520 blank_or_comment = 1;
1524 tokens = token_array;
1527 strcmp(tokens[0], "group") ||
1528 strcmp(tokens[2], "member"))
1534 if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1536 *group_id = group_id_val;
1541 if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1543 *member_id = member_id_val;
1551 if (n_tokens && !strcmp(tokens[0], "weight")) {
1555 if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1557 *weight = weight_val;
1571 if (is_blank_or_comment)
1572 *is_blank_or_comment = blank_or_comment;
1577 pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1578 const char *selector_name,
1580 uint32_t *file_line_number)
1583 uint32_t line_id = 0;
1586 /* Buffer allocation. */
1587 line = malloc(MAX_LINE_SIZE);
1592 for (line_id = 1; ; line_id++) {
1593 uint32_t group_id, member_id, weight;
1594 int is_blank_or_comment;
1596 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1599 status = pipeline_selector_group_member_read(line,
1603 &is_blank_or_comment);
1605 if (is_blank_or_comment)
1611 status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1622 *file_line_number = line_id;
1626 static const char cmd_pipeline_selector_group_member_add_help[] =
1627 "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1630 cmd_pipeline_selector_group_member_add(char **tokens,
1637 char *pipeline_name, *selector_name, *file_name;
1639 uint32_t file_line_number = 0;
1642 if (n_tokens != 8) {
1643 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1647 pipeline_name = tokens[1];
1648 p = pipeline_find(obj, pipeline_name);
1649 if (!p || !p->ctl) {
1650 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1654 if (strcmp(tokens[2], "selector") != 0) {
1655 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1659 selector_name = tokens[3];
1661 if (strcmp(tokens[4], "group") ||
1662 strcmp(tokens[5], "member") ||
1663 strcmp(tokens[6], "add")) {
1664 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1668 file_name = tokens[7];
1669 file = fopen(file_name, "r");
1671 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1675 status = pipeline_selector_group_members_add(p->ctl,
1680 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1688 pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1689 const char *selector_name,
1691 uint32_t *file_line_number)
1694 uint32_t line_id = 0;
1697 /* Buffer allocation. */
1698 line = malloc(MAX_LINE_SIZE);
1703 for (line_id = 1; ; line_id++) {
1704 uint32_t group_id, member_id, weight;
1705 int is_blank_or_comment;
1707 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1710 status = pipeline_selector_group_member_read(line,
1714 &is_blank_or_comment);
1716 if (is_blank_or_comment)
1722 status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1732 *file_line_number = line_id;
1736 static const char cmd_pipeline_selector_group_member_delete_help[] =
1737 "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1740 cmd_pipeline_selector_group_member_delete(char **tokens,
1747 char *pipeline_name, *selector_name, *file_name;
1749 uint32_t file_line_number = 0;
1752 if (n_tokens != 8) {
1753 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1757 pipeline_name = tokens[1];
1758 p = pipeline_find(obj, pipeline_name);
1759 if (!p || !p->ctl) {
1760 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1764 if (strcmp(tokens[2], "selector") != 0) {
1765 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1769 selector_name = tokens[3];
1771 if (strcmp(tokens[4], "group") ||
1772 strcmp(tokens[5], "member") ||
1773 strcmp(tokens[6], "delete")) {
1774 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1778 file_name = tokens[7];
1779 file = fopen(file_name, "r");
1781 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1785 status = pipeline_selector_group_members_delete(p->ctl,
1790 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1797 static const char cmd_pipeline_selector_show_help[] =
1798 "pipeline <pipeline_name> selector <selector_name> show\n";
1801 cmd_pipeline_selector_show(char **tokens,
1808 char *pipeline_name, *selector_name;
1811 if (n_tokens != 5) {
1812 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1816 pipeline_name = tokens[1];
1817 p = pipeline_find(obj, pipeline_name);
1818 if (!p || !p->ctl) {
1819 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1823 selector_name = tokens[3];
1824 status = rte_swx_ctl_pipeline_selector_fprintf(stdout,
1825 p->ctl, selector_name);
1827 snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1831 pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
1832 const char *learner_name,
1834 uint32_t *file_line_number)
1837 uint32_t line_id = 0;
1840 /* Buffer allocation. */
1841 line = malloc(MAX_LINE_SIZE);
1846 for (line_id = 1; ; line_id++) {
1847 struct rte_swx_table_entry *entry;
1848 int is_blank_or_comment;
1850 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1853 entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
1856 &is_blank_or_comment);
1858 if (is_blank_or_comment)
1865 status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
1868 table_entry_free(entry);
1874 *file_line_number = line_id;
1879 static const char cmd_pipeline_learner_default_help[] =
1880 "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
1883 cmd_pipeline_learner_default(char **tokens,
1890 char *pipeline_name, *learner_name, *file_name;
1892 uint32_t file_line_number = 0;
1895 if (n_tokens != 6) {
1896 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1900 pipeline_name = tokens[1];
1901 p = pipeline_find(obj, pipeline_name);
1902 if (!p || !p->ctl) {
1903 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1907 learner_name = tokens[3];
1909 file_name = tokens[5];
1910 file = fopen(file_name, "r");
1912 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1916 status = pipeline_learner_default_entry_add(p->ctl,
1921 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1928 static const char cmd_pipeline_commit_help[] =
1929 "pipeline <pipeline_name> commit\n";
1932 cmd_pipeline_commit(char **tokens,
1939 char *pipeline_name;
1942 if (n_tokens != 3) {
1943 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1947 pipeline_name = tokens[1];
1948 p = pipeline_find(obj, pipeline_name);
1949 if (!p || !p->ctl) {
1950 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1954 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1956 snprintf(out, out_size, "Commit failed. "
1957 "Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1960 static const char cmd_pipeline_abort_help[] =
1961 "pipeline <pipeline_name> abort\n";
1964 cmd_pipeline_abort(char **tokens,
1971 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 rte_swx_ctl_pipeline_abort(p->ctl);
1988 static const char cmd_pipeline_regrd_help[] =
1989 "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
1992 cmd_pipeline_regrd(char **tokens,
2004 if (n_tokens != 5) {
2005 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2009 p = pipeline_find(obj, tokens[1]);
2010 if (!p || !p->ctl) {
2011 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2015 if (strcmp(tokens[2], "regrd")) {
2016 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
2022 if (parser_read_uint32(&idx, tokens[4])) {
2023 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2027 status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
2029 snprintf(out, out_size, "Command failed.\n");
2033 snprintf(out, out_size, "0x%" PRIx64 "\n", value);
2036 static const char cmd_pipeline_regwr_help[] =
2037 "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
2040 cmd_pipeline_regwr(char **tokens,
2052 if (n_tokens != 6) {
2053 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2057 p = pipeline_find(obj, tokens[1]);
2058 if (!p || !p->ctl) {
2059 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2063 if (strcmp(tokens[2], "regwr")) {
2064 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
2070 if (parser_read_uint32(&idx, tokens[4])) {
2071 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2075 if (parser_read_uint64(&value, tokens[5])) {
2076 snprintf(out, out_size, MSG_ARG_INVALID, "value");
2080 status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
2082 snprintf(out, out_size, "Command failed.\n");
2087 static const char cmd_pipeline_meter_profile_add_help[] =
2088 "pipeline <pipeline_name> meter profile <profile_name> add "
2089 "cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
2092 cmd_pipeline_meter_profile_add(char **tokens,
2098 struct rte_meter_trtcm_params params;
2100 const char *profile_name;
2103 if (n_tokens != 14) {
2104 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2108 p = pipeline_find(obj, tokens[1]);
2109 if (!p || !p->ctl) {
2110 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2114 if (strcmp(tokens[2], "meter")) {
2115 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2119 if (strcmp(tokens[3], "profile")) {
2120 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2124 profile_name = tokens[4];
2126 if (strcmp(tokens[5], "add")) {
2127 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2131 if (strcmp(tokens[6], "cir")) {
2132 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2136 if (parser_read_uint64(¶ms.cir, tokens[7])) {
2137 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2141 if (strcmp(tokens[8], "pir")) {
2142 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2146 if (parser_read_uint64(¶ms.pir, tokens[9])) {
2147 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2151 if (strcmp(tokens[10], "cbs")) {
2152 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2156 if (parser_read_uint64(¶ms.cbs, tokens[11])) {
2157 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2161 if (strcmp(tokens[12], "pbs")) {
2162 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2166 if (parser_read_uint64(¶ms.pbs, tokens[13])) {
2167 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2171 status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
2173 snprintf(out, out_size, "Command failed.\n");
2178 static const char cmd_pipeline_meter_profile_delete_help[] =
2179 "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2182 cmd_pipeline_meter_profile_delete(char **tokens,
2189 const char *profile_name;
2192 if (n_tokens != 6) {
2193 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2197 p = pipeline_find(obj, tokens[1]);
2198 if (!p || !p->ctl) {
2199 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2203 if (strcmp(tokens[2], "meter")) {
2204 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2208 if (strcmp(tokens[3], "profile")) {
2209 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2213 profile_name = tokens[4];
2215 if (strcmp(tokens[5], "delete")) {
2216 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2220 status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
2222 snprintf(out, out_size, "Command failed.\n");
2227 static const char cmd_pipeline_meter_reset_help[] =
2228 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2232 cmd_pipeline_meter_reset(char **tokens,
2240 uint32_t idx0 = 0, idx1 = 0;
2242 if (n_tokens != 9) {
2243 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2247 p = pipeline_find(obj, tokens[1]);
2248 if (!p || !p->ctl) {
2249 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2253 if (strcmp(tokens[2], "meter")) {
2254 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2260 if (strcmp(tokens[4], "from")) {
2261 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2265 if (parser_read_uint32(&idx0, tokens[5])) {
2266 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2270 if (strcmp(tokens[6], "to")) {
2271 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2275 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2276 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2280 if (strcmp(tokens[8], "reset")) {
2281 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2285 for ( ; idx0 <= idx1; idx0++) {
2288 status = rte_swx_ctl_meter_reset(p->p, name, idx0);
2290 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2296 static const char cmd_pipeline_meter_set_help[] =
2297 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2298 "set profile <profile_name>\n";
2301 cmd_pipeline_meter_set(char **tokens,
2308 const char *name, *profile_name;
2309 uint32_t idx0 = 0, idx1 = 0;
2311 if (n_tokens != 11) {
2312 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2316 p = pipeline_find(obj, tokens[1]);
2317 if (!p || !p->ctl) {
2318 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2322 if (strcmp(tokens[2], "meter")) {
2323 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2329 if (strcmp(tokens[4], "from")) {
2330 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2334 if (parser_read_uint32(&idx0, tokens[5])) {
2335 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2339 if (strcmp(tokens[6], "to")) {
2340 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2344 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2345 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2349 if (strcmp(tokens[8], "set")) {
2350 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2354 if (strcmp(tokens[9], "profile")) {
2355 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2359 profile_name = tokens[10];
2361 for ( ; idx0 <= idx1; idx0++) {
2364 status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
2366 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2372 static const char cmd_pipeline_meter_stats_help[] =
2373 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2377 cmd_pipeline_meter_stats(char **tokens,
2383 struct rte_swx_ctl_meter_stats stats;
2386 uint32_t idx0 = 0, idx1 = 0;
2388 if (n_tokens != 9) {
2389 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2393 p = pipeline_find(obj, tokens[1]);
2394 if (!p || !p->ctl) {
2395 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2399 if (strcmp(tokens[2], "meter")) {
2400 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2406 if (strcmp(tokens[4], "from")) {
2407 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2411 if (parser_read_uint32(&idx0, tokens[5])) {
2412 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2416 if (strcmp(tokens[6], "to")) {
2417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2421 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2422 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2426 if (strcmp(tokens[8], "stats")) {
2427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2432 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2434 "----------------", "----------------", "----------------",
2435 "----------------", "----------------", "----------------");
2436 out_size -= strlen(out);
2439 snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2441 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2442 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2443 out_size -= strlen(out);
2446 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2448 "----------------", "----------------", "----------------",
2449 "----------------", "----------------", "----------------");
2450 out_size -= strlen(out);
2454 for ( ; idx0 <= idx1; idx0++) {
2457 status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
2459 snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2460 out_size -= strlen(out);
2465 snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2466 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2468 stats.n_pkts[RTE_COLOR_GREEN],
2469 stats.n_pkts[RTE_COLOR_YELLOW],
2470 stats.n_pkts[RTE_COLOR_RED],
2471 stats.n_bytes[RTE_COLOR_GREEN],
2472 stats.n_bytes[RTE_COLOR_YELLOW],
2473 stats.n_bytes[RTE_COLOR_RED]);
2474 out_size -= strlen(out);
2479 static const char cmd_pipeline_stats_help[] =
2480 "pipeline <pipeline_name> stats\n";
2483 cmd_pipeline_stats(char **tokens,
2489 struct rte_swx_ctl_pipeline_info info;
2494 if (n_tokens != 3) {
2495 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2499 p = pipeline_find(obj, tokens[1]);
2500 if (!p || !p->ctl) {
2501 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2505 if (strcmp(tokens[2], "stats")) {
2506 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2510 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
2512 snprintf(out, out_size, "Pipeline info get error.");
2516 snprintf(out, out_size, "Input ports:\n");
2517 out_size -= strlen(out);
2520 for (i = 0; i < info.n_ports_in; i++) {
2521 struct rte_swx_port_in_stats stats;
2523 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
2525 snprintf(out, out_size, "\tPort %u:"
2528 " empty %" PRIu64 "\n",
2529 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
2530 out_size -= strlen(out);
2534 snprintf(out, out_size, "\nOutput ports:\n");
2535 out_size -= strlen(out);
2538 for (i = 0; i < info.n_ports_out; i++) {
2539 struct rte_swx_port_out_stats stats;
2541 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
2543 snprintf(out, out_size, "\tPort %u:"
2545 " bytes %" PRIu64 "\n",
2546 i, stats.n_pkts, stats.n_bytes);
2547 out_size -= strlen(out);
2551 snprintf(out, out_size, "\nTables:\n");
2552 out_size -= strlen(out);
2555 for (i = 0; i < info.n_tables; i++) {
2556 struct rte_swx_ctl_table_info table_info;
2557 uint64_t n_pkts_action[info.n_actions];
2558 struct rte_swx_table_stats stats = {
2561 .n_pkts_action = n_pkts_action,
2565 status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2567 snprintf(out, out_size, "Table info get error.");
2571 status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2573 snprintf(out, out_size, "Table stats read error.");
2577 snprintf(out, out_size, "\tTable %s:\n"
2578 "\t\tHit (packets): %" PRIu64 "\n"
2579 "\t\tMiss (packets): %" PRIu64 "\n",
2583 out_size -= strlen(out);
2586 for (j = 0; j < info.n_actions; j++) {
2587 struct rte_swx_ctl_action_info action_info;
2589 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2591 snprintf(out, out_size, "Action info get error.");
2595 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2597 stats.n_pkts_action[j]);
2598 out_size -= strlen(out);
2603 snprintf(out, out_size, "\nLearner tables:\n");
2604 out_size -= strlen(out);
2607 for (i = 0; i < info.n_learners; i++) {
2608 struct rte_swx_ctl_learner_info learner_info;
2609 uint64_t n_pkts_action[info.n_actions];
2610 struct rte_swx_learner_stats stats = {
2613 .n_pkts_action = n_pkts_action,
2617 status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
2619 snprintf(out, out_size, "Learner table info get error.");
2623 status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
2625 snprintf(out, out_size, "Learner table stats read error.");
2629 snprintf(out, out_size, "\tLearner table %s:\n"
2630 "\t\tHit (packets): %" PRIu64 "\n"
2631 "\t\tMiss (packets): %" PRIu64 "\n"
2632 "\t\tLearn OK (packets): %" PRIu64 "\n"
2633 "\t\tLearn error (packets): %" PRIu64 "\n"
2634 "\t\tForget (packets): %" PRIu64 "\n",
2638 stats.n_pkts_learn_ok,
2639 stats.n_pkts_learn_err,
2640 stats.n_pkts_forget);
2641 out_size -= strlen(out);
2644 for (j = 0; j < info.n_actions; j++) {
2645 struct rte_swx_ctl_action_info action_info;
2647 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2649 snprintf(out, out_size, "Action info get error.");
2653 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2655 stats.n_pkts_action[j]);
2656 out_size -= strlen(out);
2662 static const char cmd_thread_pipeline_enable_help[] =
2663 "thread <thread_id> pipeline <pipeline_name> enable\n";
2666 cmd_thread_pipeline_enable(char **tokens,
2672 char *pipeline_name;
2677 if (n_tokens != 5) {
2678 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2682 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2683 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2687 if (strcmp(tokens[2], "pipeline") != 0) {
2688 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2692 pipeline_name = tokens[3];
2693 p = pipeline_find(obj, pipeline_name);
2694 if (!p || !p->ctl) {
2695 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2699 if (strcmp(tokens[4], "enable") != 0) {
2700 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2704 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
2706 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
2711 static const char cmd_thread_pipeline_disable_help[] =
2712 "thread <thread_id> pipeline <pipeline_name> disable\n";
2715 cmd_thread_pipeline_disable(char **tokens,
2722 char *pipeline_name;
2726 if (n_tokens != 5) {
2727 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2731 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2732 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2736 if (strcmp(tokens[2], "pipeline") != 0) {
2737 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2741 pipeline_name = tokens[3];
2742 p = pipeline_find(obj, pipeline_name);
2743 if (!p || !p->ctl) {
2744 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2748 if (strcmp(tokens[4], "disable") != 0) {
2749 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2753 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
2755 snprintf(out, out_size, MSG_CMD_FAIL,
2756 "thread pipeline disable");
2762 cmd_help(char **tokens,
2766 void *arg __rte_unused)
2771 if (n_tokens == 0) {
2772 snprintf(out, out_size,
2773 "Type 'help <command>' for command details.\n\n"
2774 "List of commands:\n"
2778 "\tpipeline create\n"
2779 "\tpipeline port in\n"
2780 "\tpipeline port out\n"
2781 "\tpipeline build\n"
2782 "\tpipeline table add\n"
2783 "\tpipeline table delete\n"
2784 "\tpipeline table default\n"
2785 "\tpipeline table show\n"
2786 "\tpipeline selector group add\n"
2787 "\tpipeline selector group delete\n"
2788 "\tpipeline selector group member add\n"
2789 "\tpipeline selector group member delete\n"
2790 "\tpipeline selector show\n"
2791 "\tpipeline learner default\n"
2792 "\tpipeline commit\n"
2793 "\tpipeline abort\n"
2794 "\tpipeline regrd\n"
2795 "\tpipeline regwr\n"
2796 "\tpipeline meter profile add\n"
2797 "\tpipeline meter profile delete\n"
2798 "\tpipeline meter reset\n"
2799 "\tpipeline meter set\n"
2800 "\tpipeline meter stats\n"
2801 "\tpipeline stats\n"
2802 "\tthread pipeline enable\n"
2803 "\tthread pipeline disable\n\n");
2807 if (strcmp(tokens[0], "mempool") == 0) {
2808 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
2812 if (strcmp(tokens[0], "link") == 0) {
2813 snprintf(out, out_size, "\n%s\n", cmd_link_help);
2817 if (strcmp(tokens[0], "ring") == 0) {
2818 snprintf(out, out_size, "\n%s\n", cmd_ring_help);
2822 if (strcmp(tokens[0], "tap") == 0) {
2823 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2827 if ((strcmp(tokens[0], "pipeline") == 0) &&
2828 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
2829 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
2833 if ((strcmp(tokens[0], "pipeline") == 0) &&
2834 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
2835 if (strcmp(tokens[2], "in") == 0) {
2836 snprintf(out, out_size, "\n%s\n",
2837 cmd_pipeline_port_in_help);
2841 if (strcmp(tokens[2], "out") == 0) {
2842 snprintf(out, out_size, "\n%s\n",
2843 cmd_pipeline_port_out_help);
2848 if ((strcmp(tokens[0], "pipeline") == 0) &&
2849 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
2850 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
2854 if ((strcmp(tokens[0], "pipeline") == 0) &&
2856 (strcmp(tokens[1], "table") == 0) &&
2857 (strcmp(tokens[2], "add") == 0)) {
2858 snprintf(out, out_size, "\n%s\n",
2859 cmd_pipeline_table_add_help);
2863 if ((strcmp(tokens[0], "pipeline") == 0) &&
2865 (strcmp(tokens[1], "table") == 0) &&
2866 (strcmp(tokens[2], "delete") == 0)) {
2867 snprintf(out, out_size, "\n%s\n",
2868 cmd_pipeline_table_delete_help);
2872 if ((strcmp(tokens[0], "pipeline") == 0) &&
2874 (strcmp(tokens[1], "table") == 0) &&
2875 (strcmp(tokens[2], "default") == 0)) {
2876 snprintf(out, out_size, "\n%s\n",
2877 cmd_pipeline_table_default_help);
2881 if ((strcmp(tokens[0], "pipeline") == 0) &&
2883 (strcmp(tokens[1], "table") == 0) &&
2884 (strcmp(tokens[2], "show") == 0)) {
2885 snprintf(out, out_size, "\n%s\n",
2886 cmd_pipeline_table_show_help);
2890 if ((strcmp(tokens[0], "pipeline") == 0) &&
2892 (strcmp(tokens[1], "selector") == 0) &&
2893 (strcmp(tokens[2], "group") == 0) &&
2894 (strcmp(tokens[3], "add") == 0)) {
2895 snprintf(out, out_size, "\n%s\n",
2896 cmd_pipeline_selector_group_add_help);
2900 if ((strcmp(tokens[0], "pipeline") == 0) &&
2902 (strcmp(tokens[1], "selector") == 0) &&
2903 (strcmp(tokens[2], "group") == 0) &&
2904 (strcmp(tokens[3], "delete") == 0)) {
2905 snprintf(out, out_size, "\n%s\n",
2906 cmd_pipeline_selector_group_delete_help);
2910 if ((strcmp(tokens[0], "pipeline") == 0) &&
2912 (strcmp(tokens[1], "selector") == 0) &&
2913 (strcmp(tokens[2], "group") == 0) &&
2914 (strcmp(tokens[3], "member") == 0) &&
2915 (strcmp(tokens[4], "add") == 0)) {
2916 snprintf(out, out_size, "\n%s\n",
2917 cmd_pipeline_selector_group_member_add_help);
2921 if ((strcmp(tokens[0], "pipeline") == 0) &&
2923 (strcmp(tokens[1], "selector") == 0) &&
2924 (strcmp(tokens[2], "group") == 0) &&
2925 (strcmp(tokens[3], "member") == 0) &&
2926 (strcmp(tokens[4], "delete") == 0)) {
2927 snprintf(out, out_size, "\n%s\n",
2928 cmd_pipeline_selector_group_member_delete_help);
2932 if ((strcmp(tokens[0], "pipeline") == 0) &&
2934 (strcmp(tokens[1], "selector") == 0) &&
2935 (strcmp(tokens[2], "show") == 0)) {
2936 snprintf(out, out_size, "\n%s\n",
2937 cmd_pipeline_selector_show_help);
2941 if ((strcmp(tokens[0], "pipeline") == 0) &&
2943 (strcmp(tokens[1], "learner") == 0) &&
2944 (strcmp(tokens[2], "default") == 0)) {
2945 snprintf(out, out_size, "\n%s\n",
2946 cmd_pipeline_learner_default_help);
2950 if ((strcmp(tokens[0], "pipeline") == 0) &&
2952 (strcmp(tokens[1], "commit") == 0)) {
2953 snprintf(out, out_size, "\n%s\n",
2954 cmd_pipeline_commit_help);
2958 if ((strcmp(tokens[0], "pipeline") == 0) &&
2960 (strcmp(tokens[1], "abort") == 0)) {
2961 snprintf(out, out_size, "\n%s\n",
2962 cmd_pipeline_abort_help);
2966 if ((strcmp(tokens[0], "pipeline") == 0) &&
2967 (n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
2968 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
2972 if ((strcmp(tokens[0], "pipeline") == 0) &&
2973 (n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
2974 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
2978 if (!strcmp(tokens[0], "pipeline") &&
2979 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2980 && !strcmp(tokens[2], "profile")
2981 && !strcmp(tokens[3], "add")) {
2982 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2986 if (!strcmp(tokens[0], "pipeline") &&
2987 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2988 && !strcmp(tokens[2], "profile")
2989 && !strcmp(tokens[3], "delete")) {
2990 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2994 if (!strcmp(tokens[0], "pipeline") &&
2995 (n_tokens == 3) && !strcmp(tokens[1], "meter")
2996 && !strcmp(tokens[2], "reset")) {
2997 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3001 if (!strcmp(tokens[0], "pipeline") &&
3002 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3003 && !strcmp(tokens[2], "set")) {
3004 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3008 if (!strcmp(tokens[0], "pipeline") &&
3009 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3010 && !strcmp(tokens[2], "stats")) {
3011 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3015 if ((strcmp(tokens[0], "pipeline") == 0) &&
3016 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
3017 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
3021 if ((n_tokens == 3) &&
3022 (strcmp(tokens[0], "thread") == 0) &&
3023 (strcmp(tokens[1], "pipeline") == 0)) {
3024 if (strcmp(tokens[2], "enable") == 0) {
3025 snprintf(out, out_size, "\n%s\n",
3026 cmd_thread_pipeline_enable_help);
3030 if (strcmp(tokens[2], "disable") == 0) {
3031 snprintf(out, out_size, "\n%s\n",
3032 cmd_thread_pipeline_disable_help);
3037 snprintf(out, out_size, "Invalid command\n");
3041 cli_process(char *in, char *out, size_t out_size, void *obj)
3043 char *tokens[CMD_MAX_TOKENS];
3044 uint32_t n_tokens = RTE_DIM(tokens);
3050 status = parse_tokenize_string(in, tokens, &n_tokens);
3052 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
3059 if (strcmp(tokens[0], "help") == 0) {
3060 cmd_help(tokens, n_tokens, out, out_size, obj);
3064 if (strcmp(tokens[0], "mempool") == 0) {
3065 cmd_mempool(tokens, n_tokens, out, out_size, obj);
3069 if (strcmp(tokens[0], "link") == 0) {
3070 if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3071 cmd_link_show(tokens, n_tokens, out, out_size, obj);
3075 cmd_link(tokens, n_tokens, out, out_size, obj);
3079 if (strcmp(tokens[0], "ring") == 0) {
3080 cmd_ring(tokens, n_tokens, out, out_size, obj);
3084 if (strcmp(tokens[0], "tap") == 0) {
3085 cmd_tap(tokens, n_tokens, out, out_size, obj);
3089 if (strcmp(tokens[0], "pipeline") == 0) {
3090 if ((n_tokens >= 3) &&
3091 (strcmp(tokens[2], "create") == 0)) {
3092 cmd_pipeline_create(tokens, n_tokens, out, out_size,
3097 if ((n_tokens >= 4) &&
3098 (strcmp(tokens[2], "port") == 0) &&
3099 (strcmp(tokens[3], "in") == 0)) {
3100 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
3105 if ((n_tokens >= 4) &&
3106 (strcmp(tokens[2], "port") == 0) &&
3107 (strcmp(tokens[3], "out") == 0)) {
3108 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
3113 if ((n_tokens >= 3) &&
3114 (strcmp(tokens[2], "build") == 0)) {
3115 cmd_pipeline_build(tokens, n_tokens, out, out_size,
3120 if ((n_tokens >= 5) &&
3121 (strcmp(tokens[2], "table") == 0) &&
3122 (strcmp(tokens[4], "add") == 0)) {
3123 cmd_pipeline_table_add(tokens, n_tokens, out,
3128 if ((n_tokens >= 5) &&
3129 (strcmp(tokens[2], "table") == 0) &&
3130 (strcmp(tokens[4], "delete") == 0)) {
3131 cmd_pipeline_table_delete(tokens, n_tokens, out,
3136 if ((n_tokens >= 5) &&
3137 (strcmp(tokens[2], "table") == 0) &&
3138 (strcmp(tokens[4], "default") == 0)) {
3139 cmd_pipeline_table_default(tokens, n_tokens, out,
3144 if ((n_tokens >= 5) &&
3145 (strcmp(tokens[2], "table") == 0) &&
3146 (strcmp(tokens[4], "show") == 0)) {
3147 cmd_pipeline_table_show(tokens, n_tokens, out,
3152 if ((n_tokens >= 6) &&
3153 (strcmp(tokens[2], "selector") == 0) &&
3154 (strcmp(tokens[4], "group") == 0) &&
3155 (strcmp(tokens[5], "add") == 0)) {
3156 cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3161 if ((n_tokens >= 6) &&
3162 (strcmp(tokens[2], "selector") == 0) &&
3163 (strcmp(tokens[4], "group") == 0) &&
3164 (strcmp(tokens[5], "delete") == 0)) {
3165 cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3170 if ((n_tokens >= 7) &&
3171 (strcmp(tokens[2], "selector") == 0) &&
3172 (strcmp(tokens[4], "group") == 0) &&
3173 (strcmp(tokens[5], "member") == 0) &&
3174 (strcmp(tokens[6], "add") == 0)) {
3175 cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3180 if ((n_tokens >= 7) &&
3181 (strcmp(tokens[2], "selector") == 0) &&
3182 (strcmp(tokens[4], "group") == 0) &&
3183 (strcmp(tokens[5], "member") == 0) &&
3184 (strcmp(tokens[6], "delete") == 0)) {
3185 cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3190 if ((n_tokens >= 5) &&
3191 (strcmp(tokens[2], "selector") == 0) &&
3192 (strcmp(tokens[4], "show") == 0)) {
3193 cmd_pipeline_selector_show(tokens, n_tokens, out,
3198 if ((n_tokens >= 5) &&
3199 (strcmp(tokens[2], "learner") == 0) &&
3200 (strcmp(tokens[4], "default") == 0)) {
3201 cmd_pipeline_learner_default(tokens, n_tokens, out,
3206 if ((n_tokens >= 3) &&
3207 (strcmp(tokens[2], "commit") == 0)) {
3208 cmd_pipeline_commit(tokens, n_tokens, out,
3213 if ((n_tokens >= 3) &&
3214 (strcmp(tokens[2], "abort") == 0)) {
3215 cmd_pipeline_abort(tokens, n_tokens, out,
3220 if ((n_tokens >= 3) &&
3221 (strcmp(tokens[2], "regrd") == 0)) {
3222 cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
3226 if ((n_tokens >= 3) &&
3227 (strcmp(tokens[2], "regwr") == 0)) {
3228 cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
3232 if ((n_tokens >= 6) &&
3233 (strcmp(tokens[2], "meter") == 0) &&
3234 (strcmp(tokens[3], "profile") == 0) &&
3235 (strcmp(tokens[5], "add") == 0)) {
3236 cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3240 if ((n_tokens >= 6) &&
3241 (strcmp(tokens[2], "meter") == 0) &&
3242 (strcmp(tokens[3], "profile") == 0) &&
3243 (strcmp(tokens[5], "delete") == 0)) {
3244 cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3248 if ((n_tokens >= 9) &&
3249 (strcmp(tokens[2], "meter") == 0) &&
3250 (strcmp(tokens[8], "reset") == 0)) {
3251 cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3255 if ((n_tokens >= 9) &&
3256 (strcmp(tokens[2], "meter") == 0) &&
3257 (strcmp(tokens[8], "set") == 0)) {
3258 cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3262 if ((n_tokens >= 9) &&
3263 (strcmp(tokens[2], "meter") == 0) &&
3264 (strcmp(tokens[8], "stats") == 0)) {
3265 cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3269 if ((n_tokens >= 3) &&
3270 (strcmp(tokens[2], "stats") == 0)) {
3271 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
3277 if (strcmp(tokens[0], "thread") == 0) {
3278 if ((n_tokens >= 5) &&
3279 (strcmp(tokens[4], "enable") == 0)) {
3280 cmd_thread_pipeline_enable(tokens, n_tokens,
3281 out, out_size, obj);
3285 if ((n_tokens >= 5) &&
3286 (strcmp(tokens[4], "disable") == 0)) {
3287 cmd_thread_pipeline_disable(tokens, n_tokens,
3288 out, out_size, obj);
3293 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
3297 cli_script_process(const char *file_name,
3298 size_t msg_in_len_max,
3299 size_t msg_out_len_max,
3302 char *msg_in = NULL, *msg_out = NULL;
3305 /* Check input arguments */
3306 if ((file_name == NULL) ||
3307 (strlen(file_name) == 0) ||
3308 (msg_in_len_max == 0) ||
3309 (msg_out_len_max == 0))
3312 msg_in = malloc(msg_in_len_max + 1);
3313 msg_out = malloc(msg_out_len_max + 1);
3314 if ((msg_in == NULL) ||
3315 (msg_out == NULL)) {
3321 /* Open input file */
3322 f = fopen(file_name, "r");
3331 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
3334 printf("%s", msg_in);
3342 if (strlen(msg_out))
3343 printf("%s", msg_out);