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");
1830 static const char cmd_pipeline_commit_help[] =
1831 "pipeline <pipeline_name> commit\n";
1834 cmd_pipeline_commit(char **tokens,
1841 char *pipeline_name;
1844 if (n_tokens != 3) {
1845 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1849 pipeline_name = tokens[1];
1850 p = pipeline_find(obj, pipeline_name);
1851 if (!p || !p->ctl) {
1852 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1856 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1858 snprintf(out, out_size, "Commit failed. "
1859 "Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1862 static const char cmd_pipeline_abort_help[] =
1863 "pipeline <pipeline_name> abort\n";
1866 cmd_pipeline_abort(char **tokens,
1873 char *pipeline_name;
1875 if (n_tokens != 3) {
1876 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1880 pipeline_name = tokens[1];
1881 p = pipeline_find(obj, pipeline_name);
1882 if (!p || !p->ctl) {
1883 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1887 rte_swx_ctl_pipeline_abort(p->ctl);
1890 static const char cmd_pipeline_regrd_help[] =
1891 "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
1894 cmd_pipeline_regrd(char **tokens,
1906 if (n_tokens != 5) {
1907 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1911 p = pipeline_find(obj, tokens[1]);
1912 if (!p || !p->ctl) {
1913 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1917 if (strcmp(tokens[2], "regrd")) {
1918 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
1924 if (parser_read_uint32(&idx, tokens[4])) {
1925 snprintf(out, out_size, MSG_ARG_INVALID, "index");
1929 status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
1931 snprintf(out, out_size, "Command failed.\n");
1935 snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1938 static const char cmd_pipeline_regwr_help[] =
1939 "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
1942 cmd_pipeline_regwr(char **tokens,
1954 if (n_tokens != 6) {
1955 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1959 p = pipeline_find(obj, tokens[1]);
1960 if (!p || !p->ctl) {
1961 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1965 if (strcmp(tokens[2], "regwr")) {
1966 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
1972 if (parser_read_uint32(&idx, tokens[4])) {
1973 snprintf(out, out_size, MSG_ARG_INVALID, "index");
1977 if (parser_read_uint64(&value, tokens[5])) {
1978 snprintf(out, out_size, MSG_ARG_INVALID, "value");
1982 status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
1984 snprintf(out, out_size, "Command failed.\n");
1989 static const char cmd_pipeline_meter_profile_add_help[] =
1990 "pipeline <pipeline_name> meter profile <profile_name> add "
1991 "cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1994 cmd_pipeline_meter_profile_add(char **tokens,
2000 struct rte_meter_trtcm_params params;
2002 const char *profile_name;
2005 if (n_tokens != 14) {
2006 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2010 p = pipeline_find(obj, tokens[1]);
2011 if (!p || !p->ctl) {
2012 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2016 if (strcmp(tokens[2], "meter")) {
2017 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2021 if (strcmp(tokens[3], "profile")) {
2022 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2026 profile_name = tokens[4];
2028 if (strcmp(tokens[5], "add")) {
2029 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2033 if (strcmp(tokens[6], "cir")) {
2034 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2038 if (parser_read_uint64(¶ms.cir, tokens[7])) {
2039 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2043 if (strcmp(tokens[8], "pir")) {
2044 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2048 if (parser_read_uint64(¶ms.pir, tokens[9])) {
2049 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2053 if (strcmp(tokens[10], "cbs")) {
2054 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2058 if (parser_read_uint64(¶ms.cbs, tokens[11])) {
2059 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2063 if (strcmp(tokens[12], "pbs")) {
2064 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2068 if (parser_read_uint64(¶ms.pbs, tokens[13])) {
2069 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2073 status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
2075 snprintf(out, out_size, "Command failed.\n");
2080 static const char cmd_pipeline_meter_profile_delete_help[] =
2081 "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2084 cmd_pipeline_meter_profile_delete(char **tokens,
2091 const char *profile_name;
2094 if (n_tokens != 6) {
2095 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2099 p = pipeline_find(obj, tokens[1]);
2100 if (!p || !p->ctl) {
2101 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2105 if (strcmp(tokens[2], "meter")) {
2106 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2110 if (strcmp(tokens[3], "profile")) {
2111 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2115 profile_name = tokens[4];
2117 if (strcmp(tokens[5], "delete")) {
2118 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2122 status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
2124 snprintf(out, out_size, "Command failed.\n");
2129 static const char cmd_pipeline_meter_reset_help[] =
2130 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2134 cmd_pipeline_meter_reset(char **tokens,
2142 uint32_t idx0 = 0, idx1 = 0;
2144 if (n_tokens != 9) {
2145 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2149 p = pipeline_find(obj, tokens[1]);
2150 if (!p || !p->ctl) {
2151 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2155 if (strcmp(tokens[2], "meter")) {
2156 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2162 if (strcmp(tokens[4], "from")) {
2163 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2167 if (parser_read_uint32(&idx0, tokens[5])) {
2168 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2172 if (strcmp(tokens[6], "to")) {
2173 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2177 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2178 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2182 if (strcmp(tokens[8], "reset")) {
2183 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2187 for ( ; idx0 <= idx1; idx0++) {
2190 status = rte_swx_ctl_meter_reset(p->p, name, idx0);
2192 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2198 static const char cmd_pipeline_meter_set_help[] =
2199 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2200 "set profile <profile_name>\n";
2203 cmd_pipeline_meter_set(char **tokens,
2210 const char *name, *profile_name;
2211 uint32_t idx0 = 0, idx1 = 0;
2213 if (n_tokens != 11) {
2214 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2218 p = pipeline_find(obj, tokens[1]);
2219 if (!p || !p->ctl) {
2220 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2224 if (strcmp(tokens[2], "meter")) {
2225 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2231 if (strcmp(tokens[4], "from")) {
2232 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2236 if (parser_read_uint32(&idx0, tokens[5])) {
2237 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2241 if (strcmp(tokens[6], "to")) {
2242 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2246 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2247 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2251 if (strcmp(tokens[8], "set")) {
2252 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2256 if (strcmp(tokens[9], "profile")) {
2257 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2261 profile_name = tokens[10];
2263 for ( ; idx0 <= idx1; idx0++) {
2266 status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
2268 snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2274 static const char cmd_pipeline_meter_stats_help[] =
2275 "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2279 cmd_pipeline_meter_stats(char **tokens,
2285 struct rte_swx_ctl_meter_stats stats;
2288 uint32_t idx0 = 0, idx1 = 0;
2290 if (n_tokens != 9) {
2291 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2295 p = pipeline_find(obj, tokens[1]);
2296 if (!p || !p->ctl) {
2297 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2301 if (strcmp(tokens[2], "meter")) {
2302 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2308 if (strcmp(tokens[4], "from")) {
2309 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2313 if (parser_read_uint32(&idx0, tokens[5])) {
2314 snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2318 if (strcmp(tokens[6], "to")) {
2319 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2323 if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2324 snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2328 if (strcmp(tokens[8], "stats")) {
2329 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2334 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2336 "----------------", "----------------", "----------------",
2337 "----------------", "----------------", "----------------");
2338 out_size -= strlen(out);
2341 snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2343 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2344 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2345 out_size -= strlen(out);
2348 snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2350 "----------------", "----------------", "----------------",
2351 "----------------", "----------------", "----------------");
2352 out_size -= strlen(out);
2356 for ( ; idx0 <= idx1; idx0++) {
2359 status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
2361 snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2362 out_size -= strlen(out);
2367 snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2368 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2370 stats.n_pkts[RTE_COLOR_GREEN],
2371 stats.n_pkts[RTE_COLOR_YELLOW],
2372 stats.n_pkts[RTE_COLOR_RED],
2373 stats.n_bytes[RTE_COLOR_GREEN],
2374 stats.n_bytes[RTE_COLOR_YELLOW],
2375 stats.n_bytes[RTE_COLOR_RED]);
2376 out_size -= strlen(out);
2381 static const char cmd_pipeline_stats_help[] =
2382 "pipeline <pipeline_name> stats\n";
2385 cmd_pipeline_stats(char **tokens,
2391 struct rte_swx_ctl_pipeline_info info;
2396 if (n_tokens != 3) {
2397 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2401 p = pipeline_find(obj, tokens[1]);
2402 if (!p || !p->ctl) {
2403 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2407 if (strcmp(tokens[2], "stats")) {
2408 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2412 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
2414 snprintf(out, out_size, "Pipeline info get error.");
2418 snprintf(out, out_size, "Input ports:\n");
2419 out_size -= strlen(out);
2422 for (i = 0; i < info.n_ports_in; i++) {
2423 struct rte_swx_port_in_stats stats;
2425 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
2427 snprintf(out, out_size, "\tPort %u:"
2430 " empty %" PRIu64 "\n",
2431 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
2432 out_size -= strlen(out);
2436 snprintf(out, out_size, "\nOutput ports:\n");
2437 out_size -= strlen(out);
2440 for (i = 0; i < info.n_ports_out; i++) {
2441 struct rte_swx_port_out_stats stats;
2443 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
2445 snprintf(out, out_size, "\tPort %u:"
2447 " bytes %" PRIu64 "\n",
2448 i, stats.n_pkts, stats.n_bytes);
2449 out_size -= strlen(out);
2453 snprintf(out, out_size, "\nTables:\n");
2454 out_size -= strlen(out);
2457 for (i = 0; i < info.n_tables; i++) {
2458 struct rte_swx_ctl_table_info table_info;
2459 uint64_t n_pkts_action[info.n_actions];
2460 struct rte_swx_table_stats stats = {
2463 .n_pkts_action = n_pkts_action,
2467 status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2469 snprintf(out, out_size, "Table info get error.");
2473 status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2475 snprintf(out, out_size, "Table stats read error.");
2479 snprintf(out, out_size, "\tTable %s:\n"
2480 "\t\tHit (packets): %" PRIu64 "\n"
2481 "\t\tMiss (packets): %" PRIu64 "\n",
2485 out_size -= strlen(out);
2488 for (j = 0; j < info.n_actions; j++) {
2489 struct rte_swx_ctl_action_info action_info;
2491 status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2493 snprintf(out, out_size, "Action info get error.");
2497 snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2499 stats.n_pkts_action[j]);
2500 out_size -= strlen(out);
2506 static const char cmd_thread_pipeline_enable_help[] =
2507 "thread <thread_id> pipeline <pipeline_name> enable\n";
2510 cmd_thread_pipeline_enable(char **tokens,
2516 char *pipeline_name;
2521 if (n_tokens != 5) {
2522 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2526 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2527 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2531 if (strcmp(tokens[2], "pipeline") != 0) {
2532 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2536 pipeline_name = tokens[3];
2537 p = pipeline_find(obj, pipeline_name);
2538 if (!p || !p->ctl) {
2539 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2543 if (strcmp(tokens[4], "enable") != 0) {
2544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2548 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
2550 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
2555 static const char cmd_thread_pipeline_disable_help[] =
2556 "thread <thread_id> pipeline <pipeline_name> disable\n";
2559 cmd_thread_pipeline_disable(char **tokens,
2566 char *pipeline_name;
2570 if (n_tokens != 5) {
2571 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2575 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
2576 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
2580 if (strcmp(tokens[2], "pipeline") != 0) {
2581 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2585 pipeline_name = tokens[3];
2586 p = pipeline_find(obj, pipeline_name);
2587 if (!p || !p->ctl) {
2588 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2592 if (strcmp(tokens[4], "disable") != 0) {
2593 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2597 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
2599 snprintf(out, out_size, MSG_CMD_FAIL,
2600 "thread pipeline disable");
2606 cmd_help(char **tokens,
2610 void *arg __rte_unused)
2615 if (n_tokens == 0) {
2616 snprintf(out, out_size,
2617 "Type 'help <command>' for command details.\n\n"
2618 "List of commands:\n"
2622 "\tpipeline create\n"
2623 "\tpipeline port in\n"
2624 "\tpipeline port out\n"
2625 "\tpipeline build\n"
2626 "\tpipeline table add\n"
2627 "\tpipeline table delete\n"
2628 "\tpipeline table default\n"
2629 "\tpipeline table show\n"
2630 "\tpipeline selector group add\n"
2631 "\tpipeline selector group delete\n"
2632 "\tpipeline selector group member add\n"
2633 "\tpipeline selector group member delete\n"
2634 "\tpipeline selector show\n"
2635 "\tpipeline commit\n"
2636 "\tpipeline abort\n"
2637 "\tpipeline regrd\n"
2638 "\tpipeline regwr\n"
2639 "\tpipeline meter profile add\n"
2640 "\tpipeline meter profile delete\n"
2641 "\tpipeline meter reset\n"
2642 "\tpipeline meter set\n"
2643 "\tpipeline meter stats\n"
2644 "\tpipeline stats\n"
2645 "\tthread pipeline enable\n"
2646 "\tthread pipeline disable\n\n");
2650 if (strcmp(tokens[0], "mempool") == 0) {
2651 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
2655 if (strcmp(tokens[0], "link") == 0) {
2656 snprintf(out, out_size, "\n%s\n", cmd_link_help);
2660 if (strcmp(tokens[0], "ring") == 0) {
2661 snprintf(out, out_size, "\n%s\n", cmd_ring_help);
2665 if (strcmp(tokens[0], "tap") == 0) {
2666 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2670 if ((strcmp(tokens[0], "pipeline") == 0) &&
2671 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
2672 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
2676 if ((strcmp(tokens[0], "pipeline") == 0) &&
2677 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
2678 if (strcmp(tokens[2], "in") == 0) {
2679 snprintf(out, out_size, "\n%s\n",
2680 cmd_pipeline_port_in_help);
2684 if (strcmp(tokens[2], "out") == 0) {
2685 snprintf(out, out_size, "\n%s\n",
2686 cmd_pipeline_port_out_help);
2691 if ((strcmp(tokens[0], "pipeline") == 0) &&
2692 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
2693 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
2697 if ((strcmp(tokens[0], "pipeline") == 0) &&
2699 (strcmp(tokens[1], "table") == 0) &&
2700 (strcmp(tokens[2], "add") == 0)) {
2701 snprintf(out, out_size, "\n%s\n",
2702 cmd_pipeline_table_add_help);
2706 if ((strcmp(tokens[0], "pipeline") == 0) &&
2708 (strcmp(tokens[1], "table") == 0) &&
2709 (strcmp(tokens[2], "delete") == 0)) {
2710 snprintf(out, out_size, "\n%s\n",
2711 cmd_pipeline_table_delete_help);
2715 if ((strcmp(tokens[0], "pipeline") == 0) &&
2717 (strcmp(tokens[1], "table") == 0) &&
2718 (strcmp(tokens[2], "default") == 0)) {
2719 snprintf(out, out_size, "\n%s\n",
2720 cmd_pipeline_table_default_help);
2724 if ((strcmp(tokens[0], "pipeline") == 0) &&
2726 (strcmp(tokens[1], "table") == 0) &&
2727 (strcmp(tokens[2], "show") == 0)) {
2728 snprintf(out, out_size, "\n%s\n",
2729 cmd_pipeline_table_show_help);
2733 if ((strcmp(tokens[0], "pipeline") == 0) &&
2735 (strcmp(tokens[1], "selector") == 0) &&
2736 (strcmp(tokens[2], "group") == 0) &&
2737 (strcmp(tokens[3], "add") == 0)) {
2738 snprintf(out, out_size, "\n%s\n",
2739 cmd_pipeline_selector_group_add_help);
2743 if ((strcmp(tokens[0], "pipeline") == 0) &&
2745 (strcmp(tokens[1], "selector") == 0) &&
2746 (strcmp(tokens[2], "group") == 0) &&
2747 (strcmp(tokens[3], "delete") == 0)) {
2748 snprintf(out, out_size, "\n%s\n",
2749 cmd_pipeline_selector_group_delete_help);
2753 if ((strcmp(tokens[0], "pipeline") == 0) &&
2755 (strcmp(tokens[1], "selector") == 0) &&
2756 (strcmp(tokens[2], "group") == 0) &&
2757 (strcmp(tokens[3], "member") == 0) &&
2758 (strcmp(tokens[4], "add") == 0)) {
2759 snprintf(out, out_size, "\n%s\n",
2760 cmd_pipeline_selector_group_member_add_help);
2764 if ((strcmp(tokens[0], "pipeline") == 0) &&
2766 (strcmp(tokens[1], "selector") == 0) &&
2767 (strcmp(tokens[2], "group") == 0) &&
2768 (strcmp(tokens[3], "member") == 0) &&
2769 (strcmp(tokens[4], "delete") == 0)) {
2770 snprintf(out, out_size, "\n%s\n",
2771 cmd_pipeline_selector_group_member_delete_help);
2775 if ((strcmp(tokens[0], "pipeline") == 0) &&
2777 (strcmp(tokens[1], "selector") == 0) &&
2778 (strcmp(tokens[2], "show") == 0)) {
2779 snprintf(out, out_size, "\n%s\n",
2780 cmd_pipeline_selector_show_help);
2784 if ((strcmp(tokens[0], "pipeline") == 0) &&
2786 (strcmp(tokens[1], "commit") == 0)) {
2787 snprintf(out, out_size, "\n%s\n",
2788 cmd_pipeline_commit_help);
2792 if ((strcmp(tokens[0], "pipeline") == 0) &&
2794 (strcmp(tokens[1], "abort") == 0)) {
2795 snprintf(out, out_size, "\n%s\n",
2796 cmd_pipeline_abort_help);
2800 if ((strcmp(tokens[0], "pipeline") == 0) &&
2801 (n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
2802 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
2806 if ((strcmp(tokens[0], "pipeline") == 0) &&
2807 (n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
2808 snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
2812 if (!strcmp(tokens[0], "pipeline") &&
2813 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2814 && !strcmp(tokens[2], "profile")
2815 && !strcmp(tokens[3], "add")) {
2816 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2820 if (!strcmp(tokens[0], "pipeline") &&
2821 (n_tokens == 4) && !strcmp(tokens[1], "meter")
2822 && !strcmp(tokens[2], "profile")
2823 && !strcmp(tokens[3], "delete")) {
2824 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2828 if (!strcmp(tokens[0], "pipeline") &&
2829 (n_tokens == 3) && !strcmp(tokens[1], "meter")
2830 && !strcmp(tokens[2], "reset")) {
2831 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
2835 if (!strcmp(tokens[0], "pipeline") &&
2836 (n_tokens == 3) && !strcmp(tokens[1], "meter")
2837 && !strcmp(tokens[2], "set")) {
2838 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
2842 if (!strcmp(tokens[0], "pipeline") &&
2843 (n_tokens == 3) && !strcmp(tokens[1], "meter")
2844 && !strcmp(tokens[2], "stats")) {
2845 snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
2849 if ((strcmp(tokens[0], "pipeline") == 0) &&
2850 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
2851 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
2855 if ((n_tokens == 3) &&
2856 (strcmp(tokens[0], "thread") == 0) &&
2857 (strcmp(tokens[1], "pipeline") == 0)) {
2858 if (strcmp(tokens[2], "enable") == 0) {
2859 snprintf(out, out_size, "\n%s\n",
2860 cmd_thread_pipeline_enable_help);
2864 if (strcmp(tokens[2], "disable") == 0) {
2865 snprintf(out, out_size, "\n%s\n",
2866 cmd_thread_pipeline_disable_help);
2871 snprintf(out, out_size, "Invalid command\n");
2875 cli_process(char *in, char *out, size_t out_size, void *obj)
2877 char *tokens[CMD_MAX_TOKENS];
2878 uint32_t n_tokens = RTE_DIM(tokens);
2884 status = parse_tokenize_string(in, tokens, &n_tokens);
2886 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
2893 if (strcmp(tokens[0], "help") == 0) {
2894 cmd_help(tokens, n_tokens, out, out_size, obj);
2898 if (strcmp(tokens[0], "mempool") == 0) {
2899 cmd_mempool(tokens, n_tokens, out, out_size, obj);
2903 if (strcmp(tokens[0], "link") == 0) {
2904 if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
2905 cmd_link_show(tokens, n_tokens, out, out_size, obj);
2909 cmd_link(tokens, n_tokens, out, out_size, obj);
2913 if (strcmp(tokens[0], "ring") == 0) {
2914 cmd_ring(tokens, n_tokens, out, out_size, obj);
2918 if (strcmp(tokens[0], "tap") == 0) {
2919 cmd_tap(tokens, n_tokens, out, out_size, obj);
2923 if (strcmp(tokens[0], "pipeline") == 0) {
2924 if ((n_tokens >= 3) &&
2925 (strcmp(tokens[2], "create") == 0)) {
2926 cmd_pipeline_create(tokens, n_tokens, out, out_size,
2931 if ((n_tokens >= 4) &&
2932 (strcmp(tokens[2], "port") == 0) &&
2933 (strcmp(tokens[3], "in") == 0)) {
2934 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
2939 if ((n_tokens >= 4) &&
2940 (strcmp(tokens[2], "port") == 0) &&
2941 (strcmp(tokens[3], "out") == 0)) {
2942 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
2947 if ((n_tokens >= 3) &&
2948 (strcmp(tokens[2], "build") == 0)) {
2949 cmd_pipeline_build(tokens, n_tokens, out, out_size,
2954 if ((n_tokens >= 5) &&
2955 (strcmp(tokens[2], "table") == 0) &&
2956 (strcmp(tokens[4], "add") == 0)) {
2957 cmd_pipeline_table_add(tokens, n_tokens, out,
2962 if ((n_tokens >= 5) &&
2963 (strcmp(tokens[2], "table") == 0) &&
2964 (strcmp(tokens[4], "delete") == 0)) {
2965 cmd_pipeline_table_delete(tokens, n_tokens, out,
2970 if ((n_tokens >= 5) &&
2971 (strcmp(tokens[2], "table") == 0) &&
2972 (strcmp(tokens[4], "default") == 0)) {
2973 cmd_pipeline_table_default(tokens, n_tokens, out,
2978 if ((n_tokens >= 5) &&
2979 (strcmp(tokens[2], "table") == 0) &&
2980 (strcmp(tokens[4], "show") == 0)) {
2981 cmd_pipeline_table_show(tokens, n_tokens, out,
2986 if ((n_tokens >= 6) &&
2987 (strcmp(tokens[2], "selector") == 0) &&
2988 (strcmp(tokens[4], "group") == 0) &&
2989 (strcmp(tokens[5], "add") == 0)) {
2990 cmd_pipeline_selector_group_add(tokens, n_tokens, out,
2995 if ((n_tokens >= 6) &&
2996 (strcmp(tokens[2], "selector") == 0) &&
2997 (strcmp(tokens[4], "group") == 0) &&
2998 (strcmp(tokens[5], "delete") == 0)) {
2999 cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3004 if ((n_tokens >= 7) &&
3005 (strcmp(tokens[2], "selector") == 0) &&
3006 (strcmp(tokens[4], "group") == 0) &&
3007 (strcmp(tokens[5], "member") == 0) &&
3008 (strcmp(tokens[6], "add") == 0)) {
3009 cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3014 if ((n_tokens >= 7) &&
3015 (strcmp(tokens[2], "selector") == 0) &&
3016 (strcmp(tokens[4], "group") == 0) &&
3017 (strcmp(tokens[5], "member") == 0) &&
3018 (strcmp(tokens[6], "delete") == 0)) {
3019 cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3024 if ((n_tokens >= 5) &&
3025 (strcmp(tokens[2], "selector") == 0) &&
3026 (strcmp(tokens[4], "show") == 0)) {
3027 cmd_pipeline_selector_show(tokens, n_tokens, out,
3032 if ((n_tokens >= 3) &&
3033 (strcmp(tokens[2], "commit") == 0)) {
3034 cmd_pipeline_commit(tokens, n_tokens, out,
3039 if ((n_tokens >= 3) &&
3040 (strcmp(tokens[2], "abort") == 0)) {
3041 cmd_pipeline_abort(tokens, n_tokens, out,
3046 if ((n_tokens >= 3) &&
3047 (strcmp(tokens[2], "regrd") == 0)) {
3048 cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
3052 if ((n_tokens >= 3) &&
3053 (strcmp(tokens[2], "regwr") == 0)) {
3054 cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
3058 if ((n_tokens >= 6) &&
3059 (strcmp(tokens[2], "meter") == 0) &&
3060 (strcmp(tokens[3], "profile") == 0) &&
3061 (strcmp(tokens[5], "add") == 0)) {
3062 cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3066 if ((n_tokens >= 6) &&
3067 (strcmp(tokens[2], "meter") == 0) &&
3068 (strcmp(tokens[3], "profile") == 0) &&
3069 (strcmp(tokens[5], "delete") == 0)) {
3070 cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3074 if ((n_tokens >= 9) &&
3075 (strcmp(tokens[2], "meter") == 0) &&
3076 (strcmp(tokens[8], "reset") == 0)) {
3077 cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3081 if ((n_tokens >= 9) &&
3082 (strcmp(tokens[2], "meter") == 0) &&
3083 (strcmp(tokens[8], "set") == 0)) {
3084 cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3088 if ((n_tokens >= 9) &&
3089 (strcmp(tokens[2], "meter") == 0) &&
3090 (strcmp(tokens[8], "stats") == 0)) {
3091 cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3095 if ((n_tokens >= 3) &&
3096 (strcmp(tokens[2], "stats") == 0)) {
3097 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
3103 if (strcmp(tokens[0], "thread") == 0) {
3104 if ((n_tokens >= 5) &&
3105 (strcmp(tokens[4], "enable") == 0)) {
3106 cmd_thread_pipeline_enable(tokens, n_tokens,
3107 out, out_size, obj);
3111 if ((n_tokens >= 5) &&
3112 (strcmp(tokens[4], "disable") == 0)) {
3113 cmd_thread_pipeline_disable(tokens, n_tokens,
3114 out, out_size, obj);
3119 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
3123 cli_script_process(const char *file_name,
3124 size_t msg_in_len_max,
3125 size_t msg_out_len_max,
3128 char *msg_in = NULL, *msg_out = NULL;
3131 /* Check input arguments */
3132 if ((file_name == NULL) ||
3133 (strlen(file_name) == 0) ||
3134 (msg_in_len_max == 0) ||
3135 (msg_out_len_max == 0))
3138 msg_in = malloc(msg_in_len_max + 1);
3139 msg_out = malloc(msg_out_len_max + 1);
3140 if ((msg_in == NULL) ||
3141 (msg_out == NULL)) {
3147 /* Open input file */
3148 f = fopen(file_name, "r");
3157 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
3160 printf("%s", msg_in);
3168 if (strlen(msg_out))
3169 printf("%s", msg_out);