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\n";
1352 cmd_pipeline_table_show(char **tokens,
1359 char *pipeline_name, *table_name;
1362 if (n_tokens != 5) {
1363 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1367 pipeline_name = tokens[1];
1368 p = pipeline_find(obj, pipeline_name);
1369 if (!p || !p->ctl) {
1370 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1374 table_name = tokens[3];
1375 status = rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
1377 snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1380 static const char cmd_pipeline_selector_group_add_help[] =
1381 "pipeline <pipeline_name> selector <selector_name> group add\n";
1384 cmd_pipeline_selector_group_add(char **tokens,
1391 char *pipeline_name, *selector_name;
1395 if (n_tokens != 6) {
1396 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1400 pipeline_name = tokens[1];
1401 p = pipeline_find(obj, pipeline_name);
1402 if (!p || !p->ctl) {
1403 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1407 if (strcmp(tokens[2], "selector") != 0) {
1408 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1412 selector_name = tokens[3];
1414 if (strcmp(tokens[4], "group") ||
1415 strcmp(tokens[5], "add")) {
1416 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1420 status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
1424 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1426 snprintf(out, out_size, "Group ID: %u\n", group_id);
1429 static const char cmd_pipeline_selector_group_delete_help[] =
1430 "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1433 cmd_pipeline_selector_group_delete(char **tokens,
1440 char *pipeline_name, *selector_name;
1444 if (n_tokens != 7) {
1445 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1449 pipeline_name = tokens[1];
1450 p = pipeline_find(obj, pipeline_name);
1451 if (!p || !p->ctl) {
1452 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1456 if (strcmp(tokens[2], "selector") != 0) {
1457 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1461 selector_name = tokens[3];
1463 if (strcmp(tokens[4], "group") ||
1464 strcmp(tokens[5], "delete")) {
1465 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1469 if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1470 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1474 status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
1478 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1481 #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1484 token_is_comment(const char *token)
1486 if ((token[0] == '#') ||
1487 (token[0] == ';') ||
1488 ((token[0] == '/') && (token[1] == '/')))
1489 return 1; /* TRUE. */
1491 return 0; /* FALSE. */
1495 pipeline_selector_group_member_read(const char *string,
1497 uint32_t *member_id,
1499 int *is_blank_or_comment)
1501 char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1502 char *s0 = NULL, *s;
1503 uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1504 int blank_or_comment = 0;
1506 /* Check input arguments. */
1507 if (!string || !string[0])
1510 /* Memory allocation. */
1511 s0 = strdup(string);
1515 /* Parse the string into tokens. */
1519 token = strtok_r(s, " \f\n\r\t\v", &s);
1520 if (!token || token_is_comment(token))
1523 if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1526 token_array[n_tokens] = token;
1531 blank_or_comment = 1;
1535 tokens = token_array;
1538 strcmp(tokens[0], "group") ||
1539 strcmp(tokens[2], "member"))
1545 if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1547 *group_id = group_id_val;
1552 if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1554 *member_id = member_id_val;
1562 if (n_tokens && !strcmp(tokens[0], "weight")) {
1566 if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1568 *weight = weight_val;
1582 if (is_blank_or_comment)
1583 *is_blank_or_comment = blank_or_comment;
1588 pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1589 const char *selector_name,
1591 uint32_t *file_line_number)
1594 uint32_t line_id = 0;
1597 /* Buffer allocation. */
1598 line = malloc(MAX_LINE_SIZE);
1603 for (line_id = 1; ; line_id++) {
1604 uint32_t group_id, member_id, weight;
1605 int is_blank_or_comment;
1607 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1610 status = pipeline_selector_group_member_read(line,
1614 &is_blank_or_comment);
1616 if (is_blank_or_comment)
1622 status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1633 *file_line_number = line_id;
1637 static const char cmd_pipeline_selector_group_member_add_help[] =
1638 "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1641 cmd_pipeline_selector_group_member_add(char **tokens,
1648 char *pipeline_name, *selector_name, *file_name;
1650 uint32_t file_line_number = 0;
1653 if (n_tokens != 8) {
1654 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1658 pipeline_name = tokens[1];
1659 p = pipeline_find(obj, pipeline_name);
1660 if (!p || !p->ctl) {
1661 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1665 if (strcmp(tokens[2], "selector") != 0) {
1666 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1670 selector_name = tokens[3];
1672 if (strcmp(tokens[4], "group") ||
1673 strcmp(tokens[5], "member") ||
1674 strcmp(tokens[6], "add")) {
1675 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1679 file_name = tokens[7];
1680 file = fopen(file_name, "r");
1682 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1686 status = pipeline_selector_group_members_add(p->ctl,
1691 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1699 pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1700 const char *selector_name,
1702 uint32_t *file_line_number)
1705 uint32_t line_id = 0;
1708 /* Buffer allocation. */
1709 line = malloc(MAX_LINE_SIZE);
1714 for (line_id = 1; ; line_id++) {
1715 uint32_t group_id, member_id, weight;
1716 int is_blank_or_comment;
1718 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1721 status = pipeline_selector_group_member_read(line,
1725 &is_blank_or_comment);
1727 if (is_blank_or_comment)
1733 status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1743 *file_line_number = line_id;
1747 static const char cmd_pipeline_selector_group_member_delete_help[] =
1748 "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1751 cmd_pipeline_selector_group_member_delete(char **tokens,
1758 char *pipeline_name, *selector_name, *file_name;
1760 uint32_t file_line_number = 0;
1763 if (n_tokens != 8) {
1764 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1768 pipeline_name = tokens[1];
1769 p = pipeline_find(obj, pipeline_name);
1770 if (!p || !p->ctl) {
1771 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1775 if (strcmp(tokens[2], "selector") != 0) {
1776 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1780 selector_name = tokens[3];
1782 if (strcmp(tokens[4], "group") ||
1783 strcmp(tokens[5], "member") ||
1784 strcmp(tokens[6], "delete")) {
1785 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1789 file_name = tokens[7];
1790 file = fopen(file_name, "r");
1792 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1796 status = pipeline_selector_group_members_delete(p->ctl,
1801 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1808 static const char cmd_pipeline_selector_show_help[] =
1809 "pipeline <pipeline_name> selector <selector_name> show\n";
1812 cmd_pipeline_selector_show(char **tokens,
1819 char *pipeline_name, *selector_name;
1822 if (n_tokens != 5) {
1823 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1827 pipeline_name = tokens[1];
1828 p = pipeline_find(obj, pipeline_name);
1829 if (!p || !p->ctl) {
1830 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1834 selector_name = tokens[3];
1835 status = rte_swx_ctl_pipeline_selector_fprintf(stdout,
1836 p->ctl, selector_name);
1838 snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1842 pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
1843 const char *learner_name,
1845 uint32_t *file_line_number)
1848 uint32_t line_id = 0;
1851 /* Buffer allocation. */
1852 line = malloc(MAX_LINE_SIZE);
1857 for (line_id = 1; ; line_id++) {
1858 struct rte_swx_table_entry *entry;
1859 int is_blank_or_comment;
1861 if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1864 entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
1867 &is_blank_or_comment);
1869 if (is_blank_or_comment)
1876 status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
1879 table_entry_free(entry);
1885 *file_line_number = line_id;
1890 static const char cmd_pipeline_learner_default_help[] =
1891 "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
1894 cmd_pipeline_learner_default(char **tokens,
1901 char *pipeline_name, *learner_name, *file_name;
1903 uint32_t file_line_number = 0;
1906 if (n_tokens != 6) {
1907 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1911 pipeline_name = tokens[1];
1912 p = pipeline_find(obj, pipeline_name);
1913 if (!p || !p->ctl) {
1914 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1918 learner_name = tokens[3];
1920 file_name = tokens[5];
1921 file = fopen(file_name, "r");
1923 snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1927 status = pipeline_learner_default_entry_add(p->ctl,
1932 snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1939 static const char cmd_pipeline_commit_help[] =
1940 "pipeline <pipeline_name> commit\n";
1943 cmd_pipeline_commit(char **tokens,
1950 char *pipeline_name;
1953 if (n_tokens != 3) {
1954 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1958 pipeline_name = tokens[1];
1959 p = pipeline_find(obj, pipeline_name);
1960 if (!p || !p->ctl) {
1961 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1965 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1967 snprintf(out, out_size, "Commit failed. "
1968 "Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1971 static const char cmd_pipeline_abort_help[] =
1972 "pipeline <pipeline_name> abort\n";
1975 cmd_pipeline_abort(char **tokens,
1982 char *pipeline_name;
1984 if (n_tokens != 3) {
1985 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1989 pipeline_name = tokens[1];
1990 p = pipeline_find(obj, pipeline_name);
1991 if (!p || !p->ctl) {
1992 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1996 rte_swx_ctl_pipeline_abort(p->ctl);
1999 static const char cmd_pipeline_regrd_help[] =
2000 "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
2003 cmd_pipeline_regrd(char **tokens,
2015 if (n_tokens != 5) {
2016 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2020 p = pipeline_find(obj, tokens[1]);
2021 if (!p || !p->ctl) {
2022 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2026 if (strcmp(tokens[2], "regrd")) {
2027 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
2033 if (parser_read_uint32(&idx, tokens[4])) {
2034 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2038 status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
2040 snprintf(out, out_size, "Command failed.\n");
2044 snprintf(out, out_size, "0x%" PRIx64 "\n", value);
2047 static const char cmd_pipeline_regwr_help[] =
2048 "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
2051 cmd_pipeline_regwr(char **tokens,
2063 if (n_tokens != 6) {
2064 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2068 p = pipeline_find(obj, tokens[1]);
2069 if (!p || !p->ctl) {
2070 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2074 if (strcmp(tokens[2], "regwr")) {
2075 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
2081 if (parser_read_uint32(&idx, tokens[4])) {
2082 snprintf(out, out_size, MSG_ARG_INVALID, "index");
2086 if (parser_read_uint64(&value, tokens[5])) {
2087 snprintf(out, out_size, MSG_ARG_INVALID, "value");
2091 status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
2093 snprintf(out, out_size, "Command failed.\n");
2098 static const char cmd_pipeline_meter_profile_add_help[] =
2099 "pipeline <pipeline_name> meter profile <profile_name> add "
2100 "cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
2103 cmd_pipeline_meter_profile_add(char **tokens,
2109 struct rte_meter_trtcm_params params;
2111 const char *profile_name;
2114 if (n_tokens != 14) {
2115 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2119 p = pipeline_find(obj, tokens[1]);
2120 if (!p || !p->ctl) {
2121 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2125 if (strcmp(tokens[2], "meter")) {
2126 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2130 if (strcmp(tokens[3], "profile")) {
2131 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2135 profile_name = tokens[4];
2137 if (strcmp(tokens[5], "add")) {
2138 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2142 if (strcmp(tokens[6], "cir")) {
2143 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2147 if (parser_read_uint64(¶ms.cir, tokens[7])) {
2148 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2152 if (strcmp(tokens[8], "pir")) {
2153 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2157 if (parser_read_uint64(¶ms.pir, tokens[9])) {
2158 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2162 if (strcmp(tokens[10], "cbs")) {
2163 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2167 if (parser_read_uint64(¶ms.cbs, tokens[11])) {
2168 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2172 if (strcmp(tokens[12], "pbs")) {
2173 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2177 if (parser_read_uint64(¶ms.pbs, tokens[13])) {
2178 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2182 status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
2184 snprintf(out, out_size, "Command failed.\n");
2189 static const char cmd_pipeline_meter_profile_delete_help[] =
2190 "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2193 cmd_pipeline_meter_profile_delete(char **tokens,
2200 const char *profile_name;
2203 if (n_tokens != 6) {
2204 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2208 p = pipeline_find(obj, tokens[1]);
2209 if (!p || !p->ctl) {
2210 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2214 if (strcmp(tokens[2], "meter")) {
2215 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2219 if (strcmp(tokens[3], "profile")) {
2220 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2224 profile_name = tokens[4];
2226 if (strcmp(tokens[5], "delete")) {
2227 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2231 status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
2233 snprintf(out, out_size, "Command failed.\n");
2238 static const char cmd_pipeline_meter_reset_help[] =
2239 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2243 cmd_pipeline_meter_reset(char **tokens,
2251 uint32_t idx0 = 0, idx1 = 0;
2253 if (n_tokens != 9) {
2254 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2258 p = pipeline_find(obj, tokens[1]);
2259 if (!p || !p->ctl) {
2260 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2264 if (strcmp(tokens[2], "meter")) {
2265 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2271 if (strcmp(tokens[4], "from")) {
2272 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2276 if (parser_read_uint32(&idx0, tokens[5])) {
2277 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2281 if (strcmp(tokens[6], "to")) {
2282 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2286 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2287 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2291 if (strcmp(tokens[8], "reset")) {
2292 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2296 for ( ; idx0 <= idx1; idx0++) {
2299 status = rte_swx_ctl_meter_reset(p->p, name, idx0);
2301 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2307 static const char cmd_pipeline_meter_set_help[] =
2308 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2309 "set profile <profile_name>\n";
2312 cmd_pipeline_meter_set(char **tokens,
2319 const char *name, *profile_name;
2320 uint32_t idx0 = 0, idx1 = 0;
2322 if (n_tokens != 11) {
2323 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2327 p = pipeline_find(obj, tokens[1]);
2328 if (!p || !p->ctl) {
2329 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2333 if (strcmp(tokens[2], "meter")) {
2334 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2340 if (strcmp(tokens[4], "from")) {
2341 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2345 if (parser_read_uint32(&idx0, tokens[5])) {
2346 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2350 if (strcmp(tokens[6], "to")) {
2351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2355 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2356 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2360 if (strcmp(tokens[8], "set")) {
2361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2365 if (strcmp(tokens[9], "profile")) {
2366 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2370 profile_name = tokens[10];
2372 for ( ; idx0 <= idx1; idx0++) {
2375 status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
2377 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2383 static const char cmd_pipeline_meter_stats_help[] =
2384 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2388 cmd_pipeline_meter_stats(char **tokens,
2394 struct rte_swx_ctl_meter_stats stats;
2397 uint32_t idx0 = 0, idx1 = 0;
2399 if (n_tokens != 9) {
2400 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2404 p = pipeline_find(obj, tokens[1]);
2405 if (!p || !p->ctl) {
2406 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2410 if (strcmp(tokens[2], "meter")) {
2411 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2417 if (strcmp(tokens[4], "from")) {
2418 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2422 if (parser_read_uint32(&idx0, tokens[5])) {
2423 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2427 if (strcmp(tokens[6], "to")) {
2428 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2432 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2433 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2437 if (strcmp(tokens[8], "stats")) {
2438 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2443 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2445 "----------------", "----------------", "----------------",
2446 "----------------", "----------------", "----------------");
2447 out_size -= strlen(out);
2450 snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2452 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2453 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2454 out_size -= strlen(out);
2457 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2459 "----------------", "----------------", "----------------",
2460 "----------------", "----------------", "----------------");
2461 out_size -= strlen(out);
2465 for ( ; idx0 <= idx1; idx0++) {
2468 status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
2470 snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2471 out_size -= strlen(out);
2476 snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2477 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2479 stats.n_pkts[RTE_COLOR_GREEN],
2480 stats.n_pkts[RTE_COLOR_YELLOW],
2481 stats.n_pkts[RTE_COLOR_RED],
2482 stats.n_bytes[RTE_COLOR_GREEN],
2483 stats.n_bytes[RTE_COLOR_YELLOW],
2484 stats.n_bytes[RTE_COLOR_RED]);
2485 out_size -= strlen(out);
2490 static const char cmd_pipeline_stats_help[] =
2491 "pipeline <pipeline_name> stats\n";
2494 cmd_pipeline_stats(char **tokens,
2500 struct rte_swx_ctl_pipeline_info info;
2505 if (n_tokens != 3) {
2506 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2510 p = pipeline_find(obj, tokens[1]);
2511 if (!p || !p->ctl) {
2512 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2516 if (strcmp(tokens[2], "stats")) {
2517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2521 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
2523 snprintf(out, out_size, "Pipeline info get error.");
2527 snprintf(out, out_size, "Input ports:\n");
2528 out_size -= strlen(out);
2531 for (i = 0; i < info.n_ports_in; i++) {
2532 struct rte_swx_port_in_stats stats;
2534 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
2536 snprintf(out, out_size, "\tPort %u:"
2539 " empty %" PRIu64 "\n",
2540 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
2541 out_size -= strlen(out);
2545 snprintf(out, out_size, "\nOutput ports:\n");
2546 out_size -= strlen(out);
2549 for (i = 0; i < info.n_ports_out; i++) {
2550 struct rte_swx_port_out_stats stats;
2552 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
2554 snprintf(out, out_size, "\tPort %u:"
2556 " bytes %" PRIu64 "\n",
2557 i, stats.n_pkts, stats.n_bytes);
2558 out_size -= strlen(out);
2562 snprintf(out, out_size, "\nTables:\n");
2563 out_size -= strlen(out);
2566 for (i = 0; i < info.n_tables; i++) {
2567 struct rte_swx_ctl_table_info table_info;
2568 uint64_t n_pkts_action[info.n_actions];
2569 struct rte_swx_table_stats stats = {
2572 .n_pkts_action = n_pkts_action,
2576 status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2578 snprintf(out, out_size, "Table info get error.");
2582 status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2584 snprintf(out, out_size, "Table stats read error.");
2588 snprintf(out, out_size, "\tTable %s:\n"
2589 "\t\tHit (packets): %" PRIu64 "\n"
2590 "\t\tMiss (packets): %" PRIu64 "\n",
2594 out_size -= strlen(out);
2597 for (j = 0; j < info.n_actions; j++) {
2598 struct rte_swx_ctl_action_info action_info;
2600 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2602 snprintf(out, out_size, "Action info get error.");
2606 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2608 stats.n_pkts_action[j]);
2609 out_size -= strlen(out);
2614 snprintf(out, out_size, "\nLearner tables:\n");
2615 out_size -= strlen(out);
2618 for (i = 0; i < info.n_learners; i++) {
2619 struct rte_swx_ctl_learner_info learner_info;
2620 uint64_t n_pkts_action[info.n_actions];
2621 struct rte_swx_learner_stats stats = {
2624 .n_pkts_action = n_pkts_action,
2628 status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
2630 snprintf(out, out_size, "Learner table info get error.");
2634 status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
2636 snprintf(out, out_size, "Learner table stats read error.");
2640 snprintf(out, out_size, "\tLearner table %s:\n"
2641 "\t\tHit (packets): %" PRIu64 "\n"
2642 "\t\tMiss (packets): %" PRIu64 "\n"
2643 "\t\tLearn OK (packets): %" PRIu64 "\n"
2644 "\t\tLearn error (packets): %" PRIu64 "\n"
2645 "\t\tForget (packets): %" PRIu64 "\n",
2649 stats.n_pkts_learn_ok,
2650 stats.n_pkts_learn_err,
2651 stats.n_pkts_forget);
2652 out_size -= strlen(out);
2655 for (j = 0; j < info.n_actions; j++) {
2656 struct rte_swx_ctl_action_info action_info;
2658 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2660 snprintf(out, out_size, "Action info get error.");
2664 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2666 stats.n_pkts_action[j]);
2667 out_size -= strlen(out);
2673 static const char cmd_thread_pipeline_enable_help[] =
2674 "thread <thread_id> pipeline <pipeline_name> enable\n";
2677 cmd_thread_pipeline_enable(char **tokens,
2683 char *pipeline_name;
2688 if (n_tokens != 5) {
2689 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2693 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2694 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2698 if (strcmp(tokens[2], "pipeline") != 0) {
2699 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2703 pipeline_name = tokens[3];
2704 p = pipeline_find(obj, pipeline_name);
2705 if (!p || !p->ctl) {
2706 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2710 if (strcmp(tokens[4], "enable") != 0) {
2711 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2715 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
2717 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
2722 static const char cmd_thread_pipeline_disable_help[] =
2723 "thread <thread_id> pipeline <pipeline_name> disable\n";
2726 cmd_thread_pipeline_disable(char **tokens,
2733 char *pipeline_name;
2737 if (n_tokens != 5) {
2738 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2742 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2743 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2747 if (strcmp(tokens[2], "pipeline") != 0) {
2748 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2752 pipeline_name = tokens[3];
2753 p = pipeline_find(obj, pipeline_name);
2754 if (!p || !p->ctl) {
2755 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2759 if (strcmp(tokens[4], "disable") != 0) {
2760 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2764 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
2766 snprintf(out, out_size, MSG_CMD_FAIL,
2767 "thread pipeline disable");
2773 cmd_help(char **tokens,
2777 void *arg __rte_unused)
2782 if (n_tokens == 0) {
2783 snprintf(out, out_size,
2784 "Type 'help <command>' for command details.\n\n"
2785 "List of commands:\n"
2789 "\tpipeline create\n"
2790 "\tpipeline port in\n"
2791 "\tpipeline port out\n"
2792 "\tpipeline build\n"
2793 "\tpipeline table add\n"
2794 "\tpipeline table delete\n"
2795 "\tpipeline table default\n"
2796 "\tpipeline table show\n"
2797 "\tpipeline selector group add\n"
2798 "\tpipeline selector group delete\n"
2799 "\tpipeline selector group member add\n"
2800 "\tpipeline selector group member delete\n"
2801 "\tpipeline selector show\n"
2802 "\tpipeline learner default\n"
2803 "\tpipeline commit\n"
2804 "\tpipeline abort\n"
2805 "\tpipeline regrd\n"
2806 "\tpipeline regwr\n"
2807 "\tpipeline meter profile add\n"
2808 "\tpipeline meter profile delete\n"
2809 "\tpipeline meter reset\n"
2810 "\tpipeline meter set\n"
2811 "\tpipeline meter stats\n"
2812 "\tpipeline stats\n"
2813 "\tthread pipeline enable\n"
2814 "\tthread pipeline disable\n\n");
2818 if (strcmp(tokens[0], "mempool") == 0) {
2819 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
2823 if (strcmp(tokens[0], "link") == 0) {
2824 snprintf(out, out_size, "\n%s\n", cmd_link_help);
2828 if (strcmp(tokens[0], "ring") == 0) {
2829 snprintf(out, out_size, "\n%s\n", cmd_ring_help);
2833 if (strcmp(tokens[0], "tap") == 0) {
2834 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2838 if ((strcmp(tokens[0], "pipeline") == 0) &&
2839 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
2840 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
2844 if ((strcmp(tokens[0], "pipeline") == 0) &&
2845 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
2846 if (strcmp(tokens[2], "in") == 0) {
2847 snprintf(out, out_size, "\n%s\n",
2848 cmd_pipeline_port_in_help);
2852 if (strcmp(tokens[2], "out") == 0) {
2853 snprintf(out, out_size, "\n%s\n",
2854 cmd_pipeline_port_out_help);
2859 if ((strcmp(tokens[0], "pipeline") == 0) &&
2860 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
2861 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
2865 if ((strcmp(tokens[0], "pipeline") == 0) &&
2867 (strcmp(tokens[1], "table") == 0) &&
2868 (strcmp(tokens[2], "add") == 0)) {
2869 snprintf(out, out_size, "\n%s\n",
2870 cmd_pipeline_table_add_help);
2874 if ((strcmp(tokens[0], "pipeline") == 0) &&
2876 (strcmp(tokens[1], "table") == 0) &&
2877 (strcmp(tokens[2], "delete") == 0)) {
2878 snprintf(out, out_size, "\n%s\n",
2879 cmd_pipeline_table_delete_help);
2883 if ((strcmp(tokens[0], "pipeline") == 0) &&
2885 (strcmp(tokens[1], "table") == 0) &&
2886 (strcmp(tokens[2], "default") == 0)) {
2887 snprintf(out, out_size, "\n%s\n",
2888 cmd_pipeline_table_default_help);
2892 if ((strcmp(tokens[0], "pipeline") == 0) &&
2894 (strcmp(tokens[1], "table") == 0) &&
2895 (strcmp(tokens[2], "show") == 0)) {
2896 snprintf(out, out_size, "\n%s\n",
2897 cmd_pipeline_table_show_help);
2901 if ((strcmp(tokens[0], "pipeline") == 0) &&
2903 (strcmp(tokens[1], "selector") == 0) &&
2904 (strcmp(tokens[2], "group") == 0) &&
2905 (strcmp(tokens[3], "add") == 0)) {
2906 snprintf(out, out_size, "\n%s\n",
2907 cmd_pipeline_selector_group_add_help);
2911 if ((strcmp(tokens[0], "pipeline") == 0) &&
2913 (strcmp(tokens[1], "selector") == 0) &&
2914 (strcmp(tokens[2], "group") == 0) &&
2915 (strcmp(tokens[3], "delete") == 0)) {
2916 snprintf(out, out_size, "\n%s\n",
2917 cmd_pipeline_selector_group_delete_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], "add") == 0)) {
2927 snprintf(out, out_size, "\n%s\n",
2928 cmd_pipeline_selector_group_member_add_help);
2932 if ((strcmp(tokens[0], "pipeline") == 0) &&
2934 (strcmp(tokens[1], "selector") == 0) &&
2935 (strcmp(tokens[2], "group") == 0) &&
2936 (strcmp(tokens[3], "member") == 0) &&
2937 (strcmp(tokens[4], "delete") == 0)) {
2938 snprintf(out, out_size, "\n%s\n",
2939 cmd_pipeline_selector_group_member_delete_help);
2943 if ((strcmp(tokens[0], "pipeline") == 0) &&
2945 (strcmp(tokens[1], "selector") == 0) &&
2946 (strcmp(tokens[2], "show") == 0)) {
2947 snprintf(out, out_size, "\n%s\n",
2948 cmd_pipeline_selector_show_help);
2952 if ((strcmp(tokens[0], "pipeline") == 0) &&
2954 (strcmp(tokens[1], "learner") == 0) &&
2955 (strcmp(tokens[2], "default") == 0)) {
2956 snprintf(out, out_size, "\n%s\n",
2957 cmd_pipeline_learner_default_help);
2961 if ((strcmp(tokens[0], "pipeline") == 0) &&
2963 (strcmp(tokens[1], "commit") == 0)) {
2964 snprintf(out, out_size, "\n%s\n",
2965 cmd_pipeline_commit_help);
2969 if ((strcmp(tokens[0], "pipeline") == 0) &&
2971 (strcmp(tokens[1], "abort") == 0)) {
2972 snprintf(out, out_size, "\n%s\n",
2973 cmd_pipeline_abort_help);
2977 if ((strcmp(tokens[0], "pipeline") == 0) &&
2978 (n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
2979 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
2983 if ((strcmp(tokens[0], "pipeline") == 0) &&
2984 (n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
2985 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
2989 if (!strcmp(tokens[0], "pipeline") &&
2990 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2991 && !strcmp(tokens[2], "profile")
2992 && !strcmp(tokens[3], "add")) {
2993 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2997 if (!strcmp(tokens[0], "pipeline") &&
2998 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2999 && !strcmp(tokens[2], "profile")
3000 && !strcmp(tokens[3], "delete")) {
3001 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
3005 if (!strcmp(tokens[0], "pipeline") &&
3006 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3007 && !strcmp(tokens[2], "reset")) {
3008 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3012 if (!strcmp(tokens[0], "pipeline") &&
3013 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3014 && !strcmp(tokens[2], "set")) {
3015 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3019 if (!strcmp(tokens[0], "pipeline") &&
3020 (n_tokens == 3) && !strcmp(tokens[1], "meter")
3021 && !strcmp(tokens[2], "stats")) {
3022 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3026 if ((strcmp(tokens[0], "pipeline") == 0) &&
3027 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
3028 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
3032 if ((n_tokens == 3) &&
3033 (strcmp(tokens[0], "thread") == 0) &&
3034 (strcmp(tokens[1], "pipeline") == 0)) {
3035 if (strcmp(tokens[2], "enable") == 0) {
3036 snprintf(out, out_size, "\n%s\n",
3037 cmd_thread_pipeline_enable_help);
3041 if (strcmp(tokens[2], "disable") == 0) {
3042 snprintf(out, out_size, "\n%s\n",
3043 cmd_thread_pipeline_disable_help);
3048 snprintf(out, out_size, "Invalid command\n");
3052 cli_process(char *in, char *out, size_t out_size, void *obj)
3054 char *tokens[CMD_MAX_TOKENS];
3055 uint32_t n_tokens = RTE_DIM(tokens);
3061 status = parse_tokenize_string(in, tokens, &n_tokens);
3063 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
3070 if (strcmp(tokens[0], "help") == 0) {
3071 cmd_help(tokens, n_tokens, out, out_size, obj);
3075 if (strcmp(tokens[0], "mempool") == 0) {
3076 cmd_mempool(tokens, n_tokens, out, out_size, obj);
3080 if (strcmp(tokens[0], "link") == 0) {
3081 if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3082 cmd_link_show(tokens, n_tokens, out, out_size, obj);
3086 cmd_link(tokens, n_tokens, out, out_size, obj);
3090 if (strcmp(tokens[0], "ring") == 0) {
3091 cmd_ring(tokens, n_tokens, out, out_size, obj);
3095 if (strcmp(tokens[0], "tap") == 0) {
3096 cmd_tap(tokens, n_tokens, out, out_size, obj);
3100 if (strcmp(tokens[0], "pipeline") == 0) {
3101 if ((n_tokens >= 3) &&
3102 (strcmp(tokens[2], "create") == 0)) {
3103 cmd_pipeline_create(tokens, n_tokens, out, out_size,
3108 if ((n_tokens >= 4) &&
3109 (strcmp(tokens[2], "port") == 0) &&
3110 (strcmp(tokens[3], "in") == 0)) {
3111 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
3116 if ((n_tokens >= 4) &&
3117 (strcmp(tokens[2], "port") == 0) &&
3118 (strcmp(tokens[3], "out") == 0)) {
3119 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
3124 if ((n_tokens >= 3) &&
3125 (strcmp(tokens[2], "build") == 0)) {
3126 cmd_pipeline_build(tokens, n_tokens, out, out_size,
3131 if ((n_tokens >= 5) &&
3132 (strcmp(tokens[2], "table") == 0) &&
3133 (strcmp(tokens[4], "add") == 0)) {
3134 cmd_pipeline_table_add(tokens, n_tokens, out,
3139 if ((n_tokens >= 5) &&
3140 (strcmp(tokens[2], "table") == 0) &&
3141 (strcmp(tokens[4], "delete") == 0)) {
3142 cmd_pipeline_table_delete(tokens, n_tokens, out,
3147 if ((n_tokens >= 5) &&
3148 (strcmp(tokens[2], "table") == 0) &&
3149 (strcmp(tokens[4], "default") == 0)) {
3150 cmd_pipeline_table_default(tokens, n_tokens, out,
3155 if ((n_tokens >= 5) &&
3156 (strcmp(tokens[2], "table") == 0) &&
3157 (strcmp(tokens[4], "show") == 0)) {
3158 cmd_pipeline_table_show(tokens, n_tokens, out,
3163 if ((n_tokens >= 6) &&
3164 (strcmp(tokens[2], "selector") == 0) &&
3165 (strcmp(tokens[4], "group") == 0) &&
3166 (strcmp(tokens[5], "add") == 0)) {
3167 cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3172 if ((n_tokens >= 6) &&
3173 (strcmp(tokens[2], "selector") == 0) &&
3174 (strcmp(tokens[4], "group") == 0) &&
3175 (strcmp(tokens[5], "delete") == 0)) {
3176 cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3181 if ((n_tokens >= 7) &&
3182 (strcmp(tokens[2], "selector") == 0) &&
3183 (strcmp(tokens[4], "group") == 0) &&
3184 (strcmp(tokens[5], "member") == 0) &&
3185 (strcmp(tokens[6], "add") == 0)) {
3186 cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3191 if ((n_tokens >= 7) &&
3192 (strcmp(tokens[2], "selector") == 0) &&
3193 (strcmp(tokens[4], "group") == 0) &&
3194 (strcmp(tokens[5], "member") == 0) &&
3195 (strcmp(tokens[6], "delete") == 0)) {
3196 cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3201 if ((n_tokens >= 5) &&
3202 (strcmp(tokens[2], "selector") == 0) &&
3203 (strcmp(tokens[4], "show") == 0)) {
3204 cmd_pipeline_selector_show(tokens, n_tokens, out,
3209 if ((n_tokens >= 5) &&
3210 (strcmp(tokens[2], "learner") == 0) &&
3211 (strcmp(tokens[4], "default") == 0)) {
3212 cmd_pipeline_learner_default(tokens, n_tokens, out,
3217 if ((n_tokens >= 3) &&
3218 (strcmp(tokens[2], "commit") == 0)) {
3219 cmd_pipeline_commit(tokens, n_tokens, out,
3224 if ((n_tokens >= 3) &&
3225 (strcmp(tokens[2], "abort") == 0)) {
3226 cmd_pipeline_abort(tokens, n_tokens, out,
3231 if ((n_tokens >= 3) &&
3232 (strcmp(tokens[2], "regrd") == 0)) {
3233 cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
3237 if ((n_tokens >= 3) &&
3238 (strcmp(tokens[2], "regwr") == 0)) {
3239 cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
3243 if ((n_tokens >= 6) &&
3244 (strcmp(tokens[2], "meter") == 0) &&
3245 (strcmp(tokens[3], "profile") == 0) &&
3246 (strcmp(tokens[5], "add") == 0)) {
3247 cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3251 if ((n_tokens >= 6) &&
3252 (strcmp(tokens[2], "meter") == 0) &&
3253 (strcmp(tokens[3], "profile") == 0) &&
3254 (strcmp(tokens[5], "delete") == 0)) {
3255 cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3259 if ((n_tokens >= 9) &&
3260 (strcmp(tokens[2], "meter") == 0) &&
3261 (strcmp(tokens[8], "reset") == 0)) {
3262 cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3266 if ((n_tokens >= 9) &&
3267 (strcmp(tokens[2], "meter") == 0) &&
3268 (strcmp(tokens[8], "set") == 0)) {
3269 cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3273 if ((n_tokens >= 9) &&
3274 (strcmp(tokens[2], "meter") == 0) &&
3275 (strcmp(tokens[8], "stats") == 0)) {
3276 cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3280 if ((n_tokens >= 3) &&
3281 (strcmp(tokens[2], "stats") == 0)) {
3282 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
3288 if (strcmp(tokens[0], "thread") == 0) {
3289 if ((n_tokens >= 5) &&
3290 (strcmp(tokens[4], "enable") == 0)) {
3291 cmd_thread_pipeline_enable(tokens, n_tokens,
3292 out, out_size, obj);
3296 if ((n_tokens >= 5) &&
3297 (strcmp(tokens[4], "disable") == 0)) {
3298 cmd_thread_pipeline_disable(tokens, n_tokens,
3299 out, out_size, obj);
3304 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
3308 cli_script_process(const char *file_name,
3309 size_t msg_in_len_max,
3310 size_t msg_out_len_max,
3313 char *msg_in = NULL, *msg_out = NULL;
3316 /* Check input arguments */
3317 if ((file_name == NULL) ||
3318 (strlen(file_name) == 0) ||
3319 (msg_in_len_max == 0) ||
3320 (msg_out_len_max == 0))
3323 msg_in = malloc(msg_in_len_max + 1);
3324 msg_out = malloc(msg_out_len_max + 1);
3325 if ((msg_in == NULL) ||
3326 (msg_out == NULL)) {
3332 /* Open input file */
3333 f = fopen(file_name, "r");
3342 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
3345 printf("%s", msg_in);
3353 if (strlen(msg_out))
3354 printf("%s", msg_out);