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_source_sink.h>
14 #include <rte_swx_pipeline.h>
15 #include <rte_swx_ctl.h>
22 #ifndef CMD_MAX_TOKENS
23 #define CMD_MAX_TOKENS 256
26 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
27 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
28 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
29 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
30 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
31 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
32 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
33 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
34 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
35 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
36 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
38 #define skip_white_spaces(pos) \
40 __typeof__(pos) _p = (pos); \
41 for ( ; isspace(*_p); _p++) \
47 parser_read_uint64(uint64_t *value, const char *p)
52 p = skip_white_spaces(p);
56 val = strtoul(p, &next, 10);
78 p = skip_white_spaces(p);
87 parser_read_uint32(uint32_t *value, const char *p)
90 int ret = parser_read_uint64(&val, p);
103 parser_read_uint16(uint16_t *value, const char *p)
106 int ret = parser_read_uint64(&val, p);
111 if (val > UINT16_MAX)
118 #define PARSE_DELIMITER " \f\n\r\t\v"
121 parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
125 if ((string == NULL) ||
130 for (i = 0; i < *n_tokens; i++) {
131 tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
132 if (tokens[i] == NULL)
136 if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
146 if ((strlen(in) && index("!#%;", in[0])) ||
147 (strncmp(in, "//", 2) == 0) ||
148 (strncmp(in, "--", 2) == 0))
154 static const char cmd_mempool_help[] =
155 "mempool <mempool_name>\n"
156 " buffer <buffer_size>\n"
157 " pool <pool_size>\n"
158 " cache <cache_size>\n"
162 cmd_mempool(char **tokens,
168 struct mempool_params p;
170 struct mempool *mempool;
172 if (n_tokens != 10) {
173 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
179 if (strcmp(tokens[2], "buffer") != 0) {
180 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
184 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
185 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
189 if (strcmp(tokens[4], "pool") != 0) {
190 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
194 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
195 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
199 if (strcmp(tokens[6], "cache") != 0) {
200 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
204 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
205 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
209 if (strcmp(tokens[8], "cpu") != 0) {
210 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
214 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
215 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
219 mempool = mempool_create(obj, name, &p);
220 if (mempool == NULL) {
221 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
226 static const char cmd_link_help[] =
228 " dev <device_name> | port <port_id>\n"
229 " rxq <n_queues> <queue_size> <mempool_name>\n"
230 " txq <n_queues> <queue_size>\n"
231 " promiscuous on | off\n"
232 " [rss <qid_0> ... <qid_n>]\n";
235 cmd_link(char **tokens,
241 struct link_params p;
242 struct link_params_rss rss;
246 memset(&p, 0, sizeof(p));
248 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
249 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
254 if (strcmp(tokens[2], "dev") == 0)
255 p.dev_name = tokens[3];
256 else if (strcmp(tokens[2], "port") == 0) {
259 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
260 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
264 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
268 if (strcmp(tokens[4], "rxq") != 0) {
269 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
273 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
274 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
277 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
278 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
282 p.rx.mempool_name = tokens[7];
284 if (strcmp(tokens[8], "txq") != 0) {
285 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
289 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
290 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
294 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
295 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
299 if (strcmp(tokens[11], "promiscuous") != 0) {
300 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
304 if (strcmp(tokens[12], "on") == 0)
306 else if (strcmp(tokens[12], "off") == 0)
309 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
316 uint32_t queue_id, i;
318 if (strcmp(tokens[13], "rss") != 0) {
319 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
326 for (i = 14; i < n_tokens; i++) {
327 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
328 snprintf(out, out_size, MSG_ARG_INVALID,
333 rss.queue_id[rss.n_queues] = queue_id;
338 link = link_create(obj, name, &p);
340 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
345 /* Print the link stats and info */
347 print_link_info(struct link *link, char *out, size_t out_size)
349 struct rte_eth_stats stats;
350 struct rte_ether_addr mac_addr;
351 struct rte_eth_link eth_link;
355 memset(&stats, 0, sizeof(stats));
356 rte_eth_stats_get(link->port_id, &stats);
358 ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
360 snprintf(out, out_size, "\n%s: MAC address get failed: %s",
361 link->name, rte_strerror(-ret));
365 ret = rte_eth_link_get(link->port_id, ð_link);
367 snprintf(out, out_size, "\n%s: link get failed: %s",
368 link->name, rte_strerror(-ret));
372 rte_eth_dev_get_mtu(link->port_id, &mtu);
374 snprintf(out, out_size,
376 "%s: flags=<%s> mtu %u\n"
377 "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
378 "\tport# %u speed %s\n"
379 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
380 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
381 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
382 "\tTX errors %" PRIu64"\n",
384 eth_link.link_status == 0 ? "DOWN" : "UP",
386 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
387 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
388 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
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_pipeline_create_help[] =
448 "pipeline <pipeline_name> create <numa_node>\n";
451 cmd_pipeline_create(char **tokens,
462 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
468 if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
469 snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
473 p = pipeline_create(obj, name, (int)numa_node);
475 snprintf(out, out_size, "pipeline create error.");
480 static const char cmd_pipeline_port_in_help[] =
481 "pipeline <pipeline_name> port in <port_id>\n"
482 " link <link_name> rxq <queue_id> bsz <burst_size>\n"
483 " | source <mempool_name> <file_name>\n";
486 cmd_pipeline_port_in(char **tokens,
494 uint32_t port_id = 0, t0;
497 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
501 p = pipeline_find(obj, tokens[1]);
503 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
507 if (strcmp(tokens[2], "port") != 0) {
508 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
512 if (strcmp(tokens[3], "in") != 0) {
513 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
517 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
518 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
524 if (strcmp(tokens[t0], "link") == 0) {
525 struct rte_swx_port_ethdev_reader_params params;
528 if (n_tokens < t0 + 6) {
529 snprintf(out, out_size, MSG_ARG_MISMATCH,
530 "pipeline port in link");
534 link = link_find(obj, tokens[t0 + 1]);
536 snprintf(out, out_size, MSG_ARG_INVALID,
540 params.dev_name = link->dev_name;
542 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
543 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
547 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
548 snprintf(out, out_size, MSG_ARG_INVALID,
553 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
558 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
559 snprintf(out, out_size, MSG_ARG_INVALID,
566 status = rte_swx_pipeline_port_in_config(p->p,
570 } else if (strcmp(tokens[t0], "source") == 0) {
571 struct rte_swx_port_source_params params;
574 if (n_tokens < t0 + 3) {
575 snprintf(out, out_size, MSG_ARG_MISMATCH,
576 "pipeline port in source");
580 mp = mempool_find(obj, tokens[t0 + 1]);
582 snprintf(out, out_size, MSG_ARG_INVALID,
588 params.file_name = tokens[t0 + 2];
592 status = rte_swx_pipeline_port_in_config(p->p,
597 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
602 snprintf(out, out_size, "port in error.");
606 if (n_tokens != t0) {
607 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
612 static const char cmd_pipeline_port_out_help[] =
613 "pipeline <pipeline_name> port out <port_id>\n"
614 " link <link_name> txq <txq_id> bsz <burst_size>\n"
615 " | sink <file_name> | none\n";
618 cmd_pipeline_port_out(char **tokens,
626 uint32_t port_id = 0, t0;
629 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
633 p = pipeline_find(obj, tokens[1]);
635 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
639 if (strcmp(tokens[2], "port") != 0) {
640 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
644 if (strcmp(tokens[3], "out") != 0) {
645 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
649 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
650 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
656 if (strcmp(tokens[t0], "link") == 0) {
657 struct rte_swx_port_ethdev_writer_params params;
660 if (n_tokens < t0 + 6) {
661 snprintf(out, out_size, MSG_ARG_MISMATCH,
662 "pipeline port out link");
666 link = link_find(obj, tokens[t0 + 1]);
668 snprintf(out, out_size, MSG_ARG_INVALID,
672 params.dev_name = link->dev_name;
674 if (strcmp(tokens[t0 + 2], "txq") != 0) {
675 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
679 if (parser_read_uint16(¶ms.queue_id, tokens[t0 + 3]) != 0) {
680 snprintf(out, out_size, MSG_ARG_INVALID,
685 if (strcmp(tokens[t0 + 4], "bsz") != 0) {
686 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
690 if (parser_read_uint32(¶ms.burst_size, tokens[t0 + 5])) {
691 snprintf(out, out_size, MSG_ARG_INVALID,
698 status = rte_swx_pipeline_port_out_config(p->p,
702 } else if (strcmp(tokens[t0], "sink") == 0) {
703 struct rte_swx_port_sink_params params;
705 params.file_name = strcmp(tokens[t0 + 1], "none") ?
706 tokens[t0 + 1] : NULL;
710 status = rte_swx_pipeline_port_out_config(p->p,
715 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
720 snprintf(out, out_size, "port out error.");
724 if (n_tokens != t0) {
725 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
730 static const char cmd_pipeline_build_help[] =
731 "pipeline <pipeline_name> build <spec_file>\n";
734 cmd_pipeline_build(char **tokens,
740 struct pipeline *p = NULL;
747 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
751 p = pipeline_find(obj, tokens[1]);
753 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
757 spec = fopen(tokens[3], "r");
759 snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
763 status = rte_swx_pipeline_build_from_spec(p->p,
769 snprintf(out, out_size, "Error %d at line %u: %s\n.",
770 status, err_line, err_msg);
774 p->ctl = rte_swx_ctl_pipeline_create(p->p);
776 snprintf(out, out_size, "Pipeline control create failed.");
777 rte_swx_pipeline_free(p->p);
783 table_entry_free(struct rte_swx_table_entry *entry)
789 free(entry->key_mask);
790 free(entry->action_data);
794 static const char cmd_pipeline_table_update_help[] =
795 "pipeline <pipeline_name> table <table_name> update <file_name_add> "
796 "<file_name_delete> <file_name_default>";
799 cmd_pipeline_table_update(char **tokens,
806 char *pipeline_name, *table_name, *line = NULL;
807 char *file_name_add, *file_name_delete, *file_name_default;
808 FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL;
813 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
817 pipeline_name = tokens[1];
818 p = pipeline_find(obj, pipeline_name);
820 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
824 if (strcmp(tokens[2], "table") != 0) {
825 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
829 table_name = tokens[3];
831 if (strcmp(tokens[4], "update") != 0) {
832 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update");
836 file_name_add = tokens[5];
837 file_name_delete = tokens[6];
838 file_name_default = tokens[7];
841 if (strcmp(file_name_add, "none")) {
842 file_add = fopen(file_name_add, "r");
844 snprintf(out, out_size, "Cannot open file %s",
850 if (strcmp(file_name_delete, "none")) {
851 file_delete = fopen(file_name_delete, "r");
853 snprintf(out, out_size, "Cannot open file %s",
859 if (strcmp(file_name_default, "none")) {
860 file_default = fopen(file_name_default, "r");
862 snprintf(out, out_size, "Cannot open file %s",
868 if (!file_add && !file_delete && !file_default) {
869 snprintf(out, out_size, "Nothing to be done.");
873 /* Buffer allocation. */
876 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
882 for (line_id = 1; ; line_id++) {
883 struct rte_swx_table_entry *entry;
885 if (fgets(line, 2048, file_add) == NULL)
888 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
892 snprintf(out, out_size, MSG_FILE_ERR,
893 file_name_add, line_id);
897 status = rte_swx_ctl_pipeline_table_entry_add(p->ctl,
900 table_entry_free(entry);
902 snprintf(out, out_size,
903 "Invalid entry in file %s at line %u",
904 file_name_add, line_id);
912 for (line_id = 1; ; line_id++) {
913 struct rte_swx_table_entry *entry;
915 if (fgets(line, 2048, file_delete) == NULL)
918 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
922 snprintf(out, out_size, MSG_FILE_ERR,
923 file_name_delete, line_id);
927 status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl,
930 table_entry_free(entry);
932 snprintf(out, out_size,
933 "Invalid entry in file %s at line %u",
934 file_name_delete, line_id);
941 for (line_id = 1; ; line_id++) {
942 struct rte_swx_table_entry *entry;
944 if (fgets(line, 2048, file_default) == NULL)
947 entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
951 snprintf(out, out_size, MSG_FILE_ERR,
952 file_name_default, line_id);
956 status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl,
959 table_entry_free(entry);
961 snprintf(out, out_size,
962 "Invalid entry in file %s at line %u",
963 file_name_default, line_id);
968 status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
970 snprintf(out, out_size, "Commit failed.");
975 rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
983 fclose(file_default);
987 rte_swx_ctl_pipeline_abort(p->ctl);
994 fclose(file_default);
997 static const char cmd_pipeline_stats_help[] =
998 "pipeline <pipeline_name> stats\n";
1001 cmd_pipeline_stats(char **tokens,
1007 struct rte_swx_ctl_pipeline_info info;
1012 if (n_tokens != 3) {
1013 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1017 p = pipeline_find(obj, tokens[1]);
1018 if (!p || !p->ctl) {
1019 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1023 if (strcmp(tokens[2], "stats")) {
1024 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1028 status = rte_swx_ctl_pipeline_info_get(p->p, &info);
1030 snprintf(out, out_size, "Pipeline info get error.");
1034 snprintf(out, out_size, "Input ports:\n");
1035 out_size -= strlen(out);
1038 for (i = 0; i < info.n_ports_in; i++) {
1039 struct rte_swx_port_in_stats stats;
1041 rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
1043 snprintf(out, out_size, "\tPort %u:"
1046 " empty %" PRIu64 "\n",
1047 i, stats.n_pkts, stats.n_bytes, stats.n_empty);
1048 out_size -= strlen(out);
1052 snprintf(out, out_size, "Output ports:\n");
1053 out_size -= strlen(out);
1056 for (i = 0; i < info.n_ports_out; i++) {
1057 struct rte_swx_port_out_stats stats;
1059 rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
1061 snprintf(out, out_size, "\tPort %u:"
1063 " bytes %" PRIu64 "\n",
1064 i, stats.n_pkts, stats.n_bytes);
1065 out_size -= strlen(out);
1070 static const char cmd_thread_pipeline_enable_help[] =
1071 "thread <thread_id> pipeline <pipeline_name> enable\n";
1074 cmd_thread_pipeline_enable(char **tokens,
1080 char *pipeline_name;
1085 if (n_tokens != 5) {
1086 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1090 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
1091 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
1095 if (strcmp(tokens[2], "pipeline") != 0) {
1096 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
1100 pipeline_name = tokens[3];
1101 p = pipeline_find(obj, pipeline_name);
1102 if (!p || !p->ctl) {
1103 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1107 if (strcmp(tokens[4], "enable") != 0) {
1108 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1112 status = thread_pipeline_enable(thread_id, obj, pipeline_name);
1114 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
1119 static const char cmd_thread_pipeline_disable_help[] =
1120 "thread <thread_id> pipeline <pipeline_name> disable\n";
1123 cmd_thread_pipeline_disable(char **tokens,
1130 char *pipeline_name;
1134 if (n_tokens != 5) {
1135 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1139 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
1140 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
1144 if (strcmp(tokens[2], "pipeline") != 0) {
1145 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
1149 pipeline_name = tokens[3];
1150 p = pipeline_find(obj, pipeline_name);
1151 if (!p || !p->ctl) {
1152 snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1156 if (strcmp(tokens[4], "disable") != 0) {
1157 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1161 status = thread_pipeline_disable(thread_id, obj, pipeline_name);
1163 snprintf(out, out_size, MSG_CMD_FAIL,
1164 "thread pipeline disable");
1170 cmd_help(char **tokens,
1174 void *arg __rte_unused)
1179 if (n_tokens == 0) {
1180 snprintf(out, out_size,
1181 "Type 'help <command>' for command details.\n\n"
1182 "List of commands:\n"
1185 "\tpipeline create\n"
1186 "\tpipeline port in\n"
1187 "\tpipeline port out\n"
1188 "\tpipeline build\n"
1189 "\tpipeline table update\n"
1190 "\tpipeline stats\n"
1191 "\tthread pipeline enable\n"
1192 "\tthread pipeline disable\n\n");
1196 if (strcmp(tokens[0], "mempool") == 0) {
1197 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
1201 if (strcmp(tokens[0], "link") == 0) {
1202 snprintf(out, out_size, "\n%s\n", cmd_link_help);
1206 if ((strcmp(tokens[0], "pipeline") == 0) &&
1207 (n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
1208 snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
1212 if ((strcmp(tokens[0], "pipeline") == 0) &&
1213 (n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
1214 if (strcmp(tokens[2], "in") == 0) {
1215 snprintf(out, out_size, "\n%s\n",
1216 cmd_pipeline_port_in_help);
1220 if (strcmp(tokens[2], "out") == 0) {
1221 snprintf(out, out_size, "\n%s\n",
1222 cmd_pipeline_port_out_help);
1227 if ((strcmp(tokens[0], "pipeline") == 0) &&
1228 (n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
1229 snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
1233 if ((strcmp(tokens[0], "pipeline") == 0) &&
1235 (strcmp(tokens[1], "table") == 0) &&
1236 (strcmp(tokens[2], "update") == 0)) {
1237 snprintf(out, out_size, "\n%s\n",
1238 cmd_pipeline_table_update_help);
1242 if ((strcmp(tokens[0], "pipeline") == 0) &&
1243 (n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
1244 snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
1248 if ((n_tokens == 3) &&
1249 (strcmp(tokens[0], "thread") == 0) &&
1250 (strcmp(tokens[1], "pipeline") == 0)) {
1251 if (strcmp(tokens[2], "enable") == 0) {
1252 snprintf(out, out_size, "\n%s\n",
1253 cmd_thread_pipeline_enable_help);
1257 if (strcmp(tokens[2], "disable") == 0) {
1258 snprintf(out, out_size, "\n%s\n",
1259 cmd_thread_pipeline_disable_help);
1264 snprintf(out, out_size, "Invalid command\n");
1268 cli_process(char *in, char *out, size_t out_size, void *obj)
1270 char *tokens[CMD_MAX_TOKENS];
1271 uint32_t n_tokens = RTE_DIM(tokens);
1277 status = parse_tokenize_string(in, tokens, &n_tokens);
1279 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
1286 if (strcmp(tokens[0], "help") == 0) {
1287 cmd_help(tokens, n_tokens, out, out_size, obj);
1291 if (strcmp(tokens[0], "mempool") == 0) {
1292 cmd_mempool(tokens, n_tokens, out, out_size, obj);
1296 if (strcmp(tokens[0], "link") == 0) {
1297 if (strcmp(tokens[1], "show") == 0) {
1298 cmd_link_show(tokens, n_tokens, out, out_size, obj);
1302 cmd_link(tokens, n_tokens, out, out_size, obj);
1306 if (strcmp(tokens[0], "pipeline") == 0) {
1307 if ((n_tokens >= 3) &&
1308 (strcmp(tokens[2], "create") == 0)) {
1309 cmd_pipeline_create(tokens, n_tokens, out, out_size,
1314 if ((n_tokens >= 4) &&
1315 (strcmp(tokens[2], "port") == 0) &&
1316 (strcmp(tokens[3], "in") == 0)) {
1317 cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
1322 if ((n_tokens >= 4) &&
1323 (strcmp(tokens[2], "port") == 0) &&
1324 (strcmp(tokens[3], "out") == 0)) {
1325 cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
1330 if ((n_tokens >= 3) &&
1331 (strcmp(tokens[2], "build") == 0)) {
1332 cmd_pipeline_build(tokens, n_tokens, out, out_size,
1337 if ((n_tokens >= 3) &&
1338 (strcmp(tokens[2], "table") == 0)) {
1339 cmd_pipeline_table_update(tokens, n_tokens, out,
1344 if ((n_tokens >= 3) &&
1345 (strcmp(tokens[2], "stats") == 0)) {
1346 cmd_pipeline_stats(tokens, n_tokens, out, out_size,
1352 if (strcmp(tokens[0], "thread") == 0) {
1353 if ((n_tokens >= 5) &&
1354 (strcmp(tokens[4], "enable") == 0)) {
1355 cmd_thread_pipeline_enable(tokens, n_tokens,
1356 out, out_size, obj);
1360 if ((n_tokens >= 5) &&
1361 (strcmp(tokens[4], "disable") == 0)) {
1362 cmd_thread_pipeline_disable(tokens, n_tokens,
1363 out, out_size, obj);
1368 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
1372 cli_script_process(const char *file_name,
1373 size_t msg_in_len_max,
1374 size_t msg_out_len_max,
1377 char *msg_in = NULL, *msg_out = NULL;
1380 /* Check input arguments */
1381 if ((file_name == NULL) ||
1382 (strlen(file_name) == 0) ||
1383 (msg_in_len_max == 0) ||
1384 (msg_out_len_max == 0))
1387 msg_in = malloc(msg_in_len_max + 1);
1388 msg_out = malloc(msg_out_len_max + 1);
1389 if ((msg_in == NULL) ||
1390 (msg_out == NULL)) {
1396 /* Open input file */
1397 f = fopen(file_name, "r");
1406 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
1409 printf("%s", msg_in);
1417 if (strlen(msg_out))
1418 printf("%s", msg_out);