1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_cycles.h>
12 #include <rte_ethdev.h>
16 #include "cryptodev.h"
27 #ifndef CMD_MAX_TOKENS
28 #define CMD_MAX_TOKENS 256
31 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
32 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
33 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
34 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
35 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
36 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
37 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
38 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
39 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
40 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
41 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
46 if ((strlen(in) && index("!#%;", in[0])) ||
47 (strncmp(in, "//", 2) == 0) ||
48 (strncmp(in, "--", 2) == 0))
54 static const char cmd_mempool_help[] =
55 "mempool <mempool_name>\n"
56 " buffer <buffer_size>\n"
58 " cache <cache_size>\n"
62 cmd_mempool(char **tokens,
67 struct mempool_params p;
69 struct mempool *mempool;
72 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
78 if (strcmp(tokens[2], "buffer") != 0) {
79 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
83 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
84 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
88 if (strcmp(tokens[4], "pool") != 0) {
89 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
93 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
94 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
98 if (strcmp(tokens[6], "cache") != 0) {
99 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
103 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
104 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
108 if (strcmp(tokens[8], "cpu") != 0) {
109 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
113 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
114 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
118 mempool = mempool_create(name, &p);
119 if (mempool == NULL) {
120 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
125 static const char cmd_link_help[] =
127 " dev <device_name> | port <port_id>\n"
128 " rxq <n_queues> <queue_size> <mempool_name>\n"
129 " txq <n_queues> <queue_size>\n"
130 " promiscuous on | off\n"
131 " [rss <qid_0> ... <qid_n>]\n";
134 cmd_link(char **tokens,
139 struct link_params p;
140 struct link_params_rss rss;
144 memset(&p, 0, sizeof(p));
146 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
147 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
152 if (strcmp(tokens[2], "dev") == 0)
153 p.dev_name = tokens[3];
154 else if (strcmp(tokens[2], "port") == 0) {
157 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
158 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
162 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
166 if (strcmp(tokens[4], "rxq") != 0) {
167 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
171 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
172 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
175 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
176 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
180 p.rx.mempool_name = tokens[7];
182 if (strcmp(tokens[8], "txq") != 0) {
183 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
187 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
188 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
192 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
193 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
197 if (strcmp(tokens[11], "promiscuous") != 0) {
198 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
202 if (strcmp(tokens[12], "on") == 0)
204 else if (strcmp(tokens[12], "off") == 0)
207 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
214 uint32_t queue_id, i;
216 if (strcmp(tokens[13], "rss") != 0) {
217 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
224 for (i = 14; i < n_tokens; i++) {
225 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
226 snprintf(out, out_size, MSG_ARG_INVALID,
231 rss.queue_id[rss.n_queues] = queue_id;
236 link = link_create(name, &p);
238 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
243 /* Print the link stats and info */
245 print_link_info(struct link *link, char *out, size_t out_size)
247 struct rte_eth_stats stats;
248 struct rte_ether_addr mac_addr;
249 struct rte_eth_link eth_link;
252 memset(&stats, 0, sizeof(stats));
253 rte_eth_stats_get(link->port_id, &stats);
255 rte_eth_macaddr_get(link->port_id, &mac_addr);
256 rte_eth_link_get(link->port_id, ð_link);
257 rte_eth_dev_get_mtu(link->port_id, &mtu);
259 snprintf(out, out_size,
261 "%s: flags=<%s> mtu %u\n"
262 "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
263 "\tport# %u speed %u Mbps\n"
264 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
265 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
266 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
267 "\tTX errors %" PRIu64"\n",
269 eth_link.link_status == 0 ? "DOWN" : "UP",
271 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
272 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
273 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
289 * link show [<link_name>]
292 cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
297 if (n_tokens != 2 && n_tokens != 3) {
298 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
303 link = link_next(NULL);
305 while (link != NULL) {
306 out_size = out_size - strlen(out);
307 out = &out[strlen(out)];
309 print_link_info(link, out, out_size);
310 link = link_next(link);
313 out_size = out_size - strlen(out);
314 out = &out[strlen(out)];
316 link_name = tokens[2];
317 link = link_find(link_name);
320 snprintf(out, out_size, MSG_ARG_INVALID,
321 "Link does not exist");
324 print_link_info(link, out, out_size);
328 static const char cmd_swq_help[] =
334 cmd_swq(char **tokens,
344 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
350 if (strcmp(tokens[2], "size") != 0) {
351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
355 if (parser_read_uint32(&p.size, tokens[3]) != 0) {
356 snprintf(out, out_size, MSG_ARG_INVALID, "size");
360 if (strcmp(tokens[4], "cpu") != 0) {
361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
365 if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
366 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
370 swq = swq_create(name, &p);
372 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
377 static const char cmd_tmgr_subport_profile_help[] =
378 "tmgr subport profile\n"
379 " <tb_rate> <tb_size>\n"
380 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
381 " <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
382 " <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
386 cmd_tmgr_subport_profile(char **tokens,
391 struct rte_sched_subport_params p;
394 if (n_tokens != 19) {
395 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
399 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
400 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
404 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
405 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
409 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
410 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
411 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
415 if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) {
416 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
420 status = tmgr_subport_profile_add(&p);
422 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
427 static const char cmd_tmgr_pipe_profile_help[] =
428 "tmgr pipe profile\n"
429 " <tb_rate> <tb_size>\n"
430 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
431 " <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
432 " <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
435 " <wrr_weight0..3>\n";
438 cmd_tmgr_pipe_profile(char **tokens,
443 struct rte_sched_pipe_params p;
446 if (n_tokens != 24) {
447 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
451 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
452 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
456 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
457 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
461 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
462 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
463 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
467 if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) {
468 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
472 if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
473 snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
477 for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
478 if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
479 snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
483 status = tmgr_pipe_profile_add(&p);
485 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
490 static const char cmd_tmgr_help[] =
493 " spp <n_subports_per_port>\n"
494 " pps <n_pipes_per_subport>\n"
495 " qsize <qsize_tc0> <qsize_tc1> <qsize_tc2>"
496 " <qsize_tc3> <qsize_tc4> <qsize_tc5> <qsize_tc6>"
497 " <qsize_tc7> <qsize_tc8> <qsize_tc9> <qsize_tc10>"
498 " <qsize_tc11> <qsize_tc12>\n"
499 " fo <frame_overhead>\n"
504 cmd_tmgr(char **tokens,
509 struct tmgr_port_params p;
511 struct tmgr_port *tmgr_port;
514 if (n_tokens != 28) {
515 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
521 if (strcmp(tokens[2], "rate") != 0) {
522 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
526 if (parser_read_uint32(&p.rate, tokens[3]) != 0) {
527 snprintf(out, out_size, MSG_ARG_INVALID, "rate");
531 if (strcmp(tokens[4], "spp") != 0) {
532 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
536 if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
537 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
541 if (strcmp(tokens[6], "pps") != 0) {
542 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
546 if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
547 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
551 if (strcmp(tokens[8], "qsize") != 0) {
552 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize");
556 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
557 if (parser_read_uint16(&p.qsize[i], tokens[9 + i]) != 0) {
558 snprintf(out, out_size, MSG_ARG_INVALID, "qsize");
562 if (strcmp(tokens[22], "fo") != 0) {
563 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
567 if (parser_read_uint32(&p.frame_overhead, tokens[23]) != 0) {
568 snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
572 if (strcmp(tokens[24], "mtu") != 0) {
573 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
577 if (parser_read_uint32(&p.mtu, tokens[25]) != 0) {
578 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
582 if (strcmp(tokens[26], "cpu") != 0) {
583 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
587 if (parser_read_uint32(&p.cpu_id, tokens[27]) != 0) {
588 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
592 tmgr_port = tmgr_port_create(name, &p);
593 if (tmgr_port == NULL) {
594 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
599 static const char cmd_tmgr_subport_help[] =
600 "tmgr <tmgr_name> subport <subport_id>\n"
601 " profile <subport_profile_id>\n";
604 cmd_tmgr_subport(char **tokens,
609 uint32_t subport_id, subport_profile_id;
614 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
620 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
621 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
625 if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
626 snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
630 status = tmgr_subport_config(name, subport_id, subport_profile_id);
632 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
638 static const char cmd_tmgr_subport_pipe_help[] =
639 "tmgr <tmgr_name> subport <subport_id> pipe\n"
640 " from <pipe_id_first> to <pipe_id_last>\n"
641 " profile <pipe_profile_id>\n";
644 cmd_tmgr_subport_pipe(char **tokens,
649 uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
653 if (n_tokens != 11) {
654 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
660 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
661 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
665 if (strcmp(tokens[4], "pipe") != 0) {
666 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
670 if (strcmp(tokens[5], "from") != 0) {
671 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
675 if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
676 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
680 if (strcmp(tokens[7], "to") != 0) {
681 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
685 if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
686 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
690 if (strcmp(tokens[9], "profile") != 0) {
691 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
695 if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
696 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
700 status = tmgr_pipe_config(name, subport_id, pipe_id_first,
701 pipe_id_last, pipe_profile_id);
703 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
709 static const char cmd_tap_help[] =
713 cmd_tap(char **tokens,
722 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
728 tap = tap_create(name);
730 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
735 static const char cmd_kni_help[] =
737 " link <link_name>\n"
738 " mempool <mempool_name>\n"
739 " [thread <thread_id>]\n";
742 cmd_kni(char **tokens,
751 memset(&p, 0, sizeof(p));
752 if ((n_tokens != 6) && (n_tokens != 8)) {
753 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
759 if (strcmp(tokens[2], "link") != 0) {
760 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link");
764 p.link_name = tokens[3];
766 if (strcmp(tokens[4], "mempool") != 0) {
767 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool");
771 p.mempool_name = tokens[5];
774 if (strcmp(tokens[6], "thread") != 0) {
775 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread");
779 if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) {
780 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
788 kni = kni_create(name, &p);
790 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
795 static const char cmd_cryptodev_help[] =
796 "cryptodev <cryptodev_name>\n"
797 " dev <device_name> | dev_id <device_id>\n"
798 " queue <n_queues> <queue_size>\n"
799 " max_sessions <n_sessions>";
802 cmd_cryptodev(char **tokens,
807 struct cryptodev_params params;
810 memset(¶ms, 0, sizeof(params));
812 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
818 if (strcmp(tokens[2], "dev") == 0)
819 params.dev_name = tokens[3];
820 else if (strcmp(tokens[2], "dev_id") == 0) {
821 if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
822 snprintf(out, out_size, MSG_ARG_INVALID,
827 snprintf(out, out_size, MSG_ARG_INVALID,
832 if (strcmp(tokens[4], "queue")) {
833 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
838 if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
839 snprintf(out, out_size, MSG_ARG_INVALID,
844 if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
845 snprintf(out, out_size, MSG_ARG_INVALID,
850 if (strcmp(tokens[7], "max_sessions")) {
851 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
856 if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
857 snprintf(out, out_size, MSG_ARG_INVALID,
862 if (cryptodev_create(name, ¶ms) == NULL) {
863 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
868 static const char cmd_port_in_action_profile_help[] =
869 "port in action profile <profile_name>\n"
870 " [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
871 " [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
874 cmd_port_in_action_profile(char **tokens,
879 struct port_in_action_profile_params p;
880 struct port_in_action_profile *ap;
884 memset(&p, 0, sizeof(p));
887 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
891 if (strcmp(tokens[1], "in") != 0) {
892 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
896 if (strcmp(tokens[2], "action") != 0) {
897 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
901 if (strcmp(tokens[3], "profile") != 0) {
902 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
910 if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
913 if (n_tokens < t0 + 10) {
914 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
918 if (strcmp(tokens[t0 + 1], "match") == 0)
919 p.fltr.filter_on_match = 1;
920 else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
921 p.fltr.filter_on_match = 0;
923 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
927 if (strcmp(tokens[t0 + 2], "offset") != 0) {
928 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
932 if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
933 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
937 if (strcmp(tokens[t0 + 4], "mask") != 0) {
938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
942 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
943 if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
944 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
945 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
949 if (strcmp(tokens[t0 + 6], "key") != 0) {
950 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
954 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
955 if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
956 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
957 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
961 if (strcmp(tokens[t0 + 8], "port") != 0) {
962 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
966 if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
967 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
971 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
975 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
978 if (n_tokens < t0 + 22) {
979 snprintf(out, out_size, MSG_ARG_MISMATCH,
980 "port in action profile balance");
984 if (strcmp(tokens[t0 + 1], "offset") != 0) {
985 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
989 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
990 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
994 if (strcmp(tokens[t0 + 3], "mask") != 0) {
995 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
999 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1000 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1001 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1005 if (strcmp(tokens[t0 + 5], "port") != 0) {
1006 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1010 for (i = 0; i < 16; i++)
1011 if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
1012 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1016 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
1020 if (t0 < n_tokens) {
1021 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1025 ap = port_in_action_profile_create(name, &p);
1027 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1033 static const char cmd_table_action_profile_help[] =
1034 "table action profile <profile_name>\n"
1036 " offset <ip_offset>\n"
1038 " [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
1039 " [meter srtcm | trtcm\n"
1041 " stats none | pkts | bytes | both]\n"
1042 " [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
1043 " [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
1044 " vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
1046 " proto udp | tcp]\n"
1047 " [ttl drop | fwd\n"
1048 " stats none | pkts]\n"
1049 " [stats pkts | bytes | both]\n"
1051 " [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
1056 cmd_table_action_profile(char **tokens,
1061 struct table_action_profile_params p;
1062 struct table_action_profile *ap;
1066 memset(&p, 0, sizeof(p));
1069 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1073 if (strcmp(tokens[1], "action") != 0) {
1074 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1078 if (strcmp(tokens[2], "profile") != 0) {
1079 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1085 if (strcmp(tokens[4], "ipv4") == 0)
1086 p.common.ip_version = 1;
1087 else if (strcmp(tokens[4], "ipv6") == 0)
1088 p.common.ip_version = 0;
1090 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1094 if (strcmp(tokens[5], "offset") != 0) {
1095 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1099 if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
1100 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1104 if (strcmp(tokens[7], "fwd") != 0) {
1105 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1109 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1112 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
1113 if (n_tokens < t0 + 7) {
1114 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1118 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1119 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1123 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
1124 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1128 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1129 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1133 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1134 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1135 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1139 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1140 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1144 if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
1145 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1149 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1153 if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
1154 if (n_tokens < t0 + 6) {
1155 snprintf(out, out_size, MSG_ARG_MISMATCH,
1156 "table action profile meter");
1160 if (strcmp(tokens[t0 + 1], "srtcm") == 0)
1161 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1162 else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
1163 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1165 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1170 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1171 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1175 if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
1176 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1180 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1181 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1185 if (strcmp(tokens[t0 + 5], "none") == 0) {
1186 p.mtr.n_packets_enabled = 0;
1187 p.mtr.n_bytes_enabled = 0;
1188 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1189 p.mtr.n_packets_enabled = 1;
1190 p.mtr.n_bytes_enabled = 0;
1191 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1192 p.mtr.n_packets_enabled = 0;
1193 p.mtr.n_bytes_enabled = 1;
1194 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1195 p.mtr.n_packets_enabled = 1;
1196 p.mtr.n_bytes_enabled = 1;
1198 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1199 "none or pkts or bytes or both");
1203 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1207 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
1208 if (n_tokens < t0 + 5) {
1209 snprintf(out, out_size, MSG_ARG_MISMATCH,
1210 "table action profile tm");
1214 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1215 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1219 if (parser_read_uint32(&p.tm.n_subports_per_port,
1220 tokens[t0 + 2]) != 0) {
1221 snprintf(out, out_size, MSG_ARG_INVALID,
1222 "n_subports_per_port");
1226 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1227 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1231 if (parser_read_uint32(&p.tm.n_pipes_per_subport,
1232 tokens[t0 + 4]) != 0) {
1233 snprintf(out, out_size, MSG_ARG_INVALID,
1234 "n_pipes_per_subport");
1238 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1242 if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
1243 uint32_t n_extra_tokens = 0;
1245 if (n_tokens < t0 + 2) {
1246 snprintf(out, out_size, MSG_ARG_MISMATCH,
1247 "action profile encap");
1251 if (strcmp(tokens[t0 + 1], "ether") == 0)
1252 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1253 else if (strcmp(tokens[t0 + 1], "vlan") == 0)
1254 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1255 else if (strcmp(tokens[t0 + 1], "qinq") == 0)
1256 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1257 else if (strcmp(tokens[t0 + 1], "mpls") == 0)
1258 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1259 else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
1260 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1261 else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
1262 if (n_tokens < t0 + 2 + 5) {
1263 snprintf(out, out_size, MSG_ARG_MISMATCH,
1264 "action profile encap vxlan");
1268 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1269 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1274 if (parser_read_uint32(&p.encap.vxlan.data_offset,
1275 tokens[t0 + 2 + 1]) != 0) {
1276 snprintf(out, out_size, MSG_ARG_INVALID,
1277 "vxlan: ether_offset");
1281 if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
1282 p.encap.vxlan.ip_version = 1;
1283 else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
1284 p.encap.vxlan.ip_version = 0;
1286 snprintf(out, out_size, MSG_ARG_INVALID,
1287 "vxlan: ipv4 or ipv6");
1291 if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
1292 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1297 if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
1298 p.encap.vxlan.vlan = 1;
1299 else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
1300 p.encap.vxlan.vlan = 0;
1302 snprintf(out, out_size, MSG_ARG_INVALID,
1303 "vxlan: on or off");
1307 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
1309 } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
1310 p.encap.encap_mask =
1311 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
1313 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1317 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1318 t0 += 2 + n_extra_tokens;
1321 if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
1322 if (n_tokens < t0 + 4) {
1323 snprintf(out, out_size, MSG_ARG_MISMATCH,
1324 "table action profile nat");
1328 if (strcmp(tokens[t0 + 1], "src") == 0)
1329 p.nat.source_nat = 1;
1330 else if (strcmp(tokens[t0 + 1], "dst") == 0)
1331 p.nat.source_nat = 0;
1333 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1338 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1339 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1343 if (strcmp(tokens[t0 + 3], "tcp") == 0)
1345 else if (strcmp(tokens[t0 + 3], "udp") == 0)
1348 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1353 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1357 if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
1358 if (n_tokens < t0 + 4) {
1359 snprintf(out, out_size, MSG_ARG_MISMATCH,
1360 "table action profile ttl");
1364 if (strcmp(tokens[t0 + 1], "drop") == 0)
1366 else if (strcmp(tokens[t0 + 1], "fwd") == 0)
1369 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1374 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1375 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1379 if (strcmp(tokens[t0 + 3], "none") == 0)
1380 p.ttl.n_packets_enabled = 0;
1381 else if (strcmp(tokens[t0 + 3], "pkts") == 0)
1382 p.ttl.n_packets_enabled = 1;
1384 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1389 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1393 if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
1394 if (n_tokens < t0 + 2) {
1395 snprintf(out, out_size, MSG_ARG_MISMATCH,
1396 "table action profile stats");
1400 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1401 p.stats.n_packets_enabled = 1;
1402 p.stats.n_bytes_enabled = 0;
1403 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1404 p.stats.n_packets_enabled = 0;
1405 p.stats.n_bytes_enabled = 1;
1406 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1407 p.stats.n_packets_enabled = 1;
1408 p.stats.n_bytes_enabled = 1;
1410 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1411 "pkts or bytes or both");
1415 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1419 if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
1420 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1424 if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
1425 struct cryptodev *cryptodev;
1427 if (n_tokens < t0 + 5 ||
1428 strcmp(tokens[t0 + 1], "dev") ||
1429 strcmp(tokens[t0 + 3], "offset")) {
1430 snprintf(out, out_size, MSG_ARG_MISMATCH,
1431 "table action profile sym_crypto");
1435 cryptodev = cryptodev_find(tokens[t0 + 2]);
1436 if (cryptodev == NULL) {
1437 snprintf(out, out_size, MSG_ARG_INVALID,
1438 "table action profile sym_crypto");
1442 p.sym_crypto.cryptodev_id = cryptodev->dev_id;
1444 if (parser_read_uint32(&p.sym_crypto.op_offset,
1445 tokens[t0 + 4]) != 0) {
1446 snprintf(out, out_size, MSG_ARG_INVALID,
1447 "table action profile sym_crypto");
1451 p.sym_crypto.mp_create = cryptodev->mp_create;
1452 p.sym_crypto.mp_init = cryptodev->mp_init;
1454 p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
1459 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
1460 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1464 if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
1465 p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
1469 if (t0 < n_tokens) {
1470 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1474 ap = table_action_profile_create(name, &p);
1476 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1481 static const char cmd_pipeline_help[] =
1482 "pipeline <pipeline_name>\n"
1483 " period <timer_period_ms>\n"
1484 " offset_port_id <offset_port_id>\n"
1488 cmd_pipeline(char **tokens,
1493 struct pipeline_params p;
1495 struct pipeline *pipeline;
1497 if (n_tokens != 8) {
1498 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1504 if (strcmp(tokens[2], "period") != 0) {
1505 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1509 if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
1510 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1514 if (strcmp(tokens[4], "offset_port_id") != 0) {
1515 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1519 if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
1520 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1524 if (strcmp(tokens[6], "cpu") != 0) {
1525 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
1529 if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
1530 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
1534 pipeline = pipeline_create(name, &p);
1535 if (pipeline == NULL) {
1536 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1541 static const char cmd_pipeline_port_in_help[] =
1542 "pipeline <pipeline_name> port in\n"
1543 " bsz <burst_size>\n"
1544 " link <link_name> rxq <queue_id>\n"
1545 " | swq <swq_name>\n"
1546 " | tmgr <tmgr_name>\n"
1547 " | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
1548 " | kni <kni_name>\n"
1549 " | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
1550 " | cryptodev <cryptodev_name> rxq <queue_id>\n"
1551 " [action <port_in_action_profile_name>]\n"
1555 cmd_pipeline_port_in(char **tokens,
1560 struct port_in_params p;
1561 char *pipeline_name;
1563 int enabled, status;
1566 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1570 pipeline_name = tokens[1];
1572 if (strcmp(tokens[2], "port") != 0) {
1573 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1577 if (strcmp(tokens[3], "in") != 0) {
1578 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1582 if (strcmp(tokens[4], "bsz") != 0) {
1583 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1587 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1588 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1594 if (strcmp(tokens[t0], "link") == 0) {
1595 if (n_tokens < t0 + 4) {
1596 snprintf(out, out_size, MSG_ARG_MISMATCH,
1597 "pipeline port in link");
1601 p.type = PORT_IN_RXQ;
1603 p.dev_name = tokens[t0 + 1];
1605 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1610 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1611 snprintf(out, out_size, MSG_ARG_INVALID,
1616 } else if (strcmp(tokens[t0], "swq") == 0) {
1617 if (n_tokens < t0 + 2) {
1618 snprintf(out, out_size, MSG_ARG_MISMATCH,
1619 "pipeline port in swq");
1623 p.type = PORT_IN_SWQ;
1625 p.dev_name = tokens[t0 + 1];
1628 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1629 if (n_tokens < t0 + 2) {
1630 snprintf(out, out_size, MSG_ARG_MISMATCH,
1631 "pipeline port in tmgr");
1635 p.type = PORT_IN_TMGR;
1637 p.dev_name = tokens[t0 + 1];
1640 } else if (strcmp(tokens[t0], "tap") == 0) {
1641 if (n_tokens < t0 + 6) {
1642 snprintf(out, out_size, MSG_ARG_MISMATCH,
1643 "pipeline port in tap");
1647 p.type = PORT_IN_TAP;
1649 p.dev_name = tokens[t0 + 1];
1651 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1652 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1657 p.tap.mempool_name = tokens[t0 + 3];
1659 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1660 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1665 if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
1666 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1671 } else if (strcmp(tokens[t0], "kni") == 0) {
1672 if (n_tokens < t0 + 2) {
1673 snprintf(out, out_size, MSG_ARG_MISMATCH,
1674 "pipeline port in kni");
1678 p.type = PORT_IN_KNI;
1680 p.dev_name = tokens[t0 + 1];
1683 } else if (strcmp(tokens[t0], "source") == 0) {
1684 if (n_tokens < t0 + 6) {
1685 snprintf(out, out_size, MSG_ARG_MISMATCH,
1686 "pipeline port in source");
1690 p.type = PORT_IN_SOURCE;
1694 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1695 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1700 p.source.mempool_name = tokens[t0 + 2];
1702 if (strcmp(tokens[t0 + 3], "file") != 0) {
1703 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1708 p.source.file_name = tokens[t0 + 4];
1710 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1711 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1716 if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
1717 snprintf(out, out_size, MSG_ARG_INVALID,
1723 } else if (strcmp(tokens[t0], "cryptodev") == 0) {
1724 if (n_tokens < t0 + 3) {
1725 snprintf(out, out_size, MSG_ARG_MISMATCH,
1726 "pipeline port in cryptodev");
1730 p.type = PORT_IN_CRYPTODEV;
1732 p.dev_name = tokens[t0 + 1];
1733 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1734 snprintf(out, out_size, MSG_ARG_INVALID,
1739 p.cryptodev.arg_callback = NULL;
1740 p.cryptodev.f_callback = NULL;
1744 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1748 p.action_profile_name = NULL;
1749 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
1750 if (n_tokens < t0 + 2) {
1751 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1755 p.action_profile_name = tokens[t0 + 1];
1761 if ((n_tokens > t0) &&
1762 (strcmp(tokens[t0], "disabled") == 0)) {
1768 if (n_tokens != t0) {
1769 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1773 status = pipeline_port_in_create(pipeline_name,
1776 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1781 static const char cmd_pipeline_port_out_help[] =
1782 "pipeline <pipeline_name> port out\n"
1783 " bsz <burst_size>\n"
1784 " link <link_name> txq <txq_id>\n"
1785 " | swq <swq_name>\n"
1786 " | tmgr <tmgr_name>\n"
1787 " | tap <tap_name>\n"
1788 " | kni <kni_name>\n"
1789 " | sink [file <file_name> pkts <max_n_pkts>]\n"
1790 " | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
1793 cmd_pipeline_port_out(char **tokens,
1798 struct port_out_params p;
1799 char *pipeline_name;
1802 memset(&p, 0, sizeof(p));
1805 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1809 pipeline_name = tokens[1];
1811 if (strcmp(tokens[2], "port") != 0) {
1812 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1816 if (strcmp(tokens[3], "out") != 0) {
1817 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1821 if (strcmp(tokens[4], "bsz") != 0) {
1822 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1826 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1827 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1831 if (strcmp(tokens[6], "link") == 0) {
1832 if (n_tokens != 10) {
1833 snprintf(out, out_size, MSG_ARG_MISMATCH,
1834 "pipeline port out link");
1838 p.type = PORT_OUT_TXQ;
1840 p.dev_name = tokens[7];
1842 if (strcmp(tokens[8], "txq") != 0) {
1843 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1847 if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
1848 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1851 } else if (strcmp(tokens[6], "swq") == 0) {
1852 if (n_tokens != 8) {
1853 snprintf(out, out_size, MSG_ARG_MISMATCH,
1854 "pipeline port out swq");
1858 p.type = PORT_OUT_SWQ;
1860 p.dev_name = tokens[7];
1861 } else if (strcmp(tokens[6], "tmgr") == 0) {
1862 if (n_tokens != 8) {
1863 snprintf(out, out_size, MSG_ARG_MISMATCH,
1864 "pipeline port out tmgr");
1868 p.type = PORT_OUT_TMGR;
1870 p.dev_name = tokens[7];
1871 } else if (strcmp(tokens[6], "tap") == 0) {
1872 if (n_tokens != 8) {
1873 snprintf(out, out_size, MSG_ARG_MISMATCH,
1874 "pipeline port out tap");
1878 p.type = PORT_OUT_TAP;
1880 p.dev_name = tokens[7];
1881 } else if (strcmp(tokens[6], "kni") == 0) {
1882 if (n_tokens != 8) {
1883 snprintf(out, out_size, MSG_ARG_MISMATCH,
1884 "pipeline port out kni");
1888 p.type = PORT_OUT_KNI;
1890 p.dev_name = tokens[7];
1891 } else if (strcmp(tokens[6], "sink") == 0) {
1892 if ((n_tokens != 7) && (n_tokens != 11)) {
1893 snprintf(out, out_size, MSG_ARG_MISMATCH,
1894 "pipeline port out sink");
1898 p.type = PORT_OUT_SINK;
1902 if (n_tokens == 7) {
1903 p.sink.file_name = NULL;
1904 p.sink.max_n_pkts = 0;
1906 if (strcmp(tokens[7], "file") != 0) {
1907 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1912 p.sink.file_name = tokens[8];
1914 if (strcmp(tokens[9], "pkts") != 0) {
1915 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1919 if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
1920 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1925 } else if (strcmp(tokens[6], "cryptodev") == 0) {
1926 if (n_tokens != 12) {
1927 snprintf(out, out_size, MSG_ARG_MISMATCH,
1928 "pipeline port out cryptodev");
1932 p.type = PORT_OUT_CRYPTODEV;
1934 p.dev_name = tokens[7];
1936 if (strcmp(tokens[8], "txq")) {
1937 snprintf(out, out_size, MSG_ARG_MISMATCH,
1938 "pipeline port out cryptodev");
1942 if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
1944 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1948 if (strcmp(tokens[10], "offset")) {
1949 snprintf(out, out_size, MSG_ARG_MISMATCH,
1950 "pipeline port out cryptodev");
1954 if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
1956 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1960 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1964 status = pipeline_port_out_create(pipeline_name, &p);
1966 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1971 static const char cmd_pipeline_table_help[] =
1972 "pipeline <pipeline_name> table\n"
1976 " offset <ip_header_offset>\n"
1979 " offset <key_offset>\n"
1984 " mask <key_mask>\n"
1985 " offset <key_offset>\n"
1986 " buckets <n_buckets>\n"
1990 " offset <ip_header_offset>\n"
1993 " [action <table_action_profile_name>]\n";
1996 cmd_pipeline_table(char **tokens,
2001 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
2002 struct table_params p;
2003 char *pipeline_name;
2008 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2012 pipeline_name = tokens[1];
2014 if (strcmp(tokens[2], "table") != 0) {
2015 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2019 if (strcmp(tokens[3], "match") != 0) {
2020 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2025 if (strcmp(tokens[t0], "acl") == 0) {
2026 if (n_tokens < t0 + 6) {
2027 snprintf(out, out_size, MSG_ARG_MISMATCH,
2028 "pipeline table acl");
2032 p.match_type = TABLE_ACL;
2034 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2035 p.match.acl.ip_version = 1;
2036 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2037 p.match.acl.ip_version = 0;
2039 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2044 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2045 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2049 if (parser_read_uint32(&p.match.acl.ip_header_offset,
2050 tokens[t0 + 3]) != 0) {
2051 snprintf(out, out_size, MSG_ARG_INVALID,
2052 "ip_header_offset");
2056 if (strcmp(tokens[t0 + 4], "size") != 0) {
2057 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2061 if (parser_read_uint32(&p.match.acl.n_rules,
2062 tokens[t0 + 5]) != 0) {
2063 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2068 } else if (strcmp(tokens[t0], "array") == 0) {
2069 if (n_tokens < t0 + 5) {
2070 snprintf(out, out_size, MSG_ARG_MISMATCH,
2071 "pipeline table array");
2075 p.match_type = TABLE_ARRAY;
2077 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2078 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2082 if (parser_read_uint32(&p.match.array.key_offset,
2083 tokens[t0 + 2]) != 0) {
2084 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2088 if (strcmp(tokens[t0 + 3], "size") != 0) {
2089 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2093 if (parser_read_uint32(&p.match.array.n_keys,
2094 tokens[t0 + 4]) != 0) {
2095 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2100 } else if (strcmp(tokens[t0], "hash") == 0) {
2101 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2103 if (n_tokens < t0 + 12) {
2104 snprintf(out, out_size, MSG_ARG_MISMATCH,
2105 "pipeline table hash");
2109 p.match_type = TABLE_HASH;
2111 if (strcmp(tokens[t0 + 1], "ext") == 0)
2112 p.match.hash.extendable_bucket = 1;
2113 else if (strcmp(tokens[t0 + 1], "lru") == 0)
2114 p.match.hash.extendable_bucket = 0;
2116 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2121 if (strcmp(tokens[t0 + 2], "key") != 0) {
2122 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2126 if ((parser_read_uint32(&p.match.hash.key_size,
2127 tokens[t0 + 3]) != 0) ||
2128 (p.match.hash.key_size == 0) ||
2129 (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
2130 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2134 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2135 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2139 if ((parse_hex_string(tokens[t0 + 5],
2140 key_mask, &key_mask_size) != 0) ||
2141 (key_mask_size != p.match.hash.key_size)) {
2142 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2145 p.match.hash.key_mask = key_mask;
2147 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2148 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2152 if (parser_read_uint32(&p.match.hash.key_offset,
2153 tokens[t0 + 7]) != 0) {
2154 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2158 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2159 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2163 if (parser_read_uint32(&p.match.hash.n_buckets,
2164 tokens[t0 + 9]) != 0) {
2165 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2169 if (strcmp(tokens[t0 + 10], "size") != 0) {
2170 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2174 if (parser_read_uint32(&p.match.hash.n_keys,
2175 tokens[t0 + 11]) != 0) {
2176 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2181 } else if (strcmp(tokens[t0], "lpm") == 0) {
2182 if (n_tokens < t0 + 6) {
2183 snprintf(out, out_size, MSG_ARG_MISMATCH,
2184 "pipeline table lpm");
2188 p.match_type = TABLE_LPM;
2190 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2191 p.match.lpm.key_size = 4;
2192 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2193 p.match.lpm.key_size = 16;
2195 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2200 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2201 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2205 if (parser_read_uint32(&p.match.lpm.key_offset,
2206 tokens[t0 + 3]) != 0) {
2207 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2211 if (strcmp(tokens[t0 + 4], "size") != 0) {
2212 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2216 if (parser_read_uint32(&p.match.lpm.n_rules,
2217 tokens[t0 + 5]) != 0) {
2218 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2223 } else if (strcmp(tokens[t0], "stub") == 0) {
2224 p.match_type = TABLE_STUB;
2228 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2232 p.action_profile_name = NULL;
2233 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
2234 if (n_tokens < t0 + 2) {
2235 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2239 p.action_profile_name = tokens[t0 + 1];
2244 if (n_tokens > t0) {
2245 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2249 status = pipeline_table_create(pipeline_name, &p);
2251 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2256 static const char cmd_pipeline_port_in_table_help[] =
2257 "pipeline <pipeline_name> port in <port_id> table <table_id>\n";
2260 cmd_pipeline_port_in_table(char **tokens,
2265 char *pipeline_name;
2266 uint32_t port_id, table_id;
2269 if (n_tokens != 7) {
2270 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2274 pipeline_name = tokens[1];
2276 if (strcmp(tokens[2], "port") != 0) {
2277 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2281 if (strcmp(tokens[3], "in") != 0) {
2282 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2286 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2287 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2291 if (strcmp(tokens[5], "table") != 0) {
2292 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2296 if (parser_read_uint32(&table_id, tokens[6]) != 0) {
2297 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2301 status = pipeline_port_in_connect_to_table(pipeline_name,
2305 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2311 static const char cmd_pipeline_port_in_stats_help[] =
2312 "pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
2314 #define MSG_PIPELINE_PORT_IN_STATS \
2315 "Pkts in: %" PRIu64 "\n" \
2316 "Pkts dropped by AH: %" PRIu64 "\n" \
2317 "Pkts dropped by other: %" PRIu64 "\n"
2320 cmd_pipeline_port_in_stats(char **tokens,
2325 struct rte_pipeline_port_in_stats stats;
2326 char *pipeline_name;
2330 if ((n_tokens != 7) && (n_tokens != 8)) {
2331 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2335 pipeline_name = tokens[1];
2337 if (strcmp(tokens[2], "port") != 0) {
2338 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2342 if (strcmp(tokens[3], "in") != 0) {
2343 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2347 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2348 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2352 if (strcmp(tokens[5], "stats") != 0) {
2353 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2357 if (strcmp(tokens[6], "read") != 0) {
2358 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2363 if (n_tokens == 8) {
2364 if (strcmp(tokens[7], "clear") != 0) {
2365 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2372 status = pipeline_port_in_stats_read(pipeline_name,
2377 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2381 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2382 stats.stats.n_pkts_in,
2383 stats.n_pkts_dropped_by_ah,
2384 stats.stats.n_pkts_drop);
2388 static const char cmd_pipeline_port_in_enable_help[] =
2389 "pipeline <pipeline_name> port in <port_id> enable\n";
2392 cmd_pipeline_port_in_enable(char **tokens,
2397 char *pipeline_name;
2401 if (n_tokens != 6) {
2402 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2406 pipeline_name = tokens[1];
2408 if (strcmp(tokens[2], "port") != 0) {
2409 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2413 if (strcmp(tokens[3], "in") != 0) {
2414 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2418 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2419 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2423 if (strcmp(tokens[5], "enable") != 0) {
2424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2428 status = pipeline_port_in_enable(pipeline_name, port_id);
2430 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2436 static const char cmd_pipeline_port_in_disable_help[] =
2437 "pipeline <pipeline_name> port in <port_id> disable\n";
2440 cmd_pipeline_port_in_disable(char **tokens,
2445 char *pipeline_name;
2449 if (n_tokens != 6) {
2450 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2454 pipeline_name = tokens[1];
2456 if (strcmp(tokens[2], "port") != 0) {
2457 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2461 if (strcmp(tokens[3], "in") != 0) {
2462 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2466 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2467 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2471 if (strcmp(tokens[5], "disable") != 0) {
2472 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2476 status = pipeline_port_in_disable(pipeline_name, port_id);
2478 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2484 static const char cmd_pipeline_port_out_stats_help[] =
2485 "pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
2487 #define MSG_PIPELINE_PORT_OUT_STATS \
2488 "Pkts in: %" PRIu64 "\n" \
2489 "Pkts dropped by AH: %" PRIu64 "\n" \
2490 "Pkts dropped by other: %" PRIu64 "\n"
2493 cmd_pipeline_port_out_stats(char **tokens,
2498 struct rte_pipeline_port_out_stats stats;
2499 char *pipeline_name;
2503 if ((n_tokens != 7) && (n_tokens != 8)) {
2504 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2508 pipeline_name = tokens[1];
2510 if (strcmp(tokens[2], "port") != 0) {
2511 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2515 if (strcmp(tokens[3], "out") != 0) {
2516 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2520 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2521 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2525 if (strcmp(tokens[5], "stats") != 0) {
2526 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2530 if (strcmp(tokens[6], "read") != 0) {
2531 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2536 if (n_tokens == 8) {
2537 if (strcmp(tokens[7], "clear") != 0) {
2538 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2545 status = pipeline_port_out_stats_read(pipeline_name,
2550 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2554 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2555 stats.stats.n_pkts_in,
2556 stats.n_pkts_dropped_by_ah,
2557 stats.stats.n_pkts_drop);
2561 static const char cmd_pipeline_table_stats_help[] =
2562 "pipeline <pipeline_name> table <table_id> stats read [clear]\n";
2564 #define MSG_PIPELINE_TABLE_STATS \
2565 "Pkts in: %" PRIu64 "\n" \
2566 "Pkts in with lookup miss: %" PRIu64 "\n" \
2567 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2568 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2569 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2570 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2573 cmd_pipeline_table_stats(char **tokens,
2578 struct rte_pipeline_table_stats stats;
2579 char *pipeline_name;
2583 if ((n_tokens != 6) && (n_tokens != 7)) {
2584 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2588 pipeline_name = tokens[1];
2590 if (strcmp(tokens[2], "table") != 0) {
2591 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2595 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
2596 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2600 if (strcmp(tokens[4], "stats") != 0) {
2601 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2605 if (strcmp(tokens[5], "read") != 0) {
2606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2611 if (n_tokens == 7) {
2612 if (strcmp(tokens[6], "clear") != 0) {
2613 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2620 status = pipeline_table_stats_read(pipeline_name,
2625 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2629 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2630 stats.stats.n_pkts_in,
2631 stats.stats.n_pkts_lookup_miss,
2632 stats.n_pkts_dropped_by_lkp_hit_ah,
2633 stats.n_pkts_dropped_lkp_hit,
2634 stats.n_pkts_dropped_by_lkp_miss_ah,
2635 stats.n_pkts_dropped_lkp_miss);
2643 * priority <priority>
2644 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2645 * <sp0> <sp1> <dp0> <dp1> <proto>
2649 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2650 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2651 * | ipv4_addr <addr>
2652 * | ipv6_addr <addr>
2653 * | qinq <svlan> <cvlan>
2655 * ipv4 | ipv6 <addr> <depth>
2657 struct pkt_key_qinq {
2658 uint16_t ethertype_svlan;
2660 uint16_t ethertype_cvlan;
2662 } __attribute__((__packed__));
2664 struct pkt_key_ipv4_5tuple {
2665 uint8_t time_to_live;
2667 uint16_t hdr_checksum;
2672 } __attribute__((__packed__));
2674 struct pkt_key_ipv6_5tuple {
2675 uint16_t payload_length;
2682 } __attribute__((__packed__));
2684 struct pkt_key_ipv4_addr {
2686 } __attribute__((__packed__));
2688 struct pkt_key_ipv6_addr {
2690 } __attribute__((__packed__));
2693 parse_match(char **tokens,
2697 struct table_rule_match *m)
2699 memset(m, 0, sizeof(*m));
2704 if (strcmp(tokens[0], "match") != 0) {
2705 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2709 if (strcmp(tokens[1], "acl") == 0) {
2710 if (n_tokens < 14) {
2711 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2715 m->match_type = TABLE_ACL;
2717 if (strcmp(tokens[2], "priority") != 0) {
2718 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2722 if (parser_read_uint32(&m->match.acl.priority,
2724 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2728 if (strcmp(tokens[4], "ipv4") == 0) {
2729 struct in_addr saddr, daddr;
2731 m->match.acl.ip_version = 1;
2733 if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
2734 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2737 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2739 if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
2740 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2743 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2744 } else if (strcmp(tokens[4], "ipv6") == 0) {
2745 struct in6_addr saddr, daddr;
2747 m->match.acl.ip_version = 0;
2749 if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
2750 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2753 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2755 if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
2756 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2759 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2761 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2766 if (parser_read_uint32(&m->match.acl.sa_depth,
2768 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2772 if (parser_read_uint32(&m->match.acl.da_depth,
2774 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2778 if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2779 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2783 if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2784 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2788 if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2789 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2793 if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2794 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2798 if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2799 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2803 m->match.acl.proto_mask = 0xff;
2808 if (strcmp(tokens[1], "array") == 0) {
2810 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2814 m->match_type = TABLE_ARRAY;
2816 if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2817 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2824 if (strcmp(tokens[1], "hash") == 0) {
2826 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2830 m->match_type = TABLE_HASH;
2832 if (strcmp(tokens[2], "raw") == 0) {
2833 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2836 snprintf(out, out_size, MSG_ARG_MISMATCH,
2841 if (parse_hex_string(tokens[3],
2842 m->match.hash.key, &key_size) != 0) {
2843 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2850 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2851 struct pkt_key_ipv4_5tuple *ipv4 =
2852 (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
2853 struct in_addr saddr, daddr;
2858 snprintf(out, out_size, MSG_ARG_MISMATCH,
2863 if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
2864 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2868 if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
2869 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2873 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2874 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2878 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2879 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2883 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2884 snprintf(out, out_size, MSG_ARG_INVALID,
2889 ipv4->sa = saddr.s_addr;
2890 ipv4->da = daddr.s_addr;
2891 ipv4->sp = rte_cpu_to_be_16(sp);
2892 ipv4->dp = rte_cpu_to_be_16(dp);
2893 ipv4->proto = proto;
2896 } /* hash ipv4_5tuple */
2898 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2899 struct pkt_key_ipv6_5tuple *ipv6 =
2900 (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
2901 struct in6_addr saddr, daddr;
2906 snprintf(out, out_size, MSG_ARG_MISMATCH,
2911 if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
2912 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2916 if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
2917 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2921 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2922 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2926 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2927 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2931 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2932 snprintf(out, out_size, MSG_ARG_INVALID,
2937 memcpy(ipv6->sa, saddr.s6_addr, 16);
2938 memcpy(ipv6->da, daddr.s6_addr, 16);
2939 ipv6->sp = rte_cpu_to_be_16(sp);
2940 ipv6->dp = rte_cpu_to_be_16(dp);
2941 ipv6->proto = proto;
2944 } /* hash ipv6_5tuple */
2946 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2947 struct pkt_key_ipv4_addr *ipv4_addr =
2948 (struct pkt_key_ipv4_addr *) m->match.hash.key;
2949 struct in_addr addr;
2952 snprintf(out, out_size, MSG_ARG_MISMATCH,
2957 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
2958 snprintf(out, out_size, MSG_ARG_INVALID,
2963 ipv4_addr->addr = addr.s_addr;
2966 } /* hash ipv4_addr */
2968 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2969 struct pkt_key_ipv6_addr *ipv6_addr =
2970 (struct pkt_key_ipv6_addr *) m->match.hash.key;
2971 struct in6_addr addr;
2974 snprintf(out, out_size, MSG_ARG_MISMATCH,
2979 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
2980 snprintf(out, out_size, MSG_ARG_INVALID,
2985 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2988 } /* hash ipv6_5tuple */
2990 if (strcmp(tokens[2], "qinq") == 0) {
2991 struct pkt_key_qinq *qinq =
2992 (struct pkt_key_qinq *) m->match.hash.key;
2993 uint16_t svlan, cvlan;
2996 snprintf(out, out_size, MSG_ARG_MISMATCH,
3001 if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
3003 snprintf(out, out_size, MSG_ARG_INVALID,
3008 if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3010 snprintf(out, out_size, MSG_ARG_INVALID,
3015 qinq->svlan = rte_cpu_to_be_16(svlan);
3016 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3021 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3025 if (strcmp(tokens[1], "lpm") == 0) {
3027 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3031 m->match_type = TABLE_LPM;
3033 if (strcmp(tokens[2], "ipv4") == 0) {
3034 struct in_addr addr;
3036 m->match.lpm.ip_version = 1;
3038 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
3039 snprintf(out, out_size, MSG_ARG_INVALID,
3044 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3045 } else if (strcmp(tokens[2], "ipv6") == 0) {
3046 struct in6_addr addr;
3048 m->match.lpm.ip_version = 0;
3050 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
3051 snprintf(out, out_size, MSG_ARG_INVALID,
3056 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3058 snprintf(out, out_size, MSG_ARG_MISMATCH,
3063 if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3064 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3071 snprintf(out, out_size, MSG_ARG_MISMATCH,
3072 "acl or array or hash or lpm");
3084 * | table <table_id>
3085 * [balance <out0> ... <out7>]
3087 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3088 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3089 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3090 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3091 * [tm subport <subport_id> pipe <pipe_id>]
3094 * | vlan <da> <sa> <pcp> <dei> <vid>
3095 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3096 * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
3097 * | mpls unicast | multicast
3099 * label0 <label> <tc> <ttl>
3100 * [label1 <label> <tc> <ttl>
3101 * [label2 <label> <tc> <ttl>
3102 * [label3 <label> <tc> <ttl>]]]
3103 * | pppoe <da> <sa> <session_id>
3104 * | vxlan ether <da> <sa>
3105 * [vlan <pcp> <dei> <vid>]
3106 * ipv4 <sa> <da> <dscp> <ttl>
3107 * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
3110 * [nat ipv4 | ipv6 <addr> <port>]
3118 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3120 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3121 * auth_algo <algo> auth_key <key> digest_size <size>
3123 * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
3124 * digest_size <size>
3125 * data_offset <data_offset>]
3130 * <pa> ::= g | y | r | drop
3133 parse_table_action_fwd(char **tokens,
3135 struct table_rule_action *a)
3137 if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
3143 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3144 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3145 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3149 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3152 if ((n_tokens < 2) ||
3153 parser_read_uint32(&id, tokens[1]))
3156 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3158 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3162 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3163 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3164 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3168 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3171 if ((n_tokens < 2) ||
3172 parser_read_uint32(&id, tokens[1]))
3175 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3177 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3185 parse_table_action_balance(char **tokens,
3187 struct table_rule_action *a)
3191 if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
3197 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3200 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3201 if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3204 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3205 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3210 parse_policer_action(char *token, enum rte_table_action_policer *a)
3212 if (strcmp(token, "g") == 0) {
3213 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3217 if (strcmp(token, "y") == 0) {
3218 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3222 if (strcmp(token, "r") == 0) {
3223 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3227 if (strcmp(token, "drop") == 0) {
3228 *a = RTE_TABLE_ACTION_POLICER_DROP;
3236 parse_table_action_meter_tc(char **tokens,
3238 struct rte_table_action_mtr_tc_params *mtr)
3240 if ((n_tokens < 9) ||
3241 strcmp(tokens[0], "meter") ||
3242 parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3243 strcmp(tokens[2], "policer") ||
3244 strcmp(tokens[3], "g") ||
3245 parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
3246 strcmp(tokens[5], "y") ||
3247 parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
3248 strcmp(tokens[7], "r") ||
3249 parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
3256 parse_table_action_meter(char **tokens,
3258 struct table_rule_action *a)
3260 if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
3266 if ((n_tokens < 10) ||
3267 strcmp(tokens[0], "tc0") ||
3268 (parse_table_action_meter_tc(tokens + 1,
3270 &a->mtr.mtr[0]) == 0))
3276 if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
3278 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3282 if ((n_tokens < 30) ||
3283 (parse_table_action_meter_tc(tokens + 1,
3284 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3285 strcmp(tokens[10], "tc2") ||
3286 (parse_table_action_meter_tc(tokens + 11,
3287 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3288 strcmp(tokens[20], "tc3") ||
3289 (parse_table_action_meter_tc(tokens + 21,
3290 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3293 a->mtr.tc_mask = 0xF;
3294 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3295 return 1 + 10 + 3 * 10;
3299 parse_table_action_tm(char **tokens,
3301 struct table_rule_action *a)
3303 uint32_t subport_id, pipe_id;
3305 if ((n_tokens < 5) ||
3306 strcmp(tokens[0], "tm") ||
3307 strcmp(tokens[1], "subport") ||
3308 parser_read_uint32(&subport_id, tokens[2]) ||
3309 strcmp(tokens[3], "pipe") ||
3310 parser_read_uint32(&pipe_id, tokens[4]))
3313 a->tm.subport_id = subport_id;
3314 a->tm.pipe_id = pipe_id;
3315 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3320 parse_table_action_encap(char **tokens,
3322 struct table_rule_action *a)
3324 if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
3331 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3332 if ((n_tokens < 3) ||
3333 parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3334 parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3337 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3338 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3343 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3344 uint32_t pcp, dei, vid;
3346 if ((n_tokens < 6) ||
3347 parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3348 parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3349 parser_read_uint32(&pcp, tokens[3]) ||
3351 parser_read_uint32(&dei, tokens[4]) ||
3353 parser_read_uint32(&vid, tokens[5]) ||
3357 a->encap.vlan.vlan.pcp = pcp & 0x7;
3358 a->encap.vlan.vlan.dei = dei & 0x1;
3359 a->encap.vlan.vlan.vid = vid & 0xFFF;
3360 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3361 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3366 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3367 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3368 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3370 if ((n_tokens < 9) ||
3371 parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3372 parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3373 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3374 (svlan_pcp > 0x7) ||
3375 parser_read_uint32(&svlan_dei, tokens[4]) ||
3376 (svlan_dei > 0x1) ||
3377 parser_read_uint32(&svlan_vid, tokens[5]) ||
3378 (svlan_vid > 0xFFF) ||
3379 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3380 (cvlan_pcp > 0x7) ||
3381 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3382 (cvlan_dei > 0x1) ||
3383 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3384 (cvlan_vid > 0xFFF))
3387 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3388 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3389 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3390 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3391 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3392 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3393 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3394 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3399 if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
3400 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3401 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3403 if ((n_tokens < 10) ||
3404 parse_mac_addr(tokens[1],
3405 &a->encap.qinq_pppoe.ether.da) ||
3406 parse_mac_addr(tokens[2],
3407 &a->encap.qinq_pppoe.ether.sa) ||
3408 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3409 (svlan_pcp > 0x7) ||
3410 parser_read_uint32(&svlan_dei, tokens[4]) ||
3411 (svlan_dei > 0x1) ||
3412 parser_read_uint32(&svlan_vid, tokens[5]) ||
3413 (svlan_vid > 0xFFF) ||
3414 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3415 (cvlan_pcp > 0x7) ||
3416 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3417 (cvlan_dei > 0x1) ||
3418 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3419 (cvlan_vid > 0xFFF) ||
3420 parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
3424 a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
3425 a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
3426 a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
3427 a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
3428 a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
3429 a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
3430 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
3431 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3437 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3438 uint32_t label, tc, ttl;
3443 if (strcmp(tokens[1], "unicast") == 0)
3444 a->encap.mpls.unicast = 1;
3445 else if (strcmp(tokens[1], "multicast") == 0)
3446 a->encap.mpls.unicast = 0;
3450 if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3451 parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3452 strcmp(tokens[4], "label0") ||
3453 parser_read_uint32(&label, tokens[5]) ||
3454 (label > 0xFFFFF) ||
3455 parser_read_uint32(&tc, tokens[6]) ||
3457 parser_read_uint32(&ttl, tokens[7]) ||
3461 a->encap.mpls.mpls[0].label = label;
3462 a->encap.mpls.mpls[0].tc = tc;
3463 a->encap.mpls.mpls[0].ttl = ttl;
3468 if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
3469 a->encap.mpls.mpls_count = 1;
3470 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3471 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3475 if ((n_tokens < 4) ||
3476 parser_read_uint32(&label, tokens[1]) ||
3477 (label > 0xFFFFF) ||
3478 parser_read_uint32(&tc, tokens[2]) ||
3480 parser_read_uint32(&ttl, tokens[3]) ||
3484 a->encap.mpls.mpls[1].label = label;
3485 a->encap.mpls.mpls[1].tc = tc;
3486 a->encap.mpls.mpls[1].ttl = ttl;
3491 if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
3492 a->encap.mpls.mpls_count = 2;
3493 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3494 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3498 if ((n_tokens < 4) ||
3499 parser_read_uint32(&label, tokens[1]) ||
3500 (label > 0xFFFFF) ||
3501 parser_read_uint32(&tc, tokens[2]) ||
3503 parser_read_uint32(&ttl, tokens[3]) ||
3507 a->encap.mpls.mpls[2].label = label;
3508 a->encap.mpls.mpls[2].tc = tc;
3509 a->encap.mpls.mpls[2].ttl = ttl;
3514 if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
3515 a->encap.mpls.mpls_count = 3;
3516 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3517 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3518 return 1 + 8 + 4 + 4;
3521 if ((n_tokens < 4) ||
3522 parser_read_uint32(&label, tokens[1]) ||
3523 (label > 0xFFFFF) ||
3524 parser_read_uint32(&tc, tokens[2]) ||
3526 parser_read_uint32(&ttl, tokens[3]) ||
3530 a->encap.mpls.mpls[3].label = label;
3531 a->encap.mpls.mpls[3].tc = tc;
3532 a->encap.mpls.mpls[3].ttl = ttl;
3534 a->encap.mpls.mpls_count = 4;
3535 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3536 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3537 return 1 + 8 + 4 + 4 + 4;
3541 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3542 if ((n_tokens < 4) ||
3543 parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3544 parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3545 parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3549 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3550 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3555 if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
3562 /* ether <da> <sa> */
3563 if ((n_tokens < 3) ||
3564 strcmp(tokens[0], "ether") ||
3565 parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
3566 parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
3573 /* [vlan <pcp> <dei> <vid>] */
3574 if (strcmp(tokens[0], "vlan") == 0) {
3575 uint32_t pcp, dei, vid;
3577 if ((n_tokens < 4) ||
3578 parser_read_uint32(&pcp, tokens[1]) ||
3580 parser_read_uint32(&dei, tokens[2]) ||
3582 parser_read_uint32(&vid, tokens[3]) ||
3586 a->encap.vxlan.vlan.pcp = pcp;
3587 a->encap.vxlan.vlan.dei = dei;
3588 a->encap.vxlan.vlan.vid = vid;
3595 /* ipv4 <sa> <da> <dscp> <ttl>
3596 | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
3597 if (strcmp(tokens[0], "ipv4") == 0) {
3598 struct in_addr sa, da;
3601 if ((n_tokens < 5) ||
3602 parse_ipv4_addr(tokens[1], &sa) ||
3603 parse_ipv4_addr(tokens[2], &da) ||
3604 parser_read_uint8(&dscp, tokens[3]) ||
3606 parser_read_uint8(&ttl, tokens[4]))
3609 a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
3610 a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
3611 a->encap.vxlan.ipv4.dscp = dscp;
3612 a->encap.vxlan.ipv4.ttl = ttl;
3617 } else if (strcmp(tokens[0], "ipv6") == 0) {
3618 struct in6_addr sa, da;
3619 uint32_t flow_label;
3620 uint8_t dscp, hop_limit;
3622 if ((n_tokens < 6) ||
3623 parse_ipv6_addr(tokens[1], &sa) ||
3624 parse_ipv6_addr(tokens[2], &da) ||
3625 parser_read_uint32(&flow_label, tokens[3]) ||
3626 parser_read_uint8(&dscp, tokens[4]) ||
3628 parser_read_uint8(&hop_limit, tokens[5]))
3631 memcpy(a->encap.vxlan.ipv6.sa, sa.s6_addr, 16);
3632 memcpy(a->encap.vxlan.ipv6.da, da.s6_addr, 16);
3633 a->encap.vxlan.ipv6.flow_label = flow_label;
3634 a->encap.vxlan.ipv6.dscp = dscp;
3635 a->encap.vxlan.ipv6.hop_limit = hop_limit;
3644 if ((n_tokens < 3) ||
3645 strcmp(tokens[0], "udp") ||
3646 parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
3647 parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
3655 if ((n_tokens < 2) ||
3656 strcmp(tokens[0], "vxlan") ||
3657 parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
3658 (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
3665 a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
3666 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3674 parse_table_action_nat(char **tokens,
3676 struct table_rule_action *a)
3678 if ((n_tokens < 4) ||
3679 strcmp(tokens[0], "nat"))
3682 if (strcmp(tokens[1], "ipv4") == 0) {
3683 struct in_addr addr;
3686 if (parse_ipv4_addr(tokens[2], &addr) ||
3687 parser_read_uint16(&port, tokens[3]))
3690 a->nat.ip_version = 1;
3691 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3693 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3697 if (strcmp(tokens[1], "ipv6") == 0) {
3698 struct in6_addr addr;
3701 if (parse_ipv6_addr(tokens[2], &addr) ||
3702 parser_read_uint16(&port, tokens[3]))
3705 a->nat.ip_version = 0;
3706 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3708 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3716 parse_table_action_ttl(char **tokens,
3718 struct table_rule_action *a)
3720 if ((n_tokens < 2) ||
3721 strcmp(tokens[0], "ttl"))
3724 if (strcmp(tokens[1], "dec") == 0)
3725 a->ttl.decrement = 1;
3726 else if (strcmp(tokens[1], "keep") == 0)
3727 a->ttl.decrement = 0;
3731 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3736 parse_table_action_stats(char **tokens,
3738 struct table_rule_action *a)
3740 if ((n_tokens < 1) ||
3741 strcmp(tokens[0], "stats"))
3744 a->stats.n_packets = 0;
3745 a->stats.n_bytes = 0;
3746 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3751 parse_table_action_time(char **tokens,
3753 struct table_rule_action *a)
3755 if ((n_tokens < 1) ||
3756 strcmp(tokens[0], "time"))
3759 a->time.time = rte_rdtsc();
3760 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3765 parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
3767 struct rte_crypto_sym_xform *xform[2] = {NULL};
3770 xform[0] = p->xform;
3772 xform[1] = xform[0]->next;
3774 for (i = 0; i < 2; i++) {
3775 if (xform[i] == NULL)
3778 switch (xform[i]->type) {
3779 case RTE_CRYPTO_SYM_XFORM_CIPHER:
3780 if (p->cipher_auth.cipher_iv.val)
3781 free(p->cipher_auth.cipher_iv.val);
3782 if (p->cipher_auth.cipher_iv_update.val)
3783 free(p->cipher_auth.cipher_iv_update.val);
3785 case RTE_CRYPTO_SYM_XFORM_AUTH:
3786 if (p->cipher_auth.auth_iv.val)
3787 free(p->cipher_auth.cipher_iv.val);
3788 if (p->cipher_auth.auth_iv_update.val)
3789 free(p->cipher_auth.cipher_iv_update.val);
3791 case RTE_CRYPTO_SYM_XFORM_AEAD:
3793 free(p->aead.iv.val);
3794 if (p->aead.aad.val)
3795 free(p->aead.aad.val);
3804 static struct rte_crypto_sym_xform *
3805 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
3806 uint8_t *key, uint32_t max_key_len, char **tokens,
3807 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3809 struct rte_crypto_sym_xform *xform_cipher;
3813 if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
3814 strcmp(tokens[3], "cipher_key") ||
3815 strcmp(tokens[5], "cipher_iv"))
3818 xform_cipher = calloc(1, sizeof(*xform_cipher));
3819 if (xform_cipher == NULL)
3822 xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
3823 xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
3824 RTE_CRYPTO_CIPHER_OP_DECRYPT;
3827 status = rte_cryptodev_get_cipher_algo_enum(
3828 &xform_cipher->cipher.algo, tokens[2]);
3833 len = strlen(tokens[4]);
3834 if (len / 2 > max_key_len) {
3839 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
3843 xform_cipher->cipher.key.data = key;
3844 xform_cipher->cipher.key.length = (uint16_t)len;
3847 len = strlen(tokens[6]);
3849 p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
3850 if (p->cipher_auth.cipher_iv.val == NULL)
3853 status = parse_hex_string(tokens[6],
3854 p->cipher_auth.cipher_iv.val,
3859 xform_cipher->cipher.iv.length = (uint16_t)len;
3860 xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
3861 p->cipher_auth.cipher_iv.length = (uint32_t)len;
3864 return xform_cipher;
3867 if (p->cipher_auth.cipher_iv.val) {
3868 free(p->cipher_auth.cipher_iv.val);
3869 p->cipher_auth.cipher_iv.val = NULL;
3877 static struct rte_crypto_sym_xform *
3878 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
3879 uint8_t *key, uint32_t max_key_len, char **tokens,
3880 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3882 struct rte_crypto_sym_xform *xform_cipher;
3883 struct rte_crypto_sym_xform *xform_auth;
3887 if (n_tokens < 13 ||
3888 strcmp(tokens[7], "auth_algo") ||
3889 strcmp(tokens[9], "auth_key") ||
3890 strcmp(tokens[11], "digest_size"))
3893 xform_auth = calloc(1, sizeof(*xform_auth));
3894 if (xform_auth == NULL)
3897 xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
3898 xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
3899 RTE_CRYPTO_AUTH_OP_VERIFY;
3902 status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
3908 len = strlen(tokens[10]);
3909 if (len / 2 > max_key_len) {
3914 status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
3918 xform_auth->auth.key.data = key;
3919 xform_auth->auth.key.length = (uint16_t)len;
3921 key += xform_auth->auth.key.length;
3922 max_key_len -= xform_auth->auth.key.length;
3924 if (strcmp(tokens[11], "digest_size"))
3927 status = parser_read_uint16(&xform_auth->auth.digest_length,
3932 xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
3933 7, encrypt, used_n_tokens);
3934 if (xform_cipher == NULL)
3937 *used_n_tokens += 6;
3940 xform_cipher->next = xform_auth;
3941 return xform_cipher;
3943 xform_auth->next = xform_cipher;
3948 if (p->cipher_auth.auth_iv.val) {
3949 free(p->cipher_auth.auth_iv.val);
3950 p->cipher_auth.auth_iv.val = 0;
3958 static struct rte_crypto_sym_xform *
3959 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
3960 uint8_t *key, uint32_t max_key_len, char **tokens,
3961 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3963 struct rte_crypto_sym_xform *xform_aead;
3967 if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
3968 strcmp(tokens[3], "aead_key") ||
3969 strcmp(tokens[5], "aead_iv") ||
3970 strcmp(tokens[7], "aead_aad") ||
3971 strcmp(tokens[9], "digest_size"))
3974 xform_aead = calloc(1, sizeof(*xform_aead));
3975 if (xform_aead == NULL)
3978 xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
3979 xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
3980 RTE_CRYPTO_AEAD_OP_DECRYPT;
3983 status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
3989 len = strlen(tokens[4]);
3990 if (len / 2 > max_key_len) {
3995 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
3999 xform_aead->aead.key.data = key;
4000 xform_aead->aead.key.length = (uint16_t)len;
4003 len = strlen(tokens[6]);
4004 p->aead.iv.val = calloc(1, len / 2 + 1);
4005 if (p->aead.iv.val == NULL)
4008 status = parse_hex_string(tokens[6], p->aead.iv.val,
4013 xform_aead->aead.iv.length = (uint16_t)len;
4014 xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
4015 p->aead.iv.length = (uint32_t)len;
4018 len = strlen(tokens[8]);
4019 p->aead.aad.val = calloc(1, len / 2 + 1);
4020 if (p->aead.aad.val == NULL)
4023 status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
4027 xform_aead->aead.aad_length = (uint16_t)len;
4028 p->aead.aad.length = (uint32_t)len;
4031 status = parser_read_uint16(&xform_aead->aead.digest_length,
4036 *used_n_tokens = 11;
4041 if (p->aead.iv.val) {
4042 free(p->aead.iv.val);
4043 p->aead.iv.val = NULL;
4045 if (p->aead.aad.val) {
4046 free(p->aead.aad.val);
4047 p->aead.aad.val = NULL;
4057 parse_table_action_sym_crypto(char **tokens,
4059 struct table_rule_action *a)
4061 struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
4062 struct rte_crypto_sym_xform *xform = NULL;
4063 uint8_t *key = a->sym_crypto_key;
4064 uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
4065 uint32_t used_n_tokens;
4069 if ((n_tokens < 12) ||
4070 strcmp(tokens[0], "sym_crypto") ||
4071 strcmp(tokens[2], "type"))
4074 memset(p, 0, sizeof(*p));
4076 if (strcmp(tokens[1], "encrypt") == 0)
4081 status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
4085 if (strcmp(tokens[3], "cipher") == 0) {
4089 xform = parse_table_action_cipher(p, key, max_key_len, tokens,
4090 n_tokens, encrypt, &used_n_tokens);
4091 } else if (strcmp(tokens[3], "cipher_auth") == 0) {
4095 xform = parse_table_action_cipher_auth(p, key, max_key_len,
4096 tokens, n_tokens, encrypt, &used_n_tokens);
4097 } else if (strcmp(tokens[3], "aead") == 0) {
4101 xform = parse_table_action_aead(p, key, max_key_len, tokens,
4102 n_tokens, encrypt, &used_n_tokens);
4110 if (strcmp(tokens[used_n_tokens], "data_offset")) {
4111 parse_free_sym_crypto_param_data(p);
4115 a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
4117 return used_n_tokens + 5;
4121 parse_table_action_tag(char **tokens,
4123 struct table_rule_action *a)
4125 if ((n_tokens < 2) ||
4126 strcmp(tokens[0], "tag"))
4129 if (parser_read_uint32(&a->tag.tag, tokens[1]))
4132 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
4137 parse_table_action_decap(char **tokens,
4139 struct table_rule_action *a)
4141 if ((n_tokens < 2) ||
4142 strcmp(tokens[0], "decap"))
4145 if (parser_read_uint16(&a->decap.n, tokens[1]))
4148 a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
4153 parse_table_action(char **tokens,
4157 struct table_rule_action *a)
4159 uint32_t n_tokens0 = n_tokens;
4161 memset(a, 0, sizeof(*a));
4163 if ((n_tokens < 2) ||
4164 strcmp(tokens[0], "action"))
4170 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
4173 n = parse_table_action_fwd(tokens, n_tokens, a);
4175 snprintf(out, out_size, MSG_ARG_INVALID,
4184 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
4187 n = parse_table_action_balance(tokens, n_tokens, a);
4189 snprintf(out, out_size, MSG_ARG_INVALID,
4198 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
4201 n = parse_table_action_meter(tokens, n_tokens, a);
4203 snprintf(out, out_size, MSG_ARG_INVALID,
4212 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
4215 n = parse_table_action_tm(tokens, n_tokens, a);
4217 snprintf(out, out_size, MSG_ARG_INVALID,
4226 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
4229 n = parse_table_action_encap(tokens, n_tokens, a);
4231 snprintf(out, out_size, MSG_ARG_INVALID,
4240 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
4243 n = parse_table_action_nat(tokens, n_tokens, a);
4245 snprintf(out, out_size, MSG_ARG_INVALID,
4254 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
4257 n = parse_table_action_ttl(tokens, n_tokens, a);
4259 snprintf(out, out_size, MSG_ARG_INVALID,
4268 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
4271 n = parse_table_action_stats(tokens, n_tokens, a);
4273 snprintf(out, out_size, MSG_ARG_INVALID,
4282 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
4285 n = parse_table_action_time(tokens, n_tokens, a);
4287 snprintf(out, out_size, MSG_ARG_INVALID,
4296 if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
4299 n = parse_table_action_sym_crypto(tokens, n_tokens, a);
4301 snprintf(out, out_size, MSG_ARG_INVALID,
4302 "action sym_crypto");
4309 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
4312 n = parse_table_action_tag(tokens, n_tokens, a);
4314 snprintf(out, out_size, MSG_ARG_INVALID,
4323 if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
4326 n = parse_table_action_decap(tokens, n_tokens, a);
4328 snprintf(out, out_size, MSG_ARG_INVALID,
4337 if (n_tokens0 - n_tokens == 1) {
4338 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4342 return n_tokens0 - n_tokens;
4346 static const char cmd_pipeline_table_rule_add_help[] =
4347 "pipeline <pipeline_name> table <table_id> rule add\n"
4349 " action <table_action>\n";
4352 cmd_pipeline_table_rule_add(char **tokens,
4357 struct table_rule_match m;
4358 struct table_rule_action a;
4359 char *pipeline_name;
4360 uint32_t table_id, t0, n_tokens_parsed;
4364 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4368 pipeline_name = tokens[1];
4370 if (strcmp(tokens[2], "table") != 0) {
4371 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4375 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4376 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4380 if (strcmp(tokens[4], "rule") != 0) {
4381 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4385 if (strcmp(tokens[5], "add") != 0) {
4386 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4393 n_tokens_parsed = parse_match(tokens + t0,
4398 if (n_tokens_parsed == 0)
4400 t0 += n_tokens_parsed;
4403 n_tokens_parsed = parse_table_action(tokens + t0,
4408 if (n_tokens_parsed == 0)
4410 t0 += n_tokens_parsed;
4412 if (t0 != n_tokens) {
4413 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
4417 status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
4419 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4423 if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
4424 parse_free_sym_crypto_param_data(&a.sym_crypto);
4428 static const char cmd_pipeline_table_rule_add_default_help[] =
4429 "pipeline <pipeline_name> table <table_id> rule add\n"
4435 " | port <port_id>\n"
4437 " | table <table_id>\n";
4440 cmd_pipeline_table_rule_add_default(char **tokens,
4445 struct table_rule_action action;
4446 char *pipeline_name;
4450 if ((n_tokens != 11) && (n_tokens != 12)) {
4451 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4455 pipeline_name = tokens[1];
4457 if (strcmp(tokens[2], "table") != 0) {
4458 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4462 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4463 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4467 if (strcmp(tokens[4], "rule") != 0) {
4468 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4472 if (strcmp(tokens[5], "add") != 0) {
4473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4477 if (strcmp(tokens[6], "match") != 0) {
4478 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4482 if (strcmp(tokens[7], "default") != 0) {
4483 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4487 if (strcmp(tokens[8], "action") != 0) {
4488 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4492 if (strcmp(tokens[9], "fwd") != 0) {
4493 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4497 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4499 if (strcmp(tokens[10], "drop") == 0) {
4500 if (n_tokens != 11) {
4501 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4505 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4506 } else if (strcmp(tokens[10], "port") == 0) {
4509 if (n_tokens != 12) {
4510 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4514 if (parser_read_uint32(&id, tokens[11]) != 0) {
4515 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4519 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4521 } else if (strcmp(tokens[10], "meta") == 0) {
4522 if (n_tokens != 11) {
4523 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4527 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4528 } else if (strcmp(tokens[10], "table") == 0) {
4531 if (n_tokens != 12) {
4532 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4536 if (parser_read_uint32(&id, tokens[11]) != 0) {
4537 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4541 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4544 snprintf(out, out_size, MSG_ARG_INVALID,
4545 "drop or port or meta or table");
4549 status = pipeline_table_rule_add_default(pipeline_name,
4553 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4559 static const char cmd_pipeline_table_rule_add_bulk_help[] =
4560 "pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
4562 " File <file_name>:\n"
4563 " - line format: match <match> action <action>\n";
4566 cli_rule_file_process(const char *file_name,
4567 size_t line_len_max,
4568 struct table_rule_list **rule_list,
4570 uint32_t *line_number,
4575 cmd_pipeline_table_rule_add_bulk(char **tokens,
4580 struct table_rule_list *list = NULL;
4581 char *pipeline_name, *file_name;
4582 uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
4585 if (n_tokens != 8) {
4586 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4590 pipeline_name = tokens[1];
4592 if (strcmp(tokens[2], "table") != 0) {
4593 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4597 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4598 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4602 if (strcmp(tokens[4], "rule") != 0) {
4603 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4607 if (strcmp(tokens[5], "add") != 0) {
4608 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4612 if (strcmp(tokens[6], "bulk") != 0) {
4613 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4617 file_name = tokens[7];
4619 /* Load rules from file. */
4620 status = cli_rule_file_process(file_name,
4628 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4633 status = pipeline_table_rule_add_bulk(pipeline_name,
4637 &n_rules_not_added);
4639 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4643 snprintf(out, out_size, "Added %u rules out of %u.\n",
4649 static const char cmd_pipeline_table_rule_delete_help[] =
4650 "pipeline <pipeline_name> table <table_id> rule delete\n"
4654 cmd_pipeline_table_rule_delete(char **tokens,
4659 struct table_rule_match m;
4660 char *pipeline_name;
4661 uint32_t table_id, n_tokens_parsed, t0;
4665 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4669 pipeline_name = tokens[1];
4671 if (strcmp(tokens[2], "table") != 0) {
4672 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4676 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4677 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4681 if (strcmp(tokens[4], "rule") != 0) {
4682 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4686 if (strcmp(tokens[5], "delete") != 0) {
4687 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4694 n_tokens_parsed = parse_match(tokens + t0,
4699 if (n_tokens_parsed == 0)
4701 t0 += n_tokens_parsed;
4703 if (n_tokens != t0) {
4704 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4708 status = pipeline_table_rule_delete(pipeline_name,
4712 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4718 static const char cmd_pipeline_table_rule_delete_default_help[] =
4719 "pipeline <pipeline_name> table <table_id> rule delete\n"
4724 cmd_pipeline_table_rule_delete_default(char **tokens,
4729 char *pipeline_name;
4733 if (n_tokens != 8) {
4734 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4738 pipeline_name = tokens[1];
4740 if (strcmp(tokens[2], "table") != 0) {
4741 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4745 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4746 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4750 if (strcmp(tokens[4], "rule") != 0) {
4751 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4755 if (strcmp(tokens[5], "delete") != 0) {
4756 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4760 if (strcmp(tokens[6], "match") != 0) {
4761 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4765 if (strcmp(tokens[7], "default") != 0) {
4766 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4770 status = pipeline_table_rule_delete_default(pipeline_name,
4773 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4779 ether_addr_show(FILE *f, struct rte_ether_addr *addr)
4781 fprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x",
4782 (uint32_t)addr->addr_bytes[0], (uint32_t)addr->addr_bytes[1],
4783 (uint32_t)addr->addr_bytes[2], (uint32_t)addr->addr_bytes[3],
4784 (uint32_t)addr->addr_bytes[4], (uint32_t)addr->addr_bytes[5]);
4788 ipv4_addr_show(FILE *f, uint32_t addr)
4790 fprintf(f, "%u.%u.%u.%u",
4792 (addr >> 16) & 0xFF,
4798 ipv6_addr_show(FILE *f, uint8_t *addr)
4800 fprintf(f, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
4801 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:",
4802 (uint32_t)addr[0], (uint32_t)addr[1],
4803 (uint32_t)addr[2], (uint32_t)addr[3],
4804 (uint32_t)addr[4], (uint32_t)addr[5],
4805 (uint32_t)addr[6], (uint32_t)addr[7],
4806 (uint32_t)addr[8], (uint32_t)addr[9],
4807 (uint32_t)addr[10], (uint32_t)addr[11],
4808 (uint32_t)addr[12], (uint32_t)addr[13],
4809 (uint32_t)addr[14], (uint32_t)addr[15]);
4813 policer_action_string(enum rte_table_action_policer action) {
4815 case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
4816 case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
4817 case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
4818 case RTE_TABLE_ACTION_POLICER_DROP: return "D";
4819 default: return "?";
4824 table_rule_show(const char *pipeline_name,
4826 const char *file_name)
4829 struct table *table;
4830 struct table_rule *rule;
4834 /* Check input params. */
4835 if ((pipeline_name == NULL) ||
4836 (file_name == NULL))
4839 p = pipeline_find(pipeline_name);
4841 (table_id >= p->n_tables))
4844 table = &p->table[table_id];
4847 f = fopen(file_name, "w");
4851 /* Write table rules to file. */
4852 TAILQ_FOREACH(rule, &table->rules, node) {
4853 struct table_rule_match *m = &rule->match;
4854 struct table_rule_action *a = &rule->action;
4856 fprintf(f, "match ");
4857 switch (m->match_type) {
4859 fprintf(f, "acl priority %u ",
4860 m->match.acl.priority);
4862 fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
4864 if (m->match.acl.ip_version)
4865 ipv4_addr_show(f, m->match.acl.ipv4.sa);
4867 ipv6_addr_show(f, m->match.acl.ipv6.sa);
4869 fprintf(f, "%u", m->match.acl.sa_depth);
4871 if (m->match.acl.ip_version)
4872 ipv4_addr_show(f, m->match.acl.ipv4.da);
4874 ipv6_addr_show(f, m->match.acl.ipv6.da);
4876 fprintf(f, "%u", m->match.acl.da_depth);
4878 fprintf(f, "%u %u %u %u %u ",
4879 (uint32_t)m->match.acl.sp0,
4880 (uint32_t)m->match.acl.sp1,
4881 (uint32_t)m->match.acl.dp0,
4882 (uint32_t)m->match.acl.dp1,
4883 (uint32_t)m->match.acl.proto);
4887 fprintf(f, "array %u ",
4888 m->match.array.pos);
4892 fprintf(f, "hash raw ");
4893 for (i = 0; i < table->params.match.hash.key_size; i++)
4894 fprintf(f, "%02x", m->match.hash.key[i]);
4901 fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
4903 if (m->match.acl.ip_version)
4904 ipv4_addr_show(f, m->match.lpm.ipv4);
4906 ipv6_addr_show(f, m->match.lpm.ipv6);
4909 (uint32_t)m->match.lpm.depth);
4913 fprintf(f, "unknown ");
4916 fprintf(f, "action ");
4917 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
4919 switch (a->fwd.action) {
4920 case RTE_PIPELINE_ACTION_DROP:
4921 fprintf(f, "drop ");
4924 case RTE_PIPELINE_ACTION_PORT:
4925 fprintf(f, "port %u ", a->fwd.id);
4928 case RTE_PIPELINE_ACTION_PORT_META:
4929 fprintf(f, "meta ");
4932 case RTE_PIPELINE_ACTION_TABLE:
4934 fprintf(f, "table %u ", a->fwd.id);
4938 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
4939 fprintf(f, "balance ");
4940 for (i = 0; i < RTE_DIM(a->lb.out); i++)
4941 fprintf(f, "%u ", a->lb.out[i]);
4944 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
4946 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
4947 if (a->mtr.tc_mask & (1 << i)) {
4948 struct rte_table_action_mtr_tc_params *p =
4950 enum rte_table_action_policer ga =
4951 p->policer[RTE_COLOR_GREEN];
4952 enum rte_table_action_policer ya =
4953 p->policer[RTE_COLOR_YELLOW];
4954 enum rte_table_action_policer ra =
4955 p->policer[RTE_COLOR_RED];
4957 fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
4959 a->mtr.mtr[i].meter_profile_id,
4960 policer_action_string(ga),
4961 policer_action_string(ya),
4962 policer_action_string(ra));
4966 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
4967 fprintf(f, "tm subport %u pipe %u ",
4971 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
4972 fprintf(f, "encap ");
4973 switch (a->encap.type) {
4974 case RTE_TABLE_ACTION_ENCAP_ETHER:
4975 fprintf(f, "ether ");
4976 ether_addr_show(f, &a->encap.ether.ether.da);
4978 ether_addr_show(f, &a->encap.ether.ether.sa);
4982 case RTE_TABLE_ACTION_ENCAP_VLAN:
4983 fprintf(f, "vlan ");
4984 ether_addr_show(f, &a->encap.vlan.ether.da);
4986 ether_addr_show(f, &a->encap.vlan.ether.sa);
4987 fprintf(f, " pcp %u dei %u vid %u ",
4988 a->encap.vlan.vlan.pcp,
4989 a->encap.vlan.vlan.dei,
4990 a->encap.vlan.vlan.vid);
4993 case RTE_TABLE_ACTION_ENCAP_QINQ:
4994 fprintf(f, "qinq ");
4995 ether_addr_show(f, &a->encap.qinq.ether.da);
4997 ether_addr_show(f, &a->encap.qinq.ether.sa);
4998 fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
4999 a->encap.qinq.svlan.pcp,
5000 a->encap.qinq.svlan.dei,
5001 a->encap.qinq.svlan.vid,
5002 a->encap.qinq.cvlan.pcp,
5003 a->encap.qinq.cvlan.dei,
5004 a->encap.qinq.cvlan.vid);
5007 case RTE_TABLE_ACTION_ENCAP_MPLS:
5008 fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
5009 "unicast " : "multicast ");
5010 ether_addr_show(f, &a->encap.mpls.ether.da);
5012 ether_addr_show(f, &a->encap.mpls.ether.sa);
5014 for (i = 0; i < a->encap.mpls.mpls_count; i++) {
5015 struct rte_table_action_mpls_hdr *l =
5016 &a->encap.mpls.mpls[i];
5018 fprintf(f, "label%u %u %u %u ",
5026 case RTE_TABLE_ACTION_ENCAP_PPPOE:
5027 fprintf(f, "pppoe ");
5028 ether_addr_show(f, &a->encap.pppoe.ether.da);
5030 ether_addr_show(f, &a->encap.pppoe.ether.sa);
5031 fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
5034 case RTE_TABLE_ACTION_ENCAP_VXLAN:
5035 fprintf(f, "vxlan ether ");
5036 ether_addr_show(f, &a->encap.vxlan.ether.da);
5038 ether_addr_show(f, &a->encap.vxlan.ether.sa);
5039 if (table->ap->params.encap.vxlan.vlan)
5040 fprintf(f, " vlan pcp %u dei %u vid %u ",
5041 a->encap.vxlan.vlan.pcp,
5042 a->encap.vxlan.vlan.dei,
5043 a->encap.vxlan.vlan.vid);
5044 if (table->ap->params.encap.vxlan.ip_version) {
5045 fprintf(f, " ipv4 ");
5046 ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
5048 ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
5049 fprintf(f, " %u %u ",
5050 (uint32_t)a->encap.vxlan.ipv4.dscp,
5051 (uint32_t)a->encap.vxlan.ipv4.ttl);
5053 fprintf(f, " ipv6 ");
5054 ipv6_addr_show(f, a->encap.vxlan.ipv6.sa);
5056 ipv6_addr_show(f, a->encap.vxlan.ipv6.da);
5057 fprintf(f, " %u %u %u ",
5058 a->encap.vxlan.ipv6.flow_label,
5059 (uint32_t)a->encap.vxlan.ipv6.dscp,
5060 (uint32_t)a->encap.vxlan.ipv6.hop_limit);
5061 fprintf(f, " udp %u %u vxlan %u ",
5062 a->encap.vxlan.udp.sp,
5063 a->encap.vxlan.udp.dp,
5064 a->encap.vxlan.vxlan.vni);
5069 fprintf(f, "unknown ");
5073 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
5074 fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
5075 if (a->nat.ip_version)
5076 ipv4_addr_show(f, a->nat.addr.ipv4);
5078 ipv6_addr_show(f, a->nat.addr.ipv6);
5079 fprintf(f, " %u ", (uint32_t)(a->nat.port));
5082 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
5083 fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
5085 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
5086 fprintf(f, "stats ");
5088 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
5089 fprintf(f, "time ");
5091 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
5092 fprintf(f, "sym_crypto ");
5094 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
5095 fprintf(f, "tag %u ", a->tag.tag);
5097 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
5098 fprintf(f, "decap %u ", a->decap.n);
5104 /* Write table default rule to file. */
5105 if (table->rule_default) {
5106 struct table_rule_action *a = &table->rule_default->action;
5108 fprintf(f, "# match default action fwd ");
5110 switch (a->fwd.action) {
5111 case RTE_PIPELINE_ACTION_DROP:
5112 fprintf(f, "drop ");
5115 case RTE_PIPELINE_ACTION_PORT:
5116 fprintf(f, "port %u ", a->fwd.id);
5119 case RTE_PIPELINE_ACTION_PORT_META:
5120 fprintf(f, "meta ");
5123 case RTE_PIPELINE_ACTION_TABLE:
5125 fprintf(f, "table %u ", a->fwd.id);
5128 fprintf(f, "# match default action fwd drop ");
5138 static const char cmd_pipeline_table_rule_show_help[] =
5139 "pipeline <pipeline_name> table <table_id> rule show\n"
5140 " file <file_name>\n";
5143 cmd_pipeline_table_rule_show(char **tokens,
5148 char *file_name = NULL, *pipeline_name;
5152 if (n_tokens != 8) {
5153 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5157 pipeline_name = tokens[1];
5159 if (strcmp(tokens[2], "table") != 0) {
5160 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5164 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5165 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5169 if (strcmp(tokens[4], "rule") != 0) {
5170 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5174 if (strcmp(tokens[5], "show") != 0) {
5175 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
5179 if (strcmp(tokens[6], "file") != 0) {
5180 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
5184 file_name = tokens[7];
5186 status = table_rule_show(pipeline_name, table_id, file_name);
5188 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5193 static const char cmd_pipeline_table_rule_stats_read_help[] =
5194 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
5198 cmd_pipeline_table_rule_stats_read(char **tokens,
5203 struct table_rule_match m;
5204 struct rte_table_action_stats_counters stats;
5205 char *pipeline_name;
5206 uint32_t table_id, n_tokens_parsed;
5207 int clear = 0, status;
5210 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5214 pipeline_name = tokens[1];
5216 if (strcmp(tokens[2], "table") != 0) {
5217 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5221 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5222 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5226 if (strcmp(tokens[4], "rule") != 0) {
5227 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5231 if (strcmp(tokens[5], "read") != 0) {
5232 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5236 if (strcmp(tokens[6], "stats") != 0) {
5237 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
5245 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5253 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5254 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5258 n_tokens_parsed = parse_match(tokens,
5263 if (n_tokens_parsed == 0)
5265 n_tokens -= n_tokens_parsed;
5266 tokens += n_tokens_parsed;
5270 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5274 /* Read table rule stats. */
5275 status = pipeline_table_rule_stats_read(pipeline_name,
5281 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5286 if (stats.n_packets_valid && stats.n_bytes_valid)
5287 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
5291 if (stats.n_packets_valid && !stats.n_bytes_valid)
5292 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
5295 if (!stats.n_packets_valid && stats.n_bytes_valid)
5296 snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
5299 if (!stats.n_packets_valid && !stats.n_bytes_valid)
5300 snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
5303 static const char cmd_pipeline_table_meter_profile_add_help[] =
5304 "pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
5305 " add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
5306 " | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
5309 cmd_pipeline_table_meter_profile_add(char **tokens,
5314 struct rte_table_action_meter_profile p;
5315 char *pipeline_name;
5316 uint32_t table_id, meter_profile_id;
5320 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5324 pipeline_name = tokens[1];
5326 if (strcmp(tokens[2], "table") != 0) {
5327 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5331 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5332 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5336 if (strcmp(tokens[4], "meter") != 0) {
5337 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5341 if (strcmp(tokens[5], "profile") != 0) {
5342 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5346 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5347 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5351 if (strcmp(tokens[7], "add") != 0) {
5352 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
5356 if (strcmp(tokens[8], "srtcm") == 0) {
5357 if (n_tokens != 15) {
5358 snprintf(out, out_size, MSG_ARG_MISMATCH,
5363 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
5365 if (strcmp(tokens[9], "cir") != 0) {
5366 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5370 if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
5371 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5375 if (strcmp(tokens[11], "cbs") != 0) {
5376 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5380 if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
5381 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5385 if (strcmp(tokens[13], "ebs") != 0) {
5386 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
5390 if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
5391 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
5394 } else if (strcmp(tokens[8], "trtcm") == 0) {
5395 if (n_tokens != 17) {
5396 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5400 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
5402 if (strcmp(tokens[9], "cir") != 0) {
5403 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5407 if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
5408 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5412 if (strcmp(tokens[11], "pir") != 0) {
5413 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
5417 if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
5418 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
5421 if (strcmp(tokens[13], "cbs") != 0) {
5422 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5426 if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
5427 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5431 if (strcmp(tokens[15], "pbs") != 0) {
5432 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
5436 if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
5437 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
5441 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5445 status = pipeline_table_mtr_profile_add(pipeline_name,
5450 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5456 static const char cmd_pipeline_table_meter_profile_delete_help[] =
5457 "pipeline <pipeline_name> table <table_id>\n"
5458 " meter profile <meter_profile_id> delete\n";
5461 cmd_pipeline_table_meter_profile_delete(char **tokens,
5466 char *pipeline_name;
5467 uint32_t table_id, meter_profile_id;
5470 if (n_tokens != 8) {
5471 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5475 pipeline_name = tokens[1];
5477 if (strcmp(tokens[2], "table") != 0) {
5478 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5482 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5483 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5487 if (strcmp(tokens[4], "meter") != 0) {
5488 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5492 if (strcmp(tokens[5], "profile") != 0) {
5493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5497 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5498 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5502 if (strcmp(tokens[7], "delete") != 0) {
5503 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
5507 status = pipeline_table_mtr_profile_delete(pipeline_name,
5511 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5517 static const char cmd_pipeline_table_rule_meter_read_help[] =
5518 "pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
5522 cmd_pipeline_table_rule_meter_read(char **tokens,
5527 struct table_rule_match m;
5528 struct rte_table_action_mtr_counters stats;
5529 char *pipeline_name;
5530 uint32_t table_id, n_tokens_parsed;
5531 int clear = 0, status;
5534 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5538 pipeline_name = tokens[1];
5540 if (strcmp(tokens[2], "table") != 0) {
5541 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5545 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5546 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5550 if (strcmp(tokens[4], "rule") != 0) {
5551 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5555 if (strcmp(tokens[5], "read") != 0) {
5556 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5560 if (strcmp(tokens[6], "meter") != 0) {
5561 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5569 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5577 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5578 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5582 n_tokens_parsed = parse_match(tokens,
5587 if (n_tokens_parsed == 0)
5589 n_tokens -= n_tokens_parsed;
5590 tokens += n_tokens_parsed;
5594 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5598 /* Read table rule meter stats. */
5599 status = pipeline_table_rule_mtr_read(pipeline_name,
5605 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5613 static const char cmd_pipeline_table_dscp_help[] =
5614 "pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
5616 " File <file_name>:\n"
5617 " - exactly 64 lines\n"
5618 " - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
5621 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
5622 const char *file_name,
5623 uint32_t *line_number)
5628 /* Check input arguments */
5629 if ((dscp_table == NULL) ||
5630 (file_name == NULL) ||
5631 (line_number == NULL)) {
5637 /* Open input file */
5638 f = fopen(file_name, "r");
5645 for (dscp = 0, l = 1; ; l++) {
5648 enum rte_color color;
5649 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
5651 if (fgets(line, sizeof(line), f) == NULL)
5654 if (is_comment(line))
5657 if (parse_tokenize_string(line, tokens, &n_tokens)) {
5666 if ((dscp >= RTE_DIM(dscp_table->entry)) ||
5667 (n_tokens != RTE_DIM(tokens)) ||
5668 parser_read_uint32(&tc_id, tokens[0]) ||
5669 (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
5670 parser_read_uint32(&tc_queue_id, tokens[1]) ||
5671 (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
5672 (strlen(tokens[2]) != 1)) {
5678 switch (tokens[2][0]) {
5681 color = RTE_COLOR_GREEN;
5686 color = RTE_COLOR_YELLOW;
5691 color = RTE_COLOR_RED;
5700 dscp_table->entry[dscp].tc_id = tc_id;
5701 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
5702 dscp_table->entry[dscp].color = color;
5712 cmd_pipeline_table_dscp(char **tokens,
5717 struct rte_table_action_dscp_table dscp_table;
5718 char *pipeline_name, *file_name;
5719 uint32_t table_id, line_number;
5722 if (n_tokens != 6) {
5723 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5727 pipeline_name = tokens[1];
5729 if (strcmp(tokens[2], "table") != 0) {
5730 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5734 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5735 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5739 if (strcmp(tokens[4], "dscp") != 0) {
5740 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
5744 file_name = tokens[5];
5746 status = load_dscp_table(&dscp_table, file_name, &line_number);
5748 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
5752 status = pipeline_table_dscp_table_update(pipeline_name,
5757 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5763 static const char cmd_pipeline_table_rule_ttl_read_help[] =
5764 "pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
5768 cmd_pipeline_table_rule_ttl_read(char **tokens,
5773 struct table_rule_match m;
5774 struct rte_table_action_ttl_counters stats;
5775 char *pipeline_name;
5776 uint32_t table_id, n_tokens_parsed;
5777 int clear = 0, status;
5780 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5784 pipeline_name = tokens[1];
5786 if (strcmp(tokens[2], "table") != 0) {
5787 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5791 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5792 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5796 if (strcmp(tokens[4], "rule") != 0) {
5797 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5801 if (strcmp(tokens[5], "read") != 0) {
5802 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5806 if (strcmp(tokens[6], "ttl") != 0) {
5807 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
5815 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5823 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5824 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5828 n_tokens_parsed = parse_match(tokens,
5833 if (n_tokens_parsed == 0)
5835 n_tokens -= n_tokens_parsed;
5836 tokens += n_tokens_parsed;
5840 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5844 /* Read table rule TTL stats. */
5845 status = pipeline_table_rule_ttl_read(pipeline_name,
5851 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5856 snprintf(out, out_size, "Packets: %" PRIu64 "\n",
5860 static const char cmd_pipeline_table_rule_time_read_help[] =
5861 "pipeline <pipeline_name> table <table_id> rule read time\n"
5865 cmd_pipeline_table_rule_time_read(char **tokens,
5870 struct table_rule_match m;
5871 char *pipeline_name;
5873 uint32_t table_id, n_tokens_parsed;
5877 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5881 pipeline_name = tokens[1];
5883 if (strcmp(tokens[2], "table") != 0) {
5884 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5888 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5889 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5893 if (strcmp(tokens[4], "rule") != 0) {
5894 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5898 if (strcmp(tokens[5], "read") != 0) {
5899 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5903 if (strcmp(tokens[6], "time") != 0) {
5904 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
5912 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5913 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5917 n_tokens_parsed = parse_match(tokens,
5922 if (n_tokens_parsed == 0)
5924 n_tokens -= n_tokens_parsed;
5925 tokens += n_tokens_parsed;
5929 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5933 /* Read table rule timestamp. */
5934 status = pipeline_table_rule_time_read(pipeline_name,
5939 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5944 snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
5947 static const char cmd_thread_pipeline_enable_help[] =
5948 "thread <thread_id> pipeline <pipeline_name> enable\n";
5951 cmd_thread_pipeline_enable(char **tokens,
5956 char *pipeline_name;
5960 if (n_tokens != 5) {
5961 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5965 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
5966 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
5970 if (strcmp(tokens[2], "pipeline") != 0) {
5971 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5975 pipeline_name = tokens[3];
5977 if (strcmp(tokens[4], "enable") != 0) {
5978 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
5982 status = thread_pipeline_enable(thread_id, pipeline_name);
5984 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
5990 static const char cmd_thread_pipeline_disable_help[] =
5991 "thread <thread_id> pipeline <pipeline_name> disable\n";
5994 cmd_thread_pipeline_disable(char **tokens,
5999 char *pipeline_name;
6003 if (n_tokens != 5) {
6004 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6008 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
6009 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
6013 if (strcmp(tokens[2], "pipeline") != 0) {
6014 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
6018 pipeline_name = tokens[3];
6020 if (strcmp(tokens[4], "disable") != 0) {
6021 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
6025 status = thread_pipeline_disable(thread_id, pipeline_name);
6027 snprintf(out, out_size, MSG_CMD_FAIL,
6028 "thread pipeline disable");
6034 cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
6039 if (n_tokens == 0) {
6040 snprintf(out, out_size,
6041 "Type 'help <command>' for details on each command.\n\n"
6042 "List of commands:\n"
6046 "\ttmgr subport profile\n"
6047 "\ttmgr pipe profile\n"
6050 "\ttmgr subport pipe\n"
6053 "\tport in action profile\n"
6054 "\ttable action profile\n"
6056 "\tpipeline port in\n"
6057 "\tpipeline port out\n"
6058 "\tpipeline table\n"
6059 "\tpipeline port in table\n"
6060 "\tpipeline port in stats\n"
6061 "\tpipeline port in enable\n"
6062 "\tpipeline port in disable\n"
6063 "\tpipeline port out stats\n"
6064 "\tpipeline table stats\n"
6065 "\tpipeline table rule add\n"
6066 "\tpipeline table rule add default\n"
6067 "\tpipeline table rule add bulk\n"
6068 "\tpipeline table rule delete\n"
6069 "\tpipeline table rule delete default\n"
6070 "\tpipeline table rule show\n"
6071 "\tpipeline table rule stats read\n"
6072 "\tpipeline table meter profile add\n"
6073 "\tpipeline table meter profile delete\n"
6074 "\tpipeline table rule meter read\n"
6075 "\tpipeline table dscp\n"
6076 "\tpipeline table rule ttl read\n"
6077 "\tpipeline table rule time read\n"
6078 "\tthread pipeline enable\n"
6079 "\tthread pipeline disable\n\n");
6083 if (strcmp(tokens[0], "mempool") == 0) {
6084 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
6088 if (strcmp(tokens[0], "link") == 0) {
6089 snprintf(out, out_size, "\n%s\n", cmd_link_help);
6093 if (strcmp(tokens[0], "swq") == 0) {
6094 snprintf(out, out_size, "\n%s\n", cmd_swq_help);
6098 if (strcmp(tokens[0], "tmgr") == 0) {
6099 if (n_tokens == 1) {
6100 snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
6104 if ((n_tokens == 2) &&
6105 (strcmp(tokens[1], "subport")) == 0) {
6106 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
6110 if ((n_tokens == 3) &&
6111 (strcmp(tokens[1], "subport") == 0) &&
6112 (strcmp(tokens[2], "profile") == 0)) {
6113 snprintf(out, out_size, "\n%s\n",
6114 cmd_tmgr_subport_profile_help);
6118 if ((n_tokens == 3) &&
6119 (strcmp(tokens[1], "subport") == 0) &&
6120 (strcmp(tokens[2], "pipe") == 0)) {
6121 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
6125 if ((n_tokens == 3) &&
6126 (strcmp(tokens[1], "pipe") == 0) &&
6127 (strcmp(tokens[2], "profile") == 0)) {
6128 snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
6133 if (strcmp(tokens[0], "tap") == 0) {
6134 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
6138 if (strcmp(tokens[0], "kni") == 0) {
6139 snprintf(out, out_size, "\n%s\n", cmd_kni_help);
6143 if (strcmp(tokens[0], "cryptodev") == 0) {
6144 snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
6148 if ((n_tokens == 4) &&
6149 (strcmp(tokens[0], "port") == 0) &&
6150 (strcmp(tokens[1], "in") == 0) &&
6151 (strcmp(tokens[2], "action") == 0) &&
6152 (strcmp(tokens[3], "profile") == 0)) {
6153 snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
6157 if ((n_tokens == 3) &&
6158 (strcmp(tokens[0], "table") == 0) &&
6159 (strcmp(tokens[1], "action") == 0) &&
6160 (strcmp(tokens[2], "profile") == 0)) {
6161 snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
6165 if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
6166 snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
6170 if ((strcmp(tokens[0], "pipeline") == 0) &&
6171 (strcmp(tokens[1], "port") == 0)) {
6172 if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
6173 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
6177 if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
6178 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
6182 if ((n_tokens == 4) &&
6183 (strcmp(tokens[2], "in") == 0) &&
6184 (strcmp(tokens[3], "table") == 0)) {
6185 snprintf(out, out_size, "\n%s\n",
6186 cmd_pipeline_port_in_table_help);
6190 if ((n_tokens == 4) &&
6191 (strcmp(tokens[2], "in") == 0) &&
6192 (strcmp(tokens[3], "stats") == 0)) {
6193 snprintf(out, out_size, "\n%s\n",
6194 cmd_pipeline_port_in_stats_help);
6198 if ((n_tokens == 4) &&
6199 (strcmp(tokens[2], "in") == 0) &&
6200 (strcmp(tokens[3], "enable") == 0)) {
6201 snprintf(out, out_size, "\n%s\n",
6202 cmd_pipeline_port_in_enable_help);
6206 if ((n_tokens == 4) &&
6207 (strcmp(tokens[2], "in") == 0) &&
6208 (strcmp(tokens[3], "disable") == 0)) {
6209 snprintf(out, out_size, "\n%s\n",
6210 cmd_pipeline_port_in_disable_help);
6214 if ((n_tokens == 4) &&
6215 (strcmp(tokens[2], "out") == 0) &&
6216 (strcmp(tokens[3], "stats") == 0)) {
6217 snprintf(out, out_size, "\n%s\n",
6218 cmd_pipeline_port_out_stats_help);
6223 if ((strcmp(tokens[0], "pipeline") == 0) &&
6224 (strcmp(tokens[1], "table") == 0)) {
6225 if (n_tokens == 2) {
6226 snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
6230 if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
6231 snprintf(out, out_size, "\n%s\n",
6232 cmd_pipeline_table_stats_help);
6236 if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
6237 snprintf(out, out_size, "\n%s\n",
6238 cmd_pipeline_table_dscp_help);
6242 if ((n_tokens == 4) &&
6243 (strcmp(tokens[2], "rule") == 0) &&
6244 (strcmp(tokens[3], "add") == 0)) {
6245 snprintf(out, out_size, "\n%s\n",
6246 cmd_pipeline_table_rule_add_help);
6250 if ((n_tokens == 5) &&
6251 (strcmp(tokens[2], "rule") == 0) &&
6252 (strcmp(tokens[3], "add") == 0) &&
6253 (strcmp(tokens[4], "default") == 0)) {
6254 snprintf(out, out_size, "\n%s\n",
6255 cmd_pipeline_table_rule_add_default_help);
6259 if ((n_tokens == 5) &&
6260 (strcmp(tokens[2], "rule") == 0) &&
6261 (strcmp(tokens[3], "add") == 0) &&
6262 (strcmp(tokens[4], "bulk") == 0)) {
6263 snprintf(out, out_size, "\n%s\n",
6264 cmd_pipeline_table_rule_add_bulk_help);
6268 if ((n_tokens == 4) &&
6269 (strcmp(tokens[2], "rule") == 0) &&
6270 (strcmp(tokens[3], "delete") == 0)) {
6271 snprintf(out, out_size, "\n%s\n",
6272 cmd_pipeline_table_rule_delete_help);
6276 if ((n_tokens == 5) &&
6277 (strcmp(tokens[2], "rule") == 0) &&
6278 (strcmp(tokens[3], "delete") == 0) &&
6279 (strcmp(tokens[4], "default") == 0)) {
6280 snprintf(out, out_size, "\n%s\n",
6281 cmd_pipeline_table_rule_delete_default_help);
6285 if ((n_tokens == 4) &&
6286 (strcmp(tokens[2], "rule") == 0) &&
6287 (strcmp(tokens[3], "show") == 0)) {
6288 snprintf(out, out_size, "\n%s\n",
6289 cmd_pipeline_table_rule_show_help);
6293 if ((n_tokens == 5) &&
6294 (strcmp(tokens[2], "rule") == 0) &&
6295 (strcmp(tokens[3], "stats") == 0) &&
6296 (strcmp(tokens[4], "read") == 0)) {
6297 snprintf(out, out_size, "\n%s\n",
6298 cmd_pipeline_table_rule_stats_read_help);
6302 if ((n_tokens == 5) &&
6303 (strcmp(tokens[2], "meter") == 0) &&
6304 (strcmp(tokens[3], "profile") == 0) &&
6305 (strcmp(tokens[4], "add") == 0)) {
6306 snprintf(out, out_size, "\n%s\n",
6307 cmd_pipeline_table_meter_profile_add_help);
6311 if ((n_tokens == 5) &&
6312 (strcmp(tokens[2], "meter") == 0) &&
6313 (strcmp(tokens[3], "profile") == 0) &&
6314 (strcmp(tokens[4], "delete") == 0)) {
6315 snprintf(out, out_size, "\n%s\n",
6316 cmd_pipeline_table_meter_profile_delete_help);
6320 if ((n_tokens == 5) &&
6321 (strcmp(tokens[2], "rule") == 0) &&
6322 (strcmp(tokens[3], "meter") == 0) &&
6323 (strcmp(tokens[4], "read") == 0)) {
6324 snprintf(out, out_size, "\n%s\n",
6325 cmd_pipeline_table_rule_meter_read_help);
6329 if ((n_tokens == 5) &&
6330 (strcmp(tokens[2], "rule") == 0) &&
6331 (strcmp(tokens[3], "ttl") == 0) &&
6332 (strcmp(tokens[4], "read") == 0)) {
6333 snprintf(out, out_size, "\n%s\n",
6334 cmd_pipeline_table_rule_ttl_read_help);
6338 if ((n_tokens == 5) &&
6339 (strcmp(tokens[2], "rule") == 0) &&
6340 (strcmp(tokens[3], "time") == 0) &&
6341 (strcmp(tokens[4], "read") == 0)) {
6342 snprintf(out, out_size, "\n%s\n",
6343 cmd_pipeline_table_rule_time_read_help);
6348 if ((n_tokens == 3) &&
6349 (strcmp(tokens[0], "thread") == 0) &&
6350 (strcmp(tokens[1], "pipeline") == 0)) {
6351 if (strcmp(tokens[2], "enable") == 0) {
6352 snprintf(out, out_size, "\n%s\n",
6353 cmd_thread_pipeline_enable_help);
6357 if (strcmp(tokens[2], "disable") == 0) {
6358 snprintf(out, out_size, "\n%s\n",
6359 cmd_thread_pipeline_disable_help);
6364 snprintf(out, out_size, "Invalid command\n");
6368 cli_process(char *in, char *out, size_t out_size)
6370 char *tokens[CMD_MAX_TOKENS];
6371 uint32_t n_tokens = RTE_DIM(tokens);
6377 status = parse_tokenize_string(in, tokens, &n_tokens);
6379 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
6386 if (strcmp(tokens[0], "help") == 0) {
6387 cmd_help(tokens, n_tokens, out, out_size);
6391 if (strcmp(tokens[0], "mempool") == 0) {
6392 cmd_mempool(tokens, n_tokens, out, out_size);
6396 if (strcmp(tokens[0], "link") == 0) {
6397 if (strcmp(tokens[1], "show") == 0) {
6398 cmd_link_show(tokens, n_tokens, out, out_size);
6402 cmd_link(tokens, n_tokens, out, out_size);
6406 if (strcmp(tokens[0], "swq") == 0) {
6407 cmd_swq(tokens, n_tokens, out, out_size);
6411 if (strcmp(tokens[0], "tmgr") == 0) {
6412 if ((n_tokens >= 3) &&
6413 (strcmp(tokens[1], "subport") == 0) &&
6414 (strcmp(tokens[2], "profile") == 0)) {
6415 cmd_tmgr_subport_profile(tokens, n_tokens,
6420 if ((n_tokens >= 3) &&
6421 (strcmp(tokens[1], "pipe") == 0) &&
6422 (strcmp(tokens[2], "profile") == 0)) {
6423 cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
6427 if ((n_tokens >= 5) &&
6428 (strcmp(tokens[2], "subport") == 0) &&
6429 (strcmp(tokens[4], "profile") == 0)) {
6430 cmd_tmgr_subport(tokens, n_tokens, out, out_size);
6434 if ((n_tokens >= 5) &&
6435 (strcmp(tokens[2], "subport") == 0) &&
6436 (strcmp(tokens[4], "pipe") == 0)) {
6437 cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
6441 cmd_tmgr(tokens, n_tokens, out, out_size);
6445 if (strcmp(tokens[0], "tap") == 0) {
6446 cmd_tap(tokens, n_tokens, out, out_size);
6450 if (strcmp(tokens[0], "kni") == 0) {
6451 cmd_kni(tokens, n_tokens, out, out_size);
6455 if (strcmp(tokens[0], "cryptodev") == 0) {
6456 cmd_cryptodev(tokens, n_tokens, out, out_size);
6460 if (strcmp(tokens[0], "port") == 0) {
6461 cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
6465 if (strcmp(tokens[0], "table") == 0) {
6466 cmd_table_action_profile(tokens, n_tokens, out, out_size);
6470 if (strcmp(tokens[0], "pipeline") == 0) {
6471 if ((n_tokens >= 3) &&
6472 (strcmp(tokens[2], "period") == 0)) {
6473 cmd_pipeline(tokens, n_tokens, out, out_size);
6477 if ((n_tokens >= 5) &&
6478 (strcmp(tokens[2], "port") == 0) &&
6479 (strcmp(tokens[3], "in") == 0) &&
6480 (strcmp(tokens[4], "bsz") == 0)) {
6481 cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
6485 if ((n_tokens >= 5) &&
6486 (strcmp(tokens[2], "port") == 0) &&
6487 (strcmp(tokens[3], "out") == 0) &&
6488 (strcmp(tokens[4], "bsz") == 0)) {
6489 cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
6493 if ((n_tokens >= 4) &&
6494 (strcmp(tokens[2], "table") == 0) &&
6495 (strcmp(tokens[3], "match") == 0)) {
6496 cmd_pipeline_table(tokens, n_tokens, out, out_size);
6500 if ((n_tokens >= 6) &&
6501 (strcmp(tokens[2], "port") == 0) &&
6502 (strcmp(tokens[3], "in") == 0) &&
6503 (strcmp(tokens[5], "table") == 0)) {
6504 cmd_pipeline_port_in_table(tokens, n_tokens,
6509 if ((n_tokens >= 6) &&
6510 (strcmp(tokens[2], "port") == 0) &&
6511 (strcmp(tokens[3], "in") == 0) &&
6512 (strcmp(tokens[5], "stats") == 0)) {
6513 cmd_pipeline_port_in_stats(tokens, n_tokens,
6518 if ((n_tokens >= 6) &&
6519 (strcmp(tokens[2], "port") == 0) &&
6520 (strcmp(tokens[3], "in") == 0) &&
6521 (strcmp(tokens[5], "enable") == 0)) {
6522 cmd_pipeline_port_in_enable(tokens, n_tokens,
6527 if ((n_tokens >= 6) &&
6528 (strcmp(tokens[2], "port") == 0) &&
6529 (strcmp(tokens[3], "in") == 0) &&
6530 (strcmp(tokens[5], "disable") == 0)) {
6531 cmd_pipeline_port_in_disable(tokens, n_tokens,
6536 if ((n_tokens >= 6) &&
6537 (strcmp(tokens[2], "port") == 0) &&
6538 (strcmp(tokens[3], "out") == 0) &&
6539 (strcmp(tokens[5], "stats") == 0)) {
6540 cmd_pipeline_port_out_stats(tokens, n_tokens,
6545 if ((n_tokens >= 5) &&
6546 (strcmp(tokens[2], "table") == 0) &&
6547 (strcmp(tokens[4], "stats") == 0)) {
6548 cmd_pipeline_table_stats(tokens, n_tokens,
6553 if ((n_tokens >= 7) &&
6554 (strcmp(tokens[2], "table") == 0) &&
6555 (strcmp(tokens[4], "rule") == 0) &&
6556 (strcmp(tokens[5], "add") == 0) &&
6557 (strcmp(tokens[6], "match") == 0)) {
6558 if ((n_tokens >= 8) &&
6559 (strcmp(tokens[7], "default") == 0)) {
6560 cmd_pipeline_table_rule_add_default(tokens,
6561 n_tokens, out, out_size);
6565 cmd_pipeline_table_rule_add(tokens, n_tokens,
6570 if ((n_tokens >= 7) &&
6571 (strcmp(tokens[2], "table") == 0) &&
6572 (strcmp(tokens[4], "rule") == 0) &&
6573 (strcmp(tokens[5], "add") == 0) &&
6574 (strcmp(tokens[6], "bulk") == 0)) {
6575 cmd_pipeline_table_rule_add_bulk(tokens,
6576 n_tokens, out, out_size);
6580 if ((n_tokens >= 7) &&
6581 (strcmp(tokens[2], "table") == 0) &&
6582 (strcmp(tokens[4], "rule") == 0) &&
6583 (strcmp(tokens[5], "delete") == 0) &&
6584 (strcmp(tokens[6], "match") == 0)) {
6585 if ((n_tokens >= 8) &&
6586 (strcmp(tokens[7], "default") == 0)) {
6587 cmd_pipeline_table_rule_delete_default(tokens,
6588 n_tokens, out, out_size);
6592 cmd_pipeline_table_rule_delete(tokens, n_tokens,
6597 if ((n_tokens >= 6) &&
6598 (strcmp(tokens[2], "table") == 0) &&
6599 (strcmp(tokens[4], "rule") == 0) &&
6600 (strcmp(tokens[5], "show") == 0)) {
6601 cmd_pipeline_table_rule_show(tokens, n_tokens,
6606 if ((n_tokens >= 7) &&
6607 (strcmp(tokens[2], "table") == 0) &&
6608 (strcmp(tokens[4], "rule") == 0) &&
6609 (strcmp(tokens[5], "read") == 0) &&
6610 (strcmp(tokens[6], "stats") == 0)) {
6611 cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
6616 if ((n_tokens >= 8) &&
6617 (strcmp(tokens[2], "table") == 0) &&
6618 (strcmp(tokens[4], "meter") == 0) &&
6619 (strcmp(tokens[5], "profile") == 0) &&
6620 (strcmp(tokens[7], "add") == 0)) {
6621 cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
6626 if ((n_tokens >= 8) &&
6627 (strcmp(tokens[2], "table") == 0) &&
6628 (strcmp(tokens[4], "meter") == 0) &&
6629 (strcmp(tokens[5], "profile") == 0) &&
6630 (strcmp(tokens[7], "delete") == 0)) {
6631 cmd_pipeline_table_meter_profile_delete(tokens,
6632 n_tokens, out, out_size);
6636 if ((n_tokens >= 7) &&
6637 (strcmp(tokens[2], "table") == 0) &&
6638 (strcmp(tokens[4], "rule") == 0) &&
6639 (strcmp(tokens[5], "read") == 0) &&
6640 (strcmp(tokens[6], "meter") == 0)) {
6641 cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
6646 if ((n_tokens >= 5) &&
6647 (strcmp(tokens[2], "table") == 0) &&
6648 (strcmp(tokens[4], "dscp") == 0)) {
6649 cmd_pipeline_table_dscp(tokens, n_tokens,
6654 if ((n_tokens >= 7) &&
6655 (strcmp(tokens[2], "table") == 0) &&
6656 (strcmp(tokens[4], "rule") == 0) &&
6657 (strcmp(tokens[5], "read") == 0) &&
6658 (strcmp(tokens[6], "ttl") == 0)) {
6659 cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
6664 if ((n_tokens >= 7) &&
6665 (strcmp(tokens[2], "table") == 0) &&
6666 (strcmp(tokens[4], "rule") == 0) &&
6667 (strcmp(tokens[5], "read") == 0) &&
6668 (strcmp(tokens[6], "time") == 0)) {
6669 cmd_pipeline_table_rule_time_read(tokens, n_tokens,
6675 if (strcmp(tokens[0], "thread") == 0) {
6676 if ((n_tokens >= 5) &&
6677 (strcmp(tokens[4], "enable") == 0)) {
6678 cmd_thread_pipeline_enable(tokens, n_tokens,
6683 if ((n_tokens >= 5) &&
6684 (strcmp(tokens[4], "disable") == 0)) {
6685 cmd_thread_pipeline_disable(tokens, n_tokens,
6691 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
6695 cli_script_process(const char *file_name,
6696 size_t msg_in_len_max,
6697 size_t msg_out_len_max)
6699 char *msg_in = NULL, *msg_out = NULL;
6702 /* Check input arguments */
6703 if ((file_name == NULL) ||
6704 (strlen(file_name) == 0) ||
6705 (msg_in_len_max == 0) ||
6706 (msg_out_len_max == 0))
6709 msg_in = malloc(msg_in_len_max + 1);
6710 msg_out = malloc(msg_out_len_max + 1);
6711 if ((msg_in == NULL) ||
6712 (msg_out == NULL)) {
6718 /* Open input file */
6719 f = fopen(file_name, "r");
6728 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
6731 printf("%s", msg_in);
6738 if (strlen(msg_out))
6739 printf("%s", msg_out);
6750 cli_rule_file_process(const char *file_name,
6751 size_t line_len_max,
6752 struct table_rule_list **rule_list,
6754 uint32_t *line_number,
6758 struct table_rule_list *list = NULL;
6761 uint32_t rule_id = 0, line_id = 0;
6764 /* Check input arguments */
6765 if ((file_name == NULL) ||
6766 (strlen(file_name) == 0) ||
6767 (line_len_max == 0) ||
6768 (rule_list == NULL) ||
6769 (n_rules == NULL) ||
6770 (line_number == NULL) ||
6773 goto cli_rule_file_process_free;
6776 /* Memory allocation */
6777 list = malloc(sizeof(struct table_rule_list));
6780 goto cli_rule_file_process_free;
6785 line = malloc(line_len_max + 1);
6788 goto cli_rule_file_process_free;
6792 f = fopen(file_name, "r");
6795 goto cli_rule_file_process_free;
6799 for (line_id = 1, rule_id = 0; ; line_id++) {
6800 char *tokens[CMD_MAX_TOKENS];
6801 struct table_rule *rule = NULL;
6802 uint32_t n_tokens, n_tokens_parsed, t0;
6804 /* Read next line from file. */
6805 if (fgets(line, line_len_max + 1, f) == NULL)
6809 if (is_comment(line))
6813 n_tokens = RTE_DIM(tokens);
6814 status = parse_tokenize_string(line, tokens, &n_tokens);
6817 goto cli_rule_file_process_free;
6825 /* Rule alloc and insert. */
6826 rule = calloc(1, sizeof(struct table_rule));
6829 goto cli_rule_file_process_free;
6832 TAILQ_INSERT_TAIL(list, rule, node);
6835 n_tokens_parsed = parse_match(tokens + t0,
6840 if (n_tokens_parsed == 0) {
6842 goto cli_rule_file_process_free;
6844 t0 += n_tokens_parsed;
6847 n_tokens_parsed = parse_table_action(tokens + t0,
6852 if (n_tokens_parsed == 0) {
6854 goto cli_rule_file_process_free;
6856 t0 += n_tokens_parsed;
6858 /* Line completed. */
6859 if (t0 < n_tokens) {
6861 goto cli_rule_file_process_free;
6864 /* Increment rule count */
6876 *line_number = line_id;
6879 cli_rule_file_process_free:
6880 if (rule_list != NULL)
6883 if (n_rules != NULL)
6886 if (line_number != NULL)
6887 *line_number = line_id;
6891 struct table_rule *rule;
6893 rule = TAILQ_FIRST(list);
6897 TAILQ_REMOVE(list, rule, node);