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>\n"
384 cmd_tmgr_subport_profile(char **tokens,
389 struct rte_sched_subport_params p;
392 if (n_tokens != 10) {
393 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
397 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
398 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
402 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
403 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
407 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
408 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
409 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
413 if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
414 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
418 status = tmgr_subport_profile_add(&p);
420 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
425 static const char cmd_tmgr_pipe_profile_help[] =
426 "tmgr pipe profile\n"
427 " <tb_rate> <tb_size>\n"
428 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n"
431 " <wrr_weight0..15>\n";
434 cmd_tmgr_pipe_profile(char **tokens,
439 struct rte_sched_pipe_params p;
442 if (n_tokens != 27) {
443 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
447 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
448 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
452 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
453 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
457 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
458 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
459 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
463 if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
464 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
468 #ifdef RTE_SCHED_SUBPORT_TC_OV
469 if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) {
470 snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
475 for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++)
476 if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + i]) != 0) {
477 snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
481 status = tmgr_pipe_profile_add(&p);
483 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
488 static const char cmd_tmgr_help[] =
491 " spp <n_subports_per_port>\n"
492 " pps <n_pipes_per_subport>\n"
493 " qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n"
494 " fo <frame_overhead>\n"
499 cmd_tmgr(char **tokens,
504 struct tmgr_port_params p;
506 struct tmgr_port *tmgr_port;
509 if (n_tokens != 19) {
510 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
516 if (strcmp(tokens[2], "rate") != 0) {
517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
521 if (parser_read_uint32(&p.rate, tokens[3]) != 0) {
522 snprintf(out, out_size, MSG_ARG_INVALID, "rate");
526 if (strcmp(tokens[4], "spp") != 0) {
527 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
531 if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
532 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
536 if (strcmp(tokens[6], "pps") != 0) {
537 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
541 if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
542 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
546 if (strcmp(tokens[8], "qsize") != 0) {
547 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize");
551 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
552 if (parser_read_uint16(&p.qsize[i], tokens[9 + i]) != 0) {
553 snprintf(out, out_size, MSG_ARG_INVALID, "qsize");
557 if (strcmp(tokens[13], "fo") != 0) {
558 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
562 if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) {
563 snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
567 if (strcmp(tokens[15], "mtu") != 0) {
568 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
572 if (parser_read_uint32(&p.mtu, tokens[16]) != 0) {
573 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
577 if (strcmp(tokens[17], "cpu") != 0) {
578 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
582 if (parser_read_uint32(&p.cpu_id, tokens[18]) != 0) {
583 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
587 tmgr_port = tmgr_port_create(name, &p);
588 if (tmgr_port == NULL) {
589 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
594 static const char cmd_tmgr_subport_help[] =
595 "tmgr <tmgr_name> subport <subport_id>\n"
596 " profile <subport_profile_id>\n";
599 cmd_tmgr_subport(char **tokens,
604 uint32_t subport_id, subport_profile_id;
609 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
615 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
616 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
620 if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
621 snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
625 status = tmgr_subport_config(name, subport_id, subport_profile_id);
627 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
633 static const char cmd_tmgr_subport_pipe_help[] =
634 "tmgr <tmgr_name> subport <subport_id> pipe\n"
635 " from <pipe_id_first> to <pipe_id_last>\n"
636 " profile <pipe_profile_id>\n";
639 cmd_tmgr_subport_pipe(char **tokens,
644 uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
648 if (n_tokens != 11) {
649 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
655 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
656 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
660 if (strcmp(tokens[4], "pipe") != 0) {
661 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
665 if (strcmp(tokens[5], "from") != 0) {
666 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
670 if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
671 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
675 if (strcmp(tokens[7], "to") != 0) {
676 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
680 if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
681 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
685 if (strcmp(tokens[9], "profile") != 0) {
686 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
690 if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
691 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
695 status = tmgr_pipe_config(name, subport_id, pipe_id_first,
696 pipe_id_last, pipe_profile_id);
698 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
704 static const char cmd_tap_help[] =
708 cmd_tap(char **tokens,
717 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
723 tap = tap_create(name);
725 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
730 static const char cmd_kni_help[] =
732 " link <link_name>\n"
733 " mempool <mempool_name>\n"
734 " [thread <thread_id>]\n";
737 cmd_kni(char **tokens,
746 memset(&p, 0, sizeof(p));
747 if ((n_tokens != 6) && (n_tokens != 8)) {
748 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
754 if (strcmp(tokens[2], "link") != 0) {
755 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link");
759 p.link_name = tokens[3];
761 if (strcmp(tokens[4], "mempool") != 0) {
762 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool");
766 p.mempool_name = tokens[5];
769 if (strcmp(tokens[6], "thread") != 0) {
770 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread");
774 if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) {
775 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
783 kni = kni_create(name, &p);
785 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
790 static const char cmd_cryptodev_help[] =
791 "cryptodev <cryptodev_name>\n"
792 " dev <device_name> | dev_id <device_id>\n"
793 " queue <n_queues> <queue_size>\n"
794 " max_sessions <n_sessions>";
797 cmd_cryptodev(char **tokens,
802 struct cryptodev_params params;
805 memset(¶ms, 0, sizeof(params));
807 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
813 if (strcmp(tokens[2], "dev") == 0)
814 params.dev_name = tokens[3];
815 else if (strcmp(tokens[2], "dev_id") == 0) {
816 if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
817 snprintf(out, out_size, MSG_ARG_INVALID,
822 snprintf(out, out_size, MSG_ARG_INVALID,
827 if (strcmp(tokens[4], "queue")) {
828 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
833 if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
834 snprintf(out, out_size, MSG_ARG_INVALID,
839 if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
840 snprintf(out, out_size, MSG_ARG_INVALID,
845 if (strcmp(tokens[7], "max_sessions")) {
846 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
851 if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
852 snprintf(out, out_size, MSG_ARG_INVALID,
857 if (cryptodev_create(name, ¶ms) == NULL) {
858 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
863 static const char cmd_port_in_action_profile_help[] =
864 "port in action profile <profile_name>\n"
865 " [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
866 " [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
869 cmd_port_in_action_profile(char **tokens,
874 struct port_in_action_profile_params p;
875 struct port_in_action_profile *ap;
879 memset(&p, 0, sizeof(p));
882 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
886 if (strcmp(tokens[1], "in") != 0) {
887 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
891 if (strcmp(tokens[2], "action") != 0) {
892 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
896 if (strcmp(tokens[3], "profile") != 0) {
897 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
905 if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
908 if (n_tokens < t0 + 10) {
909 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
913 if (strcmp(tokens[t0 + 1], "match") == 0)
914 p.fltr.filter_on_match = 1;
915 else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
916 p.fltr.filter_on_match = 0;
918 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
922 if (strcmp(tokens[t0 + 2], "offset") != 0) {
923 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
927 if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
928 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
932 if (strcmp(tokens[t0 + 4], "mask") != 0) {
933 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
937 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
938 if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
939 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
940 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
944 if (strcmp(tokens[t0 + 6], "key") != 0) {
945 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
949 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
950 if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
951 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
952 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
956 if (strcmp(tokens[t0 + 8], "port") != 0) {
957 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
961 if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
962 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
966 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
970 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
973 if (n_tokens < t0 + 22) {
974 snprintf(out, out_size, MSG_ARG_MISMATCH,
975 "port in action profile balance");
979 if (strcmp(tokens[t0 + 1], "offset") != 0) {
980 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
984 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
985 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
989 if (strcmp(tokens[t0 + 3], "mask") != 0) {
990 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
994 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
995 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
996 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1000 if (strcmp(tokens[t0 + 5], "port") != 0) {
1001 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1005 for (i = 0; i < 16; i++)
1006 if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
1007 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1011 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
1015 if (t0 < n_tokens) {
1016 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1020 ap = port_in_action_profile_create(name, &p);
1022 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1028 static const char cmd_table_action_profile_help[] =
1029 "table action profile <profile_name>\n"
1031 " offset <ip_offset>\n"
1033 " [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
1034 " [meter srtcm | trtcm\n"
1036 " stats none | pkts | bytes | both]\n"
1037 " [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
1038 " [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
1039 " vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
1041 " proto udp | tcp]\n"
1042 " [ttl drop | fwd\n"
1043 " stats none | pkts]\n"
1044 " [stats pkts | bytes | both]\n"
1046 " [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
1051 cmd_table_action_profile(char **tokens,
1056 struct table_action_profile_params p;
1057 struct table_action_profile *ap;
1061 memset(&p, 0, sizeof(p));
1064 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1068 if (strcmp(tokens[1], "action") != 0) {
1069 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1073 if (strcmp(tokens[2], "profile") != 0) {
1074 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1080 if (strcmp(tokens[4], "ipv4") == 0)
1081 p.common.ip_version = 1;
1082 else if (strcmp(tokens[4], "ipv6") == 0)
1083 p.common.ip_version = 0;
1085 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1089 if (strcmp(tokens[5], "offset") != 0) {
1090 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1094 if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
1095 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1099 if (strcmp(tokens[7], "fwd") != 0) {
1100 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1104 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1107 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
1108 if (n_tokens < t0 + 7) {
1109 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1113 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1114 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1118 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
1119 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1123 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1124 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1128 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1129 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1130 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1134 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1135 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1139 if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
1140 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1144 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1148 if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
1149 if (n_tokens < t0 + 6) {
1150 snprintf(out, out_size, MSG_ARG_MISMATCH,
1151 "table action profile meter");
1155 if (strcmp(tokens[t0 + 1], "srtcm") == 0)
1156 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1157 else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
1158 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1160 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1165 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1166 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1170 if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
1171 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1175 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1176 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1180 if (strcmp(tokens[t0 + 5], "none") == 0) {
1181 p.mtr.n_packets_enabled = 0;
1182 p.mtr.n_bytes_enabled = 0;
1183 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1184 p.mtr.n_packets_enabled = 1;
1185 p.mtr.n_bytes_enabled = 0;
1186 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1187 p.mtr.n_packets_enabled = 0;
1188 p.mtr.n_bytes_enabled = 1;
1189 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1190 p.mtr.n_packets_enabled = 1;
1191 p.mtr.n_bytes_enabled = 1;
1193 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1194 "none or pkts or bytes or both");
1198 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1202 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
1203 if (n_tokens < t0 + 5) {
1204 snprintf(out, out_size, MSG_ARG_MISMATCH,
1205 "table action profile tm");
1209 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1210 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1214 if (parser_read_uint32(&p.tm.n_subports_per_port,
1215 tokens[t0 + 2]) != 0) {
1216 snprintf(out, out_size, MSG_ARG_INVALID,
1217 "n_subports_per_port");
1221 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1222 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1226 if (parser_read_uint32(&p.tm.n_pipes_per_subport,
1227 tokens[t0 + 4]) != 0) {
1228 snprintf(out, out_size, MSG_ARG_INVALID,
1229 "n_pipes_per_subport");
1233 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1237 if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
1238 uint32_t n_extra_tokens = 0;
1240 if (n_tokens < t0 + 2) {
1241 snprintf(out, out_size, MSG_ARG_MISMATCH,
1242 "action profile encap");
1246 if (strcmp(tokens[t0 + 1], "ether") == 0)
1247 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1248 else if (strcmp(tokens[t0 + 1], "vlan") == 0)
1249 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1250 else if (strcmp(tokens[t0 + 1], "qinq") == 0)
1251 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1252 else if (strcmp(tokens[t0 + 1], "mpls") == 0)
1253 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1254 else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
1255 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1256 else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
1257 if (n_tokens < t0 + 2 + 5) {
1258 snprintf(out, out_size, MSG_ARG_MISMATCH,
1259 "action profile encap vxlan");
1263 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1264 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1269 if (parser_read_uint32(&p.encap.vxlan.data_offset,
1270 tokens[t0 + 2 + 1]) != 0) {
1271 snprintf(out, out_size, MSG_ARG_INVALID,
1272 "vxlan: ether_offset");
1276 if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
1277 p.encap.vxlan.ip_version = 1;
1278 else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
1279 p.encap.vxlan.ip_version = 0;
1281 snprintf(out, out_size, MSG_ARG_INVALID,
1282 "vxlan: ipv4 or ipv6");
1286 if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
1287 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1292 if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
1293 p.encap.vxlan.vlan = 1;
1294 else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
1295 p.encap.vxlan.vlan = 0;
1297 snprintf(out, out_size, MSG_ARG_INVALID,
1298 "vxlan: on or off");
1302 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
1304 } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
1305 p.encap.encap_mask =
1306 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
1308 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1312 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1313 t0 += 2 + n_extra_tokens;
1316 if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
1317 if (n_tokens < t0 + 4) {
1318 snprintf(out, out_size, MSG_ARG_MISMATCH,
1319 "table action profile nat");
1323 if (strcmp(tokens[t0 + 1], "src") == 0)
1324 p.nat.source_nat = 1;
1325 else if (strcmp(tokens[t0 + 1], "dst") == 0)
1326 p.nat.source_nat = 0;
1328 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1333 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1334 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1338 if (strcmp(tokens[t0 + 3], "tcp") == 0)
1340 else if (strcmp(tokens[t0 + 3], "udp") == 0)
1343 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1348 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1352 if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
1353 if (n_tokens < t0 + 4) {
1354 snprintf(out, out_size, MSG_ARG_MISMATCH,
1355 "table action profile ttl");
1359 if (strcmp(tokens[t0 + 1], "drop") == 0)
1361 else if (strcmp(tokens[t0 + 1], "fwd") == 0)
1364 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1369 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1370 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1374 if (strcmp(tokens[t0 + 3], "none") == 0)
1375 p.ttl.n_packets_enabled = 0;
1376 else if (strcmp(tokens[t0 + 3], "pkts") == 0)
1377 p.ttl.n_packets_enabled = 1;
1379 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1384 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1388 if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
1389 if (n_tokens < t0 + 2) {
1390 snprintf(out, out_size, MSG_ARG_MISMATCH,
1391 "table action profile stats");
1395 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1396 p.stats.n_packets_enabled = 1;
1397 p.stats.n_bytes_enabled = 0;
1398 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1399 p.stats.n_packets_enabled = 0;
1400 p.stats.n_bytes_enabled = 1;
1401 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1402 p.stats.n_packets_enabled = 1;
1403 p.stats.n_bytes_enabled = 1;
1405 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1406 "pkts or bytes or both");
1410 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1414 if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
1415 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1419 if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
1420 struct cryptodev *cryptodev;
1422 if (n_tokens < t0 + 5 ||
1423 strcmp(tokens[t0 + 1], "dev") ||
1424 strcmp(tokens[t0 + 3], "offset")) {
1425 snprintf(out, out_size, MSG_ARG_MISMATCH,
1426 "table action profile sym_crypto");
1430 cryptodev = cryptodev_find(tokens[t0 + 2]);
1431 if (cryptodev == NULL) {
1432 snprintf(out, out_size, MSG_ARG_INVALID,
1433 "table action profile sym_crypto");
1437 p.sym_crypto.cryptodev_id = cryptodev->dev_id;
1439 if (parser_read_uint32(&p.sym_crypto.op_offset,
1440 tokens[t0 + 4]) != 0) {
1441 snprintf(out, out_size, MSG_ARG_INVALID,
1442 "table action profile sym_crypto");
1446 p.sym_crypto.mp_create = cryptodev->mp_create;
1447 p.sym_crypto.mp_init = cryptodev->mp_init;
1449 p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
1454 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
1455 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1459 if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
1460 p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
1464 if (t0 < n_tokens) {
1465 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1469 ap = table_action_profile_create(name, &p);
1471 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1476 static const char cmd_pipeline_help[] =
1477 "pipeline <pipeline_name>\n"
1478 " period <timer_period_ms>\n"
1479 " offset_port_id <offset_port_id>\n"
1483 cmd_pipeline(char **tokens,
1488 struct pipeline_params p;
1490 struct pipeline *pipeline;
1492 if (n_tokens != 8) {
1493 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1499 if (strcmp(tokens[2], "period") != 0) {
1500 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1504 if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
1505 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1509 if (strcmp(tokens[4], "offset_port_id") != 0) {
1510 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1514 if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
1515 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1519 if (strcmp(tokens[6], "cpu") != 0) {
1520 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
1524 if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
1525 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
1529 pipeline = pipeline_create(name, &p);
1530 if (pipeline == NULL) {
1531 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1536 static const char cmd_pipeline_port_in_help[] =
1537 "pipeline <pipeline_name> port in\n"
1538 " bsz <burst_size>\n"
1539 " link <link_name> rxq <queue_id>\n"
1540 " | swq <swq_name>\n"
1541 " | tmgr <tmgr_name>\n"
1542 " | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
1543 " | kni <kni_name>\n"
1544 " | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
1545 " | cryptodev <cryptodev_name> rxq <queue_id>\n"
1546 " [action <port_in_action_profile_name>]\n"
1550 cmd_pipeline_port_in(char **tokens,
1555 struct port_in_params p;
1556 char *pipeline_name;
1558 int enabled, status;
1561 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1565 pipeline_name = tokens[1];
1567 if (strcmp(tokens[2], "port") != 0) {
1568 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1572 if (strcmp(tokens[3], "in") != 0) {
1573 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1577 if (strcmp(tokens[4], "bsz") != 0) {
1578 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1582 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1583 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1589 if (strcmp(tokens[t0], "link") == 0) {
1590 if (n_tokens < t0 + 4) {
1591 snprintf(out, out_size, MSG_ARG_MISMATCH,
1592 "pipeline port in link");
1596 p.type = PORT_IN_RXQ;
1598 p.dev_name = tokens[t0 + 1];
1600 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1601 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1605 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1606 snprintf(out, out_size, MSG_ARG_INVALID,
1611 } else if (strcmp(tokens[t0], "swq") == 0) {
1612 if (n_tokens < t0 + 2) {
1613 snprintf(out, out_size, MSG_ARG_MISMATCH,
1614 "pipeline port in swq");
1618 p.type = PORT_IN_SWQ;
1620 p.dev_name = tokens[t0 + 1];
1623 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1624 if (n_tokens < t0 + 2) {
1625 snprintf(out, out_size, MSG_ARG_MISMATCH,
1626 "pipeline port in tmgr");
1630 p.type = PORT_IN_TMGR;
1632 p.dev_name = tokens[t0 + 1];
1635 } else if (strcmp(tokens[t0], "tap") == 0) {
1636 if (n_tokens < t0 + 6) {
1637 snprintf(out, out_size, MSG_ARG_MISMATCH,
1638 "pipeline port in tap");
1642 p.type = PORT_IN_TAP;
1644 p.dev_name = tokens[t0 + 1];
1646 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1647 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1652 p.tap.mempool_name = tokens[t0 + 3];
1654 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1655 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1660 if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
1661 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1666 } else if (strcmp(tokens[t0], "kni") == 0) {
1667 if (n_tokens < t0 + 2) {
1668 snprintf(out, out_size, MSG_ARG_MISMATCH,
1669 "pipeline port in kni");
1673 p.type = PORT_IN_KNI;
1675 p.dev_name = tokens[t0 + 1];
1678 } else if (strcmp(tokens[t0], "source") == 0) {
1679 if (n_tokens < t0 + 6) {
1680 snprintf(out, out_size, MSG_ARG_MISMATCH,
1681 "pipeline port in source");
1685 p.type = PORT_IN_SOURCE;
1689 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1690 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1695 p.source.mempool_name = tokens[t0 + 2];
1697 if (strcmp(tokens[t0 + 3], "file") != 0) {
1698 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1703 p.source.file_name = tokens[t0 + 4];
1705 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1706 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1711 if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
1712 snprintf(out, out_size, MSG_ARG_INVALID,
1718 } else if (strcmp(tokens[t0], "cryptodev") == 0) {
1719 if (n_tokens < t0 + 3) {
1720 snprintf(out, out_size, MSG_ARG_MISMATCH,
1721 "pipeline port in cryptodev");
1725 p.type = PORT_IN_CRYPTODEV;
1727 p.dev_name = tokens[t0 + 1];
1728 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1729 snprintf(out, out_size, MSG_ARG_INVALID,
1734 p.cryptodev.arg_callback = NULL;
1735 p.cryptodev.f_callback = NULL;
1739 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1743 p.action_profile_name = NULL;
1744 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
1745 if (n_tokens < t0 + 2) {
1746 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1750 p.action_profile_name = tokens[t0 + 1];
1756 if ((n_tokens > t0) &&
1757 (strcmp(tokens[t0], "disabled") == 0)) {
1763 if (n_tokens != t0) {
1764 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1768 status = pipeline_port_in_create(pipeline_name,
1771 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1776 static const char cmd_pipeline_port_out_help[] =
1777 "pipeline <pipeline_name> port out\n"
1778 " bsz <burst_size>\n"
1779 " link <link_name> txq <txq_id>\n"
1780 " | swq <swq_name>\n"
1781 " | tmgr <tmgr_name>\n"
1782 " | tap <tap_name>\n"
1783 " | kni <kni_name>\n"
1784 " | sink [file <file_name> pkts <max_n_pkts>]\n"
1785 " | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
1788 cmd_pipeline_port_out(char **tokens,
1793 struct port_out_params p;
1794 char *pipeline_name;
1797 memset(&p, 0, sizeof(p));
1800 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1804 pipeline_name = tokens[1];
1806 if (strcmp(tokens[2], "port") != 0) {
1807 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1811 if (strcmp(tokens[3], "out") != 0) {
1812 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1816 if (strcmp(tokens[4], "bsz") != 0) {
1817 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1821 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1822 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1826 if (strcmp(tokens[6], "link") == 0) {
1827 if (n_tokens != 10) {
1828 snprintf(out, out_size, MSG_ARG_MISMATCH,
1829 "pipeline port out link");
1833 p.type = PORT_OUT_TXQ;
1835 p.dev_name = tokens[7];
1837 if (strcmp(tokens[8], "txq") != 0) {
1838 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1842 if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
1843 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1846 } else if (strcmp(tokens[6], "swq") == 0) {
1847 if (n_tokens != 8) {
1848 snprintf(out, out_size, MSG_ARG_MISMATCH,
1849 "pipeline port out swq");
1853 p.type = PORT_OUT_SWQ;
1855 p.dev_name = tokens[7];
1856 } else if (strcmp(tokens[6], "tmgr") == 0) {
1857 if (n_tokens != 8) {
1858 snprintf(out, out_size, MSG_ARG_MISMATCH,
1859 "pipeline port out tmgr");
1863 p.type = PORT_OUT_TMGR;
1865 p.dev_name = tokens[7];
1866 } else if (strcmp(tokens[6], "tap") == 0) {
1867 if (n_tokens != 8) {
1868 snprintf(out, out_size, MSG_ARG_MISMATCH,
1869 "pipeline port out tap");
1873 p.type = PORT_OUT_TAP;
1875 p.dev_name = tokens[7];
1876 } else if (strcmp(tokens[6], "kni") == 0) {
1877 if (n_tokens != 8) {
1878 snprintf(out, out_size, MSG_ARG_MISMATCH,
1879 "pipeline port out kni");
1883 p.type = PORT_OUT_KNI;
1885 p.dev_name = tokens[7];
1886 } else if (strcmp(tokens[6], "sink") == 0) {
1887 if ((n_tokens != 7) && (n_tokens != 11)) {
1888 snprintf(out, out_size, MSG_ARG_MISMATCH,
1889 "pipeline port out sink");
1893 p.type = PORT_OUT_SINK;
1897 if (n_tokens == 7) {
1898 p.sink.file_name = NULL;
1899 p.sink.max_n_pkts = 0;
1901 if (strcmp(tokens[7], "file") != 0) {
1902 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1907 p.sink.file_name = tokens[8];
1909 if (strcmp(tokens[9], "pkts") != 0) {
1910 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1914 if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
1915 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1920 } else if (strcmp(tokens[6], "cryptodev") == 0) {
1921 if (n_tokens != 12) {
1922 snprintf(out, out_size, MSG_ARG_MISMATCH,
1923 "pipeline port out cryptodev");
1927 p.type = PORT_OUT_CRYPTODEV;
1929 p.dev_name = tokens[7];
1931 if (strcmp(tokens[8], "txq")) {
1932 snprintf(out, out_size, MSG_ARG_MISMATCH,
1933 "pipeline port out cryptodev");
1937 if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
1939 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1943 if (strcmp(tokens[10], "offset")) {
1944 snprintf(out, out_size, MSG_ARG_MISMATCH,
1945 "pipeline port out cryptodev");
1949 if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
1951 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1955 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1959 status = pipeline_port_out_create(pipeline_name, &p);
1961 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1966 static const char cmd_pipeline_table_help[] =
1967 "pipeline <pipeline_name> table\n"
1971 " offset <ip_header_offset>\n"
1974 " offset <key_offset>\n"
1979 " mask <key_mask>\n"
1980 " offset <key_offset>\n"
1981 " buckets <n_buckets>\n"
1985 " offset <ip_header_offset>\n"
1988 " [action <table_action_profile_name>]\n";
1991 cmd_pipeline_table(char **tokens,
1996 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1997 struct table_params p;
1998 char *pipeline_name;
2003 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2007 pipeline_name = tokens[1];
2009 if (strcmp(tokens[2], "table") != 0) {
2010 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2014 if (strcmp(tokens[3], "match") != 0) {
2015 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2020 if (strcmp(tokens[t0], "acl") == 0) {
2021 if (n_tokens < t0 + 6) {
2022 snprintf(out, out_size, MSG_ARG_MISMATCH,
2023 "pipeline table acl");
2027 p.match_type = TABLE_ACL;
2029 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2030 p.match.acl.ip_version = 1;
2031 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2032 p.match.acl.ip_version = 0;
2034 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2039 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2040 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2044 if (parser_read_uint32(&p.match.acl.ip_header_offset,
2045 tokens[t0 + 3]) != 0) {
2046 snprintf(out, out_size, MSG_ARG_INVALID,
2047 "ip_header_offset");
2051 if (strcmp(tokens[t0 + 4], "size") != 0) {
2052 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2056 if (parser_read_uint32(&p.match.acl.n_rules,
2057 tokens[t0 + 5]) != 0) {
2058 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2063 } else if (strcmp(tokens[t0], "array") == 0) {
2064 if (n_tokens < t0 + 5) {
2065 snprintf(out, out_size, MSG_ARG_MISMATCH,
2066 "pipeline table array");
2070 p.match_type = TABLE_ARRAY;
2072 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2073 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2077 if (parser_read_uint32(&p.match.array.key_offset,
2078 tokens[t0 + 2]) != 0) {
2079 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2083 if (strcmp(tokens[t0 + 3], "size") != 0) {
2084 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2088 if (parser_read_uint32(&p.match.array.n_keys,
2089 tokens[t0 + 4]) != 0) {
2090 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2095 } else if (strcmp(tokens[t0], "hash") == 0) {
2096 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2098 if (n_tokens < t0 + 12) {
2099 snprintf(out, out_size, MSG_ARG_MISMATCH,
2100 "pipeline table hash");
2104 p.match_type = TABLE_HASH;
2106 if (strcmp(tokens[t0 + 1], "ext") == 0)
2107 p.match.hash.extendable_bucket = 1;
2108 else if (strcmp(tokens[t0 + 1], "lru") == 0)
2109 p.match.hash.extendable_bucket = 0;
2111 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2116 if (strcmp(tokens[t0 + 2], "key") != 0) {
2117 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2121 if ((parser_read_uint32(&p.match.hash.key_size,
2122 tokens[t0 + 3]) != 0) ||
2123 (p.match.hash.key_size == 0) ||
2124 (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
2125 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2129 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2130 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2134 if ((parse_hex_string(tokens[t0 + 5],
2135 key_mask, &key_mask_size) != 0) ||
2136 (key_mask_size != p.match.hash.key_size)) {
2137 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2140 p.match.hash.key_mask = key_mask;
2142 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2143 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2147 if (parser_read_uint32(&p.match.hash.key_offset,
2148 tokens[t0 + 7]) != 0) {
2149 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2153 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2154 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2158 if (parser_read_uint32(&p.match.hash.n_buckets,
2159 tokens[t0 + 9]) != 0) {
2160 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2164 if (strcmp(tokens[t0 + 10], "size") != 0) {
2165 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2169 if (parser_read_uint32(&p.match.hash.n_keys,
2170 tokens[t0 + 11]) != 0) {
2171 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2176 } else if (strcmp(tokens[t0], "lpm") == 0) {
2177 if (n_tokens < t0 + 6) {
2178 snprintf(out, out_size, MSG_ARG_MISMATCH,
2179 "pipeline table lpm");
2183 p.match_type = TABLE_LPM;
2185 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2186 p.match.lpm.key_size = 4;
2187 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2188 p.match.lpm.key_size = 16;
2190 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2195 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2196 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2200 if (parser_read_uint32(&p.match.lpm.key_offset,
2201 tokens[t0 + 3]) != 0) {
2202 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2206 if (strcmp(tokens[t0 + 4], "size") != 0) {
2207 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2211 if (parser_read_uint32(&p.match.lpm.n_rules,
2212 tokens[t0 + 5]) != 0) {
2213 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2218 } else if (strcmp(tokens[t0], "stub") == 0) {
2219 p.match_type = TABLE_STUB;
2223 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2227 p.action_profile_name = NULL;
2228 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
2229 if (n_tokens < t0 + 2) {
2230 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2234 p.action_profile_name = tokens[t0 + 1];
2239 if (n_tokens > t0) {
2240 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2244 status = pipeline_table_create(pipeline_name, &p);
2246 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2251 static const char cmd_pipeline_port_in_table_help[] =
2252 "pipeline <pipeline_name> port in <port_id> table <table_id>\n";
2255 cmd_pipeline_port_in_table(char **tokens,
2260 char *pipeline_name;
2261 uint32_t port_id, table_id;
2264 if (n_tokens != 7) {
2265 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2269 pipeline_name = tokens[1];
2271 if (strcmp(tokens[2], "port") != 0) {
2272 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2276 if (strcmp(tokens[3], "in") != 0) {
2277 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2281 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2282 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2286 if (strcmp(tokens[5], "table") != 0) {
2287 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2291 if (parser_read_uint32(&table_id, tokens[6]) != 0) {
2292 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2296 status = pipeline_port_in_connect_to_table(pipeline_name,
2300 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2306 static const char cmd_pipeline_port_in_stats_help[] =
2307 "pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
2309 #define MSG_PIPELINE_PORT_IN_STATS \
2310 "Pkts in: %" PRIu64 "\n" \
2311 "Pkts dropped by AH: %" PRIu64 "\n" \
2312 "Pkts dropped by other: %" PRIu64 "\n"
2315 cmd_pipeline_port_in_stats(char **tokens,
2320 struct rte_pipeline_port_in_stats stats;
2321 char *pipeline_name;
2325 if ((n_tokens != 7) && (n_tokens != 8)) {
2326 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2330 pipeline_name = tokens[1];
2332 if (strcmp(tokens[2], "port") != 0) {
2333 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2337 if (strcmp(tokens[3], "in") != 0) {
2338 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2342 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2343 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2347 if (strcmp(tokens[5], "stats") != 0) {
2348 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2352 if (strcmp(tokens[6], "read") != 0) {
2353 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2358 if (n_tokens == 8) {
2359 if (strcmp(tokens[7], "clear") != 0) {
2360 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2367 status = pipeline_port_in_stats_read(pipeline_name,
2372 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2376 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2377 stats.stats.n_pkts_in,
2378 stats.n_pkts_dropped_by_ah,
2379 stats.stats.n_pkts_drop);
2383 static const char cmd_pipeline_port_in_enable_help[] =
2384 "pipeline <pipeline_name> port in <port_id> enable\n";
2387 cmd_pipeline_port_in_enable(char **tokens,
2392 char *pipeline_name;
2396 if (n_tokens != 6) {
2397 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2401 pipeline_name = tokens[1];
2403 if (strcmp(tokens[2], "port") != 0) {
2404 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2408 if (strcmp(tokens[3], "in") != 0) {
2409 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2413 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2414 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2418 if (strcmp(tokens[5], "enable") != 0) {
2419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2423 status = pipeline_port_in_enable(pipeline_name, port_id);
2425 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2431 static const char cmd_pipeline_port_in_disable_help[] =
2432 "pipeline <pipeline_name> port in <port_id> disable\n";
2435 cmd_pipeline_port_in_disable(char **tokens,
2440 char *pipeline_name;
2444 if (n_tokens != 6) {
2445 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2449 pipeline_name = tokens[1];
2451 if (strcmp(tokens[2], "port") != 0) {
2452 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2456 if (strcmp(tokens[3], "in") != 0) {
2457 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2461 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2462 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2466 if (strcmp(tokens[5], "disable") != 0) {
2467 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2471 status = pipeline_port_in_disable(pipeline_name, port_id);
2473 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2479 static const char cmd_pipeline_port_out_stats_help[] =
2480 "pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
2482 #define MSG_PIPELINE_PORT_OUT_STATS \
2483 "Pkts in: %" PRIu64 "\n" \
2484 "Pkts dropped by AH: %" PRIu64 "\n" \
2485 "Pkts dropped by other: %" PRIu64 "\n"
2488 cmd_pipeline_port_out_stats(char **tokens,
2493 struct rte_pipeline_port_out_stats stats;
2494 char *pipeline_name;
2498 if ((n_tokens != 7) && (n_tokens != 8)) {
2499 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2503 pipeline_name = tokens[1];
2505 if (strcmp(tokens[2], "port") != 0) {
2506 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2510 if (strcmp(tokens[3], "out") != 0) {
2511 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2515 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2516 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2520 if (strcmp(tokens[5], "stats") != 0) {
2521 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2525 if (strcmp(tokens[6], "read") != 0) {
2526 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2531 if (n_tokens == 8) {
2532 if (strcmp(tokens[7], "clear") != 0) {
2533 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2540 status = pipeline_port_out_stats_read(pipeline_name,
2545 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2549 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2550 stats.stats.n_pkts_in,
2551 stats.n_pkts_dropped_by_ah,
2552 stats.stats.n_pkts_drop);
2556 static const char cmd_pipeline_table_stats_help[] =
2557 "pipeline <pipeline_name> table <table_id> stats read [clear]\n";
2559 #define MSG_PIPELINE_TABLE_STATS \
2560 "Pkts in: %" PRIu64 "\n" \
2561 "Pkts in with lookup miss: %" PRIu64 "\n" \
2562 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2563 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2564 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2565 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2568 cmd_pipeline_table_stats(char **tokens,
2573 struct rte_pipeline_table_stats stats;
2574 char *pipeline_name;
2578 if ((n_tokens != 6) && (n_tokens != 7)) {
2579 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2583 pipeline_name = tokens[1];
2585 if (strcmp(tokens[2], "table") != 0) {
2586 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2590 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
2591 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2595 if (strcmp(tokens[4], "stats") != 0) {
2596 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2600 if (strcmp(tokens[5], "read") != 0) {
2601 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2606 if (n_tokens == 7) {
2607 if (strcmp(tokens[6], "clear") != 0) {
2608 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2615 status = pipeline_table_stats_read(pipeline_name,
2620 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2624 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2625 stats.stats.n_pkts_in,
2626 stats.stats.n_pkts_lookup_miss,
2627 stats.n_pkts_dropped_by_lkp_hit_ah,
2628 stats.n_pkts_dropped_lkp_hit,
2629 stats.n_pkts_dropped_by_lkp_miss_ah,
2630 stats.n_pkts_dropped_lkp_miss);
2638 * priority <priority>
2639 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2640 * <sp0> <sp1> <dp0> <dp1> <proto>
2644 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2645 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2646 * | ipv4_addr <addr>
2647 * | ipv6_addr <addr>
2648 * | qinq <svlan> <cvlan>
2650 * ipv4 | ipv6 <addr> <depth>
2652 struct pkt_key_qinq {
2653 uint16_t ethertype_svlan;
2655 uint16_t ethertype_cvlan;
2657 } __attribute__((__packed__));
2659 struct pkt_key_ipv4_5tuple {
2660 uint8_t time_to_live;
2662 uint16_t hdr_checksum;
2667 } __attribute__((__packed__));
2669 struct pkt_key_ipv6_5tuple {
2670 uint16_t payload_length;
2677 } __attribute__((__packed__));
2679 struct pkt_key_ipv4_addr {
2681 } __attribute__((__packed__));
2683 struct pkt_key_ipv6_addr {
2685 } __attribute__((__packed__));
2688 parse_match(char **tokens,
2692 struct table_rule_match *m)
2694 memset(m, 0, sizeof(*m));
2699 if (strcmp(tokens[0], "match") != 0) {
2700 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2704 if (strcmp(tokens[1], "acl") == 0) {
2705 if (n_tokens < 14) {
2706 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2710 m->match_type = TABLE_ACL;
2712 if (strcmp(tokens[2], "priority") != 0) {
2713 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2717 if (parser_read_uint32(&m->match.acl.priority,
2719 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2723 if (strcmp(tokens[4], "ipv4") == 0) {
2724 struct in_addr saddr, daddr;
2726 m->match.acl.ip_version = 1;
2728 if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
2729 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2732 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2734 if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
2735 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2738 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2739 } else if (strcmp(tokens[4], "ipv6") == 0) {
2740 struct in6_addr saddr, daddr;
2742 m->match.acl.ip_version = 0;
2744 if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
2745 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2748 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2750 if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
2751 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2754 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2756 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2761 if (parser_read_uint32(&m->match.acl.sa_depth,
2763 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2767 if (parser_read_uint32(&m->match.acl.da_depth,
2769 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2773 if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2774 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2778 if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2779 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2783 if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2784 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2788 if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2789 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2793 if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2794 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2798 m->match.acl.proto_mask = 0xff;
2803 if (strcmp(tokens[1], "array") == 0) {
2805 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2809 m->match_type = TABLE_ARRAY;
2811 if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2812 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2819 if (strcmp(tokens[1], "hash") == 0) {
2821 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2825 m->match_type = TABLE_HASH;
2827 if (strcmp(tokens[2], "raw") == 0) {
2828 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2831 snprintf(out, out_size, MSG_ARG_MISMATCH,
2836 if (parse_hex_string(tokens[3],
2837 m->match.hash.key, &key_size) != 0) {
2838 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2845 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2846 struct pkt_key_ipv4_5tuple *ipv4 =
2847 (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
2848 struct in_addr saddr, daddr;
2853 snprintf(out, out_size, MSG_ARG_MISMATCH,
2858 if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
2859 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2863 if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
2864 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2868 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2869 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2873 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2874 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2878 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2879 snprintf(out, out_size, MSG_ARG_INVALID,
2884 ipv4->sa = saddr.s_addr;
2885 ipv4->da = daddr.s_addr;
2886 ipv4->sp = rte_cpu_to_be_16(sp);
2887 ipv4->dp = rte_cpu_to_be_16(dp);
2888 ipv4->proto = proto;
2891 } /* hash ipv4_5tuple */
2893 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2894 struct pkt_key_ipv6_5tuple *ipv6 =
2895 (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
2896 struct in6_addr saddr, daddr;
2901 snprintf(out, out_size, MSG_ARG_MISMATCH,
2906 if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
2907 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2911 if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
2912 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2916 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2917 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2921 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2922 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2926 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2927 snprintf(out, out_size, MSG_ARG_INVALID,
2932 memcpy(ipv6->sa, saddr.s6_addr, 16);
2933 memcpy(ipv6->da, daddr.s6_addr, 16);
2934 ipv6->sp = rte_cpu_to_be_16(sp);
2935 ipv6->dp = rte_cpu_to_be_16(dp);
2936 ipv6->proto = proto;
2939 } /* hash ipv6_5tuple */
2941 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2942 struct pkt_key_ipv4_addr *ipv4_addr =
2943 (struct pkt_key_ipv4_addr *) m->match.hash.key;
2944 struct in_addr addr;
2947 snprintf(out, out_size, MSG_ARG_MISMATCH,
2952 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
2953 snprintf(out, out_size, MSG_ARG_INVALID,
2958 ipv4_addr->addr = addr.s_addr;
2961 } /* hash ipv4_addr */
2963 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2964 struct pkt_key_ipv6_addr *ipv6_addr =
2965 (struct pkt_key_ipv6_addr *) m->match.hash.key;
2966 struct in6_addr addr;
2969 snprintf(out, out_size, MSG_ARG_MISMATCH,
2974 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
2975 snprintf(out, out_size, MSG_ARG_INVALID,
2980 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2983 } /* hash ipv6_5tuple */
2985 if (strcmp(tokens[2], "qinq") == 0) {
2986 struct pkt_key_qinq *qinq =
2987 (struct pkt_key_qinq *) m->match.hash.key;
2988 uint16_t svlan, cvlan;
2991 snprintf(out, out_size, MSG_ARG_MISMATCH,
2996 if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
2998 snprintf(out, out_size, MSG_ARG_INVALID,
3003 if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3005 snprintf(out, out_size, MSG_ARG_INVALID,
3010 qinq->svlan = rte_cpu_to_be_16(svlan);
3011 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3016 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3020 if (strcmp(tokens[1], "lpm") == 0) {
3022 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3026 m->match_type = TABLE_LPM;
3028 if (strcmp(tokens[2], "ipv4") == 0) {
3029 struct in_addr addr;
3031 m->match.lpm.ip_version = 1;
3033 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
3034 snprintf(out, out_size, MSG_ARG_INVALID,
3039 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3040 } else if (strcmp(tokens[2], "ipv6") == 0) {
3041 struct in6_addr addr;
3043 m->match.lpm.ip_version = 0;
3045 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
3046 snprintf(out, out_size, MSG_ARG_INVALID,
3051 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3053 snprintf(out, out_size, MSG_ARG_MISMATCH,
3058 if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3059 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3066 snprintf(out, out_size, MSG_ARG_MISMATCH,
3067 "acl or array or hash or lpm");
3079 * | table <table_id>
3080 * [balance <out0> ... <out7>]
3082 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3083 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3084 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3085 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3086 * [tm subport <subport_id> pipe <pipe_id>]
3089 * | vlan <da> <sa> <pcp> <dei> <vid>
3090 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3091 * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
3092 * | mpls unicast | multicast
3094 * label0 <label> <tc> <ttl>
3095 * [label1 <label> <tc> <ttl>
3096 * [label2 <label> <tc> <ttl>
3097 * [label3 <label> <tc> <ttl>]]]
3098 * | pppoe <da> <sa> <session_id>
3099 * | vxlan ether <da> <sa>
3100 * [vlan <pcp> <dei> <vid>]
3101 * ipv4 <sa> <da> <dscp> <ttl>
3102 * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
3105 * [nat ipv4 | ipv6 <addr> <port>]
3113 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3115 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3116 * auth_algo <algo> auth_key <key> digest_size <size>
3118 * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
3119 * digest_size <size>
3120 * data_offset <data_offset>]
3125 * <pa> ::= g | y | r | drop
3128 parse_table_action_fwd(char **tokens,
3130 struct table_rule_action *a)
3132 if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
3138 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3139 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3140 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3144 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3147 if ((n_tokens < 2) ||
3148 parser_read_uint32(&id, tokens[1]))
3151 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3153 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3157 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3158 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3159 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3163 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3166 if ((n_tokens < 2) ||
3167 parser_read_uint32(&id, tokens[1]))
3170 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3172 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3180 parse_table_action_balance(char **tokens,
3182 struct table_rule_action *a)
3186 if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
3192 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3195 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3196 if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3199 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3200 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3205 parse_policer_action(char *token, enum rte_table_action_policer *a)
3207 if (strcmp(token, "g") == 0) {
3208 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3212 if (strcmp(token, "y") == 0) {
3213 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3217 if (strcmp(token, "r") == 0) {
3218 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3222 if (strcmp(token, "drop") == 0) {
3223 *a = RTE_TABLE_ACTION_POLICER_DROP;
3231 parse_table_action_meter_tc(char **tokens,
3233 struct rte_table_action_mtr_tc_params *mtr)
3235 if ((n_tokens < 9) ||
3236 strcmp(tokens[0], "meter") ||
3237 parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3238 strcmp(tokens[2], "policer") ||
3239 strcmp(tokens[3], "g") ||
3240 parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
3241 strcmp(tokens[5], "y") ||
3242 parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
3243 strcmp(tokens[7], "r") ||
3244 parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
3251 parse_table_action_meter(char **tokens,
3253 struct table_rule_action *a)
3255 if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
3261 if ((n_tokens < 10) ||
3262 strcmp(tokens[0], "tc0") ||
3263 (parse_table_action_meter_tc(tokens + 1,
3265 &a->mtr.mtr[0]) == 0))
3271 if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
3273 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3277 if ((n_tokens < 30) ||
3278 (parse_table_action_meter_tc(tokens + 1,
3279 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3280 strcmp(tokens[10], "tc2") ||
3281 (parse_table_action_meter_tc(tokens + 11,
3282 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3283 strcmp(tokens[20], "tc3") ||
3284 (parse_table_action_meter_tc(tokens + 21,
3285 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3288 a->mtr.tc_mask = 0xF;
3289 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3290 return 1 + 10 + 3 * 10;
3294 parse_table_action_tm(char **tokens,
3296 struct table_rule_action *a)
3298 uint32_t subport_id, pipe_id;
3300 if ((n_tokens < 5) ||
3301 strcmp(tokens[0], "tm") ||
3302 strcmp(tokens[1], "subport") ||
3303 parser_read_uint32(&subport_id, tokens[2]) ||
3304 strcmp(tokens[3], "pipe") ||
3305 parser_read_uint32(&pipe_id, tokens[4]))
3308 a->tm.subport_id = subport_id;
3309 a->tm.pipe_id = pipe_id;
3310 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3315 parse_table_action_encap(char **tokens,
3317 struct table_rule_action *a)
3319 if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
3326 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3327 if ((n_tokens < 3) ||
3328 parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3329 parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3332 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3333 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3338 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3339 uint32_t pcp, dei, vid;
3341 if ((n_tokens < 6) ||
3342 parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3343 parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3344 parser_read_uint32(&pcp, tokens[3]) ||
3346 parser_read_uint32(&dei, tokens[4]) ||
3348 parser_read_uint32(&vid, tokens[5]) ||
3352 a->encap.vlan.vlan.pcp = pcp & 0x7;
3353 a->encap.vlan.vlan.dei = dei & 0x1;
3354 a->encap.vlan.vlan.vid = vid & 0xFFF;
3355 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3356 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3361 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3362 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3363 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3365 if ((n_tokens < 9) ||
3366 parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3367 parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3368 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3369 (svlan_pcp > 0x7) ||
3370 parser_read_uint32(&svlan_dei, tokens[4]) ||
3371 (svlan_dei > 0x1) ||
3372 parser_read_uint32(&svlan_vid, tokens[5]) ||
3373 (svlan_vid > 0xFFF) ||
3374 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3375 (cvlan_pcp > 0x7) ||
3376 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3377 (cvlan_dei > 0x1) ||
3378 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3379 (cvlan_vid > 0xFFF))
3382 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3383 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3384 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3385 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3386 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3387 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3388 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3389 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3394 if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
3395 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3396 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3398 if ((n_tokens < 10) ||
3399 parse_mac_addr(tokens[1],
3400 &a->encap.qinq_pppoe.ether.da) ||
3401 parse_mac_addr(tokens[2],
3402 &a->encap.qinq_pppoe.ether.sa) ||
3403 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3404 (svlan_pcp > 0x7) ||
3405 parser_read_uint32(&svlan_dei, tokens[4]) ||
3406 (svlan_dei > 0x1) ||
3407 parser_read_uint32(&svlan_vid, tokens[5]) ||
3408 (svlan_vid > 0xFFF) ||
3409 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3410 (cvlan_pcp > 0x7) ||
3411 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3412 (cvlan_dei > 0x1) ||
3413 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3414 (cvlan_vid > 0xFFF) ||
3415 parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
3419 a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
3420 a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
3421 a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
3422 a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
3423 a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
3424 a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
3425 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
3426 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3432 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3433 uint32_t label, tc, ttl;
3438 if (strcmp(tokens[1], "unicast") == 0)
3439 a->encap.mpls.unicast = 1;
3440 else if (strcmp(tokens[1], "multicast") == 0)
3441 a->encap.mpls.unicast = 0;
3445 if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3446 parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3447 strcmp(tokens[4], "label0") ||
3448 parser_read_uint32(&label, tokens[5]) ||
3449 (label > 0xFFFFF) ||
3450 parser_read_uint32(&tc, tokens[6]) ||
3452 parser_read_uint32(&ttl, tokens[7]) ||
3456 a->encap.mpls.mpls[0].label = label;
3457 a->encap.mpls.mpls[0].tc = tc;
3458 a->encap.mpls.mpls[0].ttl = ttl;
3463 if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
3464 a->encap.mpls.mpls_count = 1;
3465 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3466 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3470 if ((n_tokens < 4) ||
3471 parser_read_uint32(&label, tokens[1]) ||
3472 (label > 0xFFFFF) ||
3473 parser_read_uint32(&tc, tokens[2]) ||
3475 parser_read_uint32(&ttl, tokens[3]) ||
3479 a->encap.mpls.mpls[1].label = label;
3480 a->encap.mpls.mpls[1].tc = tc;
3481 a->encap.mpls.mpls[1].ttl = ttl;
3486 if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
3487 a->encap.mpls.mpls_count = 2;
3488 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3489 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3493 if ((n_tokens < 4) ||
3494 parser_read_uint32(&label, tokens[1]) ||
3495 (label > 0xFFFFF) ||
3496 parser_read_uint32(&tc, tokens[2]) ||
3498 parser_read_uint32(&ttl, tokens[3]) ||
3502 a->encap.mpls.mpls[2].label = label;
3503 a->encap.mpls.mpls[2].tc = tc;
3504 a->encap.mpls.mpls[2].ttl = ttl;
3509 if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
3510 a->encap.mpls.mpls_count = 3;
3511 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3512 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3513 return 1 + 8 + 4 + 4;
3516 if ((n_tokens < 4) ||
3517 parser_read_uint32(&label, tokens[1]) ||
3518 (label > 0xFFFFF) ||
3519 parser_read_uint32(&tc, tokens[2]) ||
3521 parser_read_uint32(&ttl, tokens[3]) ||
3525 a->encap.mpls.mpls[3].label = label;
3526 a->encap.mpls.mpls[3].tc = tc;
3527 a->encap.mpls.mpls[3].ttl = ttl;
3529 a->encap.mpls.mpls_count = 4;
3530 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3531 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3532 return 1 + 8 + 4 + 4 + 4;
3536 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3537 if ((n_tokens < 4) ||
3538 parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3539 parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3540 parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3544 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3545 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3550 if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
3557 /* ether <da> <sa> */
3558 if ((n_tokens < 3) ||
3559 strcmp(tokens[0], "ether") ||
3560 parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
3561 parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
3568 /* [vlan <pcp> <dei> <vid>] */
3569 if (strcmp(tokens[0], "vlan") == 0) {
3570 uint32_t pcp, dei, vid;
3572 if ((n_tokens < 4) ||
3573 parser_read_uint32(&pcp, tokens[1]) ||
3575 parser_read_uint32(&dei, tokens[2]) ||
3577 parser_read_uint32(&vid, tokens[3]) ||
3581 a->encap.vxlan.vlan.pcp = pcp;
3582 a->encap.vxlan.vlan.dei = dei;
3583 a->encap.vxlan.vlan.vid = vid;
3590 /* ipv4 <sa> <da> <dscp> <ttl>
3591 | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
3592 if (strcmp(tokens[0], "ipv4") == 0) {
3593 struct in_addr sa, da;
3596 if ((n_tokens < 5) ||
3597 parse_ipv4_addr(tokens[1], &sa) ||
3598 parse_ipv4_addr(tokens[2], &da) ||
3599 parser_read_uint8(&dscp, tokens[3]) ||
3601 parser_read_uint8(&ttl, tokens[4]))
3604 a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
3605 a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
3606 a->encap.vxlan.ipv4.dscp = dscp;
3607 a->encap.vxlan.ipv4.ttl = ttl;
3612 } else if (strcmp(tokens[0], "ipv6") == 0) {
3613 struct in6_addr sa, da;
3614 uint32_t flow_label;
3615 uint8_t dscp, hop_limit;
3617 if ((n_tokens < 6) ||
3618 parse_ipv6_addr(tokens[1], &sa) ||
3619 parse_ipv6_addr(tokens[2], &da) ||
3620 parser_read_uint32(&flow_label, tokens[3]) ||
3621 parser_read_uint8(&dscp, tokens[4]) ||
3623 parser_read_uint8(&hop_limit, tokens[5]))
3626 memcpy(a->encap.vxlan.ipv6.sa, sa.s6_addr, 16);
3627 memcpy(a->encap.vxlan.ipv6.da, da.s6_addr, 16);
3628 a->encap.vxlan.ipv6.flow_label = flow_label;
3629 a->encap.vxlan.ipv6.dscp = dscp;
3630 a->encap.vxlan.ipv6.hop_limit = hop_limit;
3639 if ((n_tokens < 3) ||
3640 strcmp(tokens[0], "udp") ||
3641 parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
3642 parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
3650 if ((n_tokens < 2) ||
3651 strcmp(tokens[0], "vxlan") ||
3652 parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
3653 (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
3660 a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
3661 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3669 parse_table_action_nat(char **tokens,
3671 struct table_rule_action *a)
3673 if ((n_tokens < 4) ||
3674 strcmp(tokens[0], "nat"))
3677 if (strcmp(tokens[1], "ipv4") == 0) {
3678 struct in_addr addr;
3681 if (parse_ipv4_addr(tokens[2], &addr) ||
3682 parser_read_uint16(&port, tokens[3]))
3685 a->nat.ip_version = 1;
3686 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3688 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3692 if (strcmp(tokens[1], "ipv6") == 0) {
3693 struct in6_addr addr;
3696 if (parse_ipv6_addr(tokens[2], &addr) ||
3697 parser_read_uint16(&port, tokens[3]))
3700 a->nat.ip_version = 0;
3701 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3703 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3711 parse_table_action_ttl(char **tokens,
3713 struct table_rule_action *a)
3715 if ((n_tokens < 2) ||
3716 strcmp(tokens[0], "ttl"))
3719 if (strcmp(tokens[1], "dec") == 0)
3720 a->ttl.decrement = 1;
3721 else if (strcmp(tokens[1], "keep") == 0)
3722 a->ttl.decrement = 0;
3726 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3731 parse_table_action_stats(char **tokens,
3733 struct table_rule_action *a)
3735 if ((n_tokens < 1) ||
3736 strcmp(tokens[0], "stats"))
3739 a->stats.n_packets = 0;
3740 a->stats.n_bytes = 0;
3741 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3746 parse_table_action_time(char **tokens,
3748 struct table_rule_action *a)
3750 if ((n_tokens < 1) ||
3751 strcmp(tokens[0], "time"))
3754 a->time.time = rte_rdtsc();
3755 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3760 parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
3762 struct rte_crypto_sym_xform *xform[2] = {NULL};
3765 xform[0] = p->xform;
3767 xform[1] = xform[0]->next;
3769 for (i = 0; i < 2; i++) {
3770 if (xform[i] == NULL)
3773 switch (xform[i]->type) {
3774 case RTE_CRYPTO_SYM_XFORM_CIPHER:
3775 if (p->cipher_auth.cipher_iv.val)
3776 free(p->cipher_auth.cipher_iv.val);
3777 if (p->cipher_auth.cipher_iv_update.val)
3778 free(p->cipher_auth.cipher_iv_update.val);
3780 case RTE_CRYPTO_SYM_XFORM_AUTH:
3781 if (p->cipher_auth.auth_iv.val)
3782 free(p->cipher_auth.cipher_iv.val);
3783 if (p->cipher_auth.auth_iv_update.val)
3784 free(p->cipher_auth.cipher_iv_update.val);
3786 case RTE_CRYPTO_SYM_XFORM_AEAD:
3788 free(p->aead.iv.val);
3789 if (p->aead.aad.val)
3790 free(p->aead.aad.val);
3799 static struct rte_crypto_sym_xform *
3800 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
3801 uint8_t *key, uint32_t max_key_len, char **tokens,
3802 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3804 struct rte_crypto_sym_xform *xform_cipher;
3808 if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
3809 strcmp(tokens[3], "cipher_key") ||
3810 strcmp(tokens[5], "cipher_iv"))
3813 xform_cipher = calloc(1, sizeof(*xform_cipher));
3814 if (xform_cipher == NULL)
3817 xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
3818 xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
3819 RTE_CRYPTO_CIPHER_OP_DECRYPT;
3822 status = rte_cryptodev_get_cipher_algo_enum(
3823 &xform_cipher->cipher.algo, tokens[2]);
3828 len = strlen(tokens[4]);
3829 if (len / 2 > max_key_len) {
3834 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
3838 xform_cipher->cipher.key.data = key;
3839 xform_cipher->cipher.key.length = (uint16_t)len;
3842 len = strlen(tokens[6]);
3844 p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
3845 if (p->cipher_auth.cipher_iv.val == NULL)
3848 status = parse_hex_string(tokens[6],
3849 p->cipher_auth.cipher_iv.val,
3854 xform_cipher->cipher.iv.length = (uint16_t)len;
3855 xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
3856 p->cipher_auth.cipher_iv.length = (uint32_t)len;
3859 return xform_cipher;
3862 if (p->cipher_auth.cipher_iv.val) {
3863 free(p->cipher_auth.cipher_iv.val);
3864 p->cipher_auth.cipher_iv.val = NULL;
3872 static struct rte_crypto_sym_xform *
3873 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
3874 uint8_t *key, uint32_t max_key_len, char **tokens,
3875 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3877 struct rte_crypto_sym_xform *xform_cipher;
3878 struct rte_crypto_sym_xform *xform_auth;
3882 if (n_tokens < 13 ||
3883 strcmp(tokens[7], "auth_algo") ||
3884 strcmp(tokens[9], "auth_key") ||
3885 strcmp(tokens[11], "digest_size"))
3888 xform_auth = calloc(1, sizeof(*xform_auth));
3889 if (xform_auth == NULL)
3892 xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
3893 xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
3894 RTE_CRYPTO_AUTH_OP_VERIFY;
3897 status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
3903 len = strlen(tokens[10]);
3904 if (len / 2 > max_key_len) {
3909 status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
3913 xform_auth->auth.key.data = key;
3914 xform_auth->auth.key.length = (uint16_t)len;
3916 key += xform_auth->auth.key.length;
3917 max_key_len -= xform_auth->auth.key.length;
3919 if (strcmp(tokens[11], "digest_size"))
3922 status = parser_read_uint16(&xform_auth->auth.digest_length,
3927 xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
3928 7, encrypt, used_n_tokens);
3929 if (xform_cipher == NULL)
3932 *used_n_tokens += 6;
3935 xform_cipher->next = xform_auth;
3936 return xform_cipher;
3938 xform_auth->next = xform_cipher;
3943 if (p->cipher_auth.auth_iv.val) {
3944 free(p->cipher_auth.auth_iv.val);
3945 p->cipher_auth.auth_iv.val = 0;
3953 static struct rte_crypto_sym_xform *
3954 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
3955 uint8_t *key, uint32_t max_key_len, char **tokens,
3956 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3958 struct rte_crypto_sym_xform *xform_aead;
3962 if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
3963 strcmp(tokens[3], "aead_key") ||
3964 strcmp(tokens[5], "aead_iv") ||
3965 strcmp(tokens[7], "aead_aad") ||
3966 strcmp(tokens[9], "digest_size"))
3969 xform_aead = calloc(1, sizeof(*xform_aead));
3970 if (xform_aead == NULL)
3973 xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
3974 xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
3975 RTE_CRYPTO_AEAD_OP_DECRYPT;
3978 status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
3984 len = strlen(tokens[4]);
3985 if (len / 2 > max_key_len) {
3990 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
3994 xform_aead->aead.key.data = key;
3995 xform_aead->aead.key.length = (uint16_t)len;
3998 len = strlen(tokens[6]);
3999 p->aead.iv.val = calloc(1, len / 2 + 1);
4000 if (p->aead.iv.val == NULL)
4003 status = parse_hex_string(tokens[6], p->aead.iv.val,
4008 xform_aead->aead.iv.length = (uint16_t)len;
4009 xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
4010 p->aead.iv.length = (uint32_t)len;
4013 len = strlen(tokens[8]);
4014 p->aead.aad.val = calloc(1, len / 2 + 1);
4015 if (p->aead.aad.val == NULL)
4018 status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
4022 xform_aead->aead.aad_length = (uint16_t)len;
4023 p->aead.aad.length = (uint32_t)len;
4026 status = parser_read_uint16(&xform_aead->aead.digest_length,
4031 *used_n_tokens = 11;
4036 if (p->aead.iv.val) {
4037 free(p->aead.iv.val);
4038 p->aead.iv.val = NULL;
4040 if (p->aead.aad.val) {
4041 free(p->aead.aad.val);
4042 p->aead.aad.val = NULL;
4052 parse_table_action_sym_crypto(char **tokens,
4054 struct table_rule_action *a)
4056 struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
4057 struct rte_crypto_sym_xform *xform = NULL;
4058 uint8_t *key = a->sym_crypto_key;
4059 uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
4060 uint32_t used_n_tokens;
4064 if ((n_tokens < 12) ||
4065 strcmp(tokens[0], "sym_crypto") ||
4066 strcmp(tokens[2], "type"))
4069 memset(p, 0, sizeof(*p));
4071 if (strcmp(tokens[1], "encrypt") == 0)
4076 status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
4080 if (strcmp(tokens[3], "cipher") == 0) {
4084 xform = parse_table_action_cipher(p, key, max_key_len, tokens,
4085 n_tokens, encrypt, &used_n_tokens);
4086 } else if (strcmp(tokens[3], "cipher_auth") == 0) {
4090 xform = parse_table_action_cipher_auth(p, key, max_key_len,
4091 tokens, n_tokens, encrypt, &used_n_tokens);
4092 } else if (strcmp(tokens[3], "aead") == 0) {
4096 xform = parse_table_action_aead(p, key, max_key_len, tokens,
4097 n_tokens, encrypt, &used_n_tokens);
4105 if (strcmp(tokens[used_n_tokens], "data_offset")) {
4106 parse_free_sym_crypto_param_data(p);
4110 a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
4112 return used_n_tokens + 5;
4116 parse_table_action_tag(char **tokens,
4118 struct table_rule_action *a)
4120 if ((n_tokens < 2) ||
4121 strcmp(tokens[0], "tag"))
4124 if (parser_read_uint32(&a->tag.tag, tokens[1]))
4127 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
4132 parse_table_action_decap(char **tokens,
4134 struct table_rule_action *a)
4136 if ((n_tokens < 2) ||
4137 strcmp(tokens[0], "decap"))
4140 if (parser_read_uint16(&a->decap.n, tokens[1]))
4143 a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
4148 parse_table_action(char **tokens,
4152 struct table_rule_action *a)
4154 uint32_t n_tokens0 = n_tokens;
4156 memset(a, 0, sizeof(*a));
4158 if ((n_tokens < 2) ||
4159 strcmp(tokens[0], "action"))
4165 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
4168 n = parse_table_action_fwd(tokens, n_tokens, a);
4170 snprintf(out, out_size, MSG_ARG_INVALID,
4179 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
4182 n = parse_table_action_balance(tokens, n_tokens, a);
4184 snprintf(out, out_size, MSG_ARG_INVALID,
4193 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
4196 n = parse_table_action_meter(tokens, n_tokens, a);
4198 snprintf(out, out_size, MSG_ARG_INVALID,
4207 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
4210 n = parse_table_action_tm(tokens, n_tokens, a);
4212 snprintf(out, out_size, MSG_ARG_INVALID,
4221 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
4224 n = parse_table_action_encap(tokens, n_tokens, a);
4226 snprintf(out, out_size, MSG_ARG_INVALID,
4235 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
4238 n = parse_table_action_nat(tokens, n_tokens, a);
4240 snprintf(out, out_size, MSG_ARG_INVALID,
4249 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
4252 n = parse_table_action_ttl(tokens, n_tokens, a);
4254 snprintf(out, out_size, MSG_ARG_INVALID,
4263 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
4266 n = parse_table_action_stats(tokens, n_tokens, a);
4268 snprintf(out, out_size, MSG_ARG_INVALID,
4277 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
4280 n = parse_table_action_time(tokens, n_tokens, a);
4282 snprintf(out, out_size, MSG_ARG_INVALID,
4291 if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
4294 n = parse_table_action_sym_crypto(tokens, n_tokens, a);
4296 snprintf(out, out_size, MSG_ARG_INVALID,
4297 "action sym_crypto");
4304 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
4307 n = parse_table_action_tag(tokens, n_tokens, a);
4309 snprintf(out, out_size, MSG_ARG_INVALID,
4318 if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
4321 n = parse_table_action_decap(tokens, n_tokens, a);
4323 snprintf(out, out_size, MSG_ARG_INVALID,
4332 if (n_tokens0 - n_tokens == 1) {
4333 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4337 return n_tokens0 - n_tokens;
4341 static const char cmd_pipeline_table_rule_add_help[] =
4342 "pipeline <pipeline_name> table <table_id> rule add\n"
4344 " action <table_action>\n";
4347 cmd_pipeline_table_rule_add(char **tokens,
4352 struct table_rule_match m;
4353 struct table_rule_action a;
4354 char *pipeline_name;
4355 uint32_t table_id, t0, n_tokens_parsed;
4359 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4363 pipeline_name = tokens[1];
4365 if (strcmp(tokens[2], "table") != 0) {
4366 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4370 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4371 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4375 if (strcmp(tokens[4], "rule") != 0) {
4376 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4380 if (strcmp(tokens[5], "add") != 0) {
4381 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4388 n_tokens_parsed = parse_match(tokens + t0,
4393 if (n_tokens_parsed == 0)
4395 t0 += n_tokens_parsed;
4398 n_tokens_parsed = parse_table_action(tokens + t0,
4403 if (n_tokens_parsed == 0)
4405 t0 += n_tokens_parsed;
4407 if (t0 != n_tokens) {
4408 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
4412 status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
4414 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4418 if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
4419 parse_free_sym_crypto_param_data(&a.sym_crypto);
4423 static const char cmd_pipeline_table_rule_add_default_help[] =
4424 "pipeline <pipeline_name> table <table_id> rule add\n"
4430 " | port <port_id>\n"
4432 " | table <table_id>\n";
4435 cmd_pipeline_table_rule_add_default(char **tokens,
4440 struct table_rule_action action;
4441 char *pipeline_name;
4445 if ((n_tokens != 11) && (n_tokens != 12)) {
4446 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4450 pipeline_name = tokens[1];
4452 if (strcmp(tokens[2], "table") != 0) {
4453 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4457 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4458 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4462 if (strcmp(tokens[4], "rule") != 0) {
4463 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4467 if (strcmp(tokens[5], "add") != 0) {
4468 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4472 if (strcmp(tokens[6], "match") != 0) {
4473 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4477 if (strcmp(tokens[7], "default") != 0) {
4478 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4482 if (strcmp(tokens[8], "action") != 0) {
4483 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4487 if (strcmp(tokens[9], "fwd") != 0) {
4488 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4492 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4494 if (strcmp(tokens[10], "drop") == 0) {
4495 if (n_tokens != 11) {
4496 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4500 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4501 } else if (strcmp(tokens[10], "port") == 0) {
4504 if (n_tokens != 12) {
4505 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4509 if (parser_read_uint32(&id, tokens[11]) != 0) {
4510 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4514 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4516 } else if (strcmp(tokens[10], "meta") == 0) {
4517 if (n_tokens != 11) {
4518 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4522 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4523 } else if (strcmp(tokens[10], "table") == 0) {
4526 if (n_tokens != 12) {
4527 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4531 if (parser_read_uint32(&id, tokens[11]) != 0) {
4532 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4536 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4539 snprintf(out, out_size, MSG_ARG_INVALID,
4540 "drop or port or meta or table");
4544 status = pipeline_table_rule_add_default(pipeline_name,
4548 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4554 static const char cmd_pipeline_table_rule_add_bulk_help[] =
4555 "pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
4557 " File <file_name>:\n"
4558 " - line format: match <match> action <action>\n";
4561 cli_rule_file_process(const char *file_name,
4562 size_t line_len_max,
4563 struct table_rule_list **rule_list,
4565 uint32_t *line_number,
4570 cmd_pipeline_table_rule_add_bulk(char **tokens,
4575 struct table_rule_list *list = NULL;
4576 char *pipeline_name, *file_name;
4577 uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
4580 if (n_tokens != 8) {
4581 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4585 pipeline_name = tokens[1];
4587 if (strcmp(tokens[2], "table") != 0) {
4588 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4592 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4593 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4597 if (strcmp(tokens[4], "rule") != 0) {
4598 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4602 if (strcmp(tokens[5], "add") != 0) {
4603 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4607 if (strcmp(tokens[6], "bulk") != 0) {
4608 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4612 file_name = tokens[7];
4614 /* Load rules from file. */
4615 status = cli_rule_file_process(file_name,
4623 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4628 status = pipeline_table_rule_add_bulk(pipeline_name,
4632 &n_rules_not_added);
4634 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4638 snprintf(out, out_size, "Added %u rules out of %u.\n",
4644 static const char cmd_pipeline_table_rule_delete_help[] =
4645 "pipeline <pipeline_name> table <table_id> rule delete\n"
4649 cmd_pipeline_table_rule_delete(char **tokens,
4654 struct table_rule_match m;
4655 char *pipeline_name;
4656 uint32_t table_id, n_tokens_parsed, t0;
4660 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4664 pipeline_name = tokens[1];
4666 if (strcmp(tokens[2], "table") != 0) {
4667 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4671 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4672 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4676 if (strcmp(tokens[4], "rule") != 0) {
4677 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4681 if (strcmp(tokens[5], "delete") != 0) {
4682 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4689 n_tokens_parsed = parse_match(tokens + t0,
4694 if (n_tokens_parsed == 0)
4696 t0 += n_tokens_parsed;
4698 if (n_tokens != t0) {
4699 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4703 status = pipeline_table_rule_delete(pipeline_name,
4707 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4713 static const char cmd_pipeline_table_rule_delete_default_help[] =
4714 "pipeline <pipeline_name> table <table_id> rule delete\n"
4719 cmd_pipeline_table_rule_delete_default(char **tokens,
4724 char *pipeline_name;
4728 if (n_tokens != 8) {
4729 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4733 pipeline_name = tokens[1];
4735 if (strcmp(tokens[2], "table") != 0) {
4736 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4740 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4741 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4745 if (strcmp(tokens[4], "rule") != 0) {
4746 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4750 if (strcmp(tokens[5], "delete") != 0) {
4751 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4755 if (strcmp(tokens[6], "match") != 0) {
4756 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4760 if (strcmp(tokens[7], "default") != 0) {
4761 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4765 status = pipeline_table_rule_delete_default(pipeline_name,
4768 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4774 ether_addr_show(FILE *f, struct rte_ether_addr *addr)
4776 fprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x",
4777 (uint32_t)addr->addr_bytes[0], (uint32_t)addr->addr_bytes[1],
4778 (uint32_t)addr->addr_bytes[2], (uint32_t)addr->addr_bytes[3],
4779 (uint32_t)addr->addr_bytes[4], (uint32_t)addr->addr_bytes[5]);
4783 ipv4_addr_show(FILE *f, uint32_t addr)
4785 fprintf(f, "%u.%u.%u.%u",
4787 (addr >> 16) & 0xFF,
4793 ipv6_addr_show(FILE *f, uint8_t *addr)
4795 fprintf(f, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
4796 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:",
4797 (uint32_t)addr[0], (uint32_t)addr[1],
4798 (uint32_t)addr[2], (uint32_t)addr[3],
4799 (uint32_t)addr[4], (uint32_t)addr[5],
4800 (uint32_t)addr[6], (uint32_t)addr[7],
4801 (uint32_t)addr[8], (uint32_t)addr[9],
4802 (uint32_t)addr[10], (uint32_t)addr[11],
4803 (uint32_t)addr[12], (uint32_t)addr[13],
4804 (uint32_t)addr[14], (uint32_t)addr[15]);
4808 policer_action_string(enum rte_table_action_policer action) {
4810 case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
4811 case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
4812 case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
4813 case RTE_TABLE_ACTION_POLICER_DROP: return "D";
4814 default: return "?";
4819 table_rule_show(const char *pipeline_name,
4821 const char *file_name)
4824 struct table *table;
4825 struct table_rule *rule;
4829 /* Check input params. */
4830 if ((pipeline_name == NULL) ||
4831 (file_name == NULL))
4834 p = pipeline_find(pipeline_name);
4836 (table_id >= p->n_tables))
4839 table = &p->table[table_id];
4842 f = fopen(file_name, "w");
4846 /* Write table rules to file. */
4847 TAILQ_FOREACH(rule, &table->rules, node) {
4848 struct table_rule_match *m = &rule->match;
4849 struct table_rule_action *a = &rule->action;
4851 fprintf(f, "match ");
4852 switch (m->match_type) {
4854 fprintf(f, "acl priority %u ",
4855 m->match.acl.priority);
4857 fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
4859 if (m->match.acl.ip_version)
4860 ipv4_addr_show(f, m->match.acl.ipv4.sa);
4862 ipv6_addr_show(f, m->match.acl.ipv6.sa);
4864 fprintf(f, "%u", m->match.acl.sa_depth);
4866 if (m->match.acl.ip_version)
4867 ipv4_addr_show(f, m->match.acl.ipv4.da);
4869 ipv6_addr_show(f, m->match.acl.ipv6.da);
4871 fprintf(f, "%u", m->match.acl.da_depth);
4873 fprintf(f, "%u %u %u %u %u ",
4874 (uint32_t)m->match.acl.sp0,
4875 (uint32_t)m->match.acl.sp1,
4876 (uint32_t)m->match.acl.dp0,
4877 (uint32_t)m->match.acl.dp1,
4878 (uint32_t)m->match.acl.proto);
4882 fprintf(f, "array %u ",
4883 m->match.array.pos);
4887 fprintf(f, "hash raw ");
4888 for (i = 0; i < table->params.match.hash.key_size; i++)
4889 fprintf(f, "%02x", m->match.hash.key[i]);
4896 fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
4898 if (m->match.acl.ip_version)
4899 ipv4_addr_show(f, m->match.lpm.ipv4);
4901 ipv6_addr_show(f, m->match.lpm.ipv6);
4904 (uint32_t)m->match.lpm.depth);
4908 fprintf(f, "unknown ");
4911 fprintf(f, "action ");
4912 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
4914 switch (a->fwd.action) {
4915 case RTE_PIPELINE_ACTION_DROP:
4916 fprintf(f, "drop ");
4919 case RTE_PIPELINE_ACTION_PORT:
4920 fprintf(f, "port %u ", a->fwd.id);
4923 case RTE_PIPELINE_ACTION_PORT_META:
4924 fprintf(f, "meta ");
4927 case RTE_PIPELINE_ACTION_TABLE:
4929 fprintf(f, "table %u ", a->fwd.id);
4933 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
4934 fprintf(f, "balance ");
4935 for (i = 0; i < RTE_DIM(a->lb.out); i++)
4936 fprintf(f, "%u ", a->lb.out[i]);
4939 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
4941 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
4942 if (a->mtr.tc_mask & (1 << i)) {
4943 struct rte_table_action_mtr_tc_params *p =
4945 enum rte_table_action_policer ga =
4946 p->policer[RTE_COLOR_GREEN];
4947 enum rte_table_action_policer ya =
4948 p->policer[RTE_COLOR_YELLOW];
4949 enum rte_table_action_policer ra =
4950 p->policer[RTE_COLOR_RED];
4952 fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
4954 a->mtr.mtr[i].meter_profile_id,
4955 policer_action_string(ga),
4956 policer_action_string(ya),
4957 policer_action_string(ra));
4961 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
4962 fprintf(f, "tm subport %u pipe %u ",
4966 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
4967 fprintf(f, "encap ");
4968 switch (a->encap.type) {
4969 case RTE_TABLE_ACTION_ENCAP_ETHER:
4970 fprintf(f, "ether ");
4971 ether_addr_show(f, &a->encap.ether.ether.da);
4973 ether_addr_show(f, &a->encap.ether.ether.sa);
4977 case RTE_TABLE_ACTION_ENCAP_VLAN:
4978 fprintf(f, "vlan ");
4979 ether_addr_show(f, &a->encap.vlan.ether.da);
4981 ether_addr_show(f, &a->encap.vlan.ether.sa);
4982 fprintf(f, " pcp %u dei %u vid %u ",
4983 a->encap.vlan.vlan.pcp,
4984 a->encap.vlan.vlan.dei,
4985 a->encap.vlan.vlan.vid);
4988 case RTE_TABLE_ACTION_ENCAP_QINQ:
4989 fprintf(f, "qinq ");
4990 ether_addr_show(f, &a->encap.qinq.ether.da);
4992 ether_addr_show(f, &a->encap.qinq.ether.sa);
4993 fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
4994 a->encap.qinq.svlan.pcp,
4995 a->encap.qinq.svlan.dei,
4996 a->encap.qinq.svlan.vid,
4997 a->encap.qinq.cvlan.pcp,
4998 a->encap.qinq.cvlan.dei,
4999 a->encap.qinq.cvlan.vid);
5002 case RTE_TABLE_ACTION_ENCAP_MPLS:
5003 fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
5004 "unicast " : "multicast ");
5005 ether_addr_show(f, &a->encap.mpls.ether.da);
5007 ether_addr_show(f, &a->encap.mpls.ether.sa);
5009 for (i = 0; i < a->encap.mpls.mpls_count; i++) {
5010 struct rte_table_action_mpls_hdr *l =
5011 &a->encap.mpls.mpls[i];
5013 fprintf(f, "label%u %u %u %u ",
5021 case RTE_TABLE_ACTION_ENCAP_PPPOE:
5022 fprintf(f, "pppoe ");
5023 ether_addr_show(f, &a->encap.pppoe.ether.da);
5025 ether_addr_show(f, &a->encap.pppoe.ether.sa);
5026 fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
5029 case RTE_TABLE_ACTION_ENCAP_VXLAN:
5030 fprintf(f, "vxlan ether ");
5031 ether_addr_show(f, &a->encap.vxlan.ether.da);
5033 ether_addr_show(f, &a->encap.vxlan.ether.sa);
5034 if (table->ap->params.encap.vxlan.vlan)
5035 fprintf(f, " vlan pcp %u dei %u vid %u ",
5036 a->encap.vxlan.vlan.pcp,
5037 a->encap.vxlan.vlan.dei,
5038 a->encap.vxlan.vlan.vid);
5039 if (table->ap->params.encap.vxlan.ip_version) {
5040 fprintf(f, " ipv4 ");
5041 ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
5043 ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
5044 fprintf(f, " %u %u ",
5045 (uint32_t)a->encap.vxlan.ipv4.dscp,
5046 (uint32_t)a->encap.vxlan.ipv4.ttl);
5048 fprintf(f, " ipv6 ");
5049 ipv6_addr_show(f, a->encap.vxlan.ipv6.sa);
5051 ipv6_addr_show(f, a->encap.vxlan.ipv6.da);
5052 fprintf(f, " %u %u %u ",
5053 a->encap.vxlan.ipv6.flow_label,
5054 (uint32_t)a->encap.vxlan.ipv6.dscp,
5055 (uint32_t)a->encap.vxlan.ipv6.hop_limit);
5056 fprintf(f, " udp %u %u vxlan %u ",
5057 a->encap.vxlan.udp.sp,
5058 a->encap.vxlan.udp.dp,
5059 a->encap.vxlan.vxlan.vni);
5064 fprintf(f, "unknown ");
5068 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
5069 fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
5070 if (a->nat.ip_version)
5071 ipv4_addr_show(f, a->nat.addr.ipv4);
5073 ipv6_addr_show(f, a->nat.addr.ipv6);
5074 fprintf(f, " %u ", (uint32_t)(a->nat.port));
5077 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
5078 fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
5080 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
5081 fprintf(f, "stats ");
5083 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
5084 fprintf(f, "time ");
5086 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
5087 fprintf(f, "sym_crypto ");
5089 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
5090 fprintf(f, "tag %u ", a->tag.tag);
5092 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
5093 fprintf(f, "decap %u ", a->decap.n);
5099 /* Write table default rule to file. */
5100 if (table->rule_default) {
5101 struct table_rule_action *a = &table->rule_default->action;
5103 fprintf(f, "# match default action fwd ");
5105 switch (a->fwd.action) {
5106 case RTE_PIPELINE_ACTION_DROP:
5107 fprintf(f, "drop ");
5110 case RTE_PIPELINE_ACTION_PORT:
5111 fprintf(f, "port %u ", a->fwd.id);
5114 case RTE_PIPELINE_ACTION_PORT_META:
5115 fprintf(f, "meta ");
5118 case RTE_PIPELINE_ACTION_TABLE:
5120 fprintf(f, "table %u ", a->fwd.id);
5123 fprintf(f, "# match default action fwd drop ");
5133 static const char cmd_pipeline_table_rule_show_help[] =
5134 "pipeline <pipeline_name> table <table_id> rule show\n"
5135 " file <file_name>\n";
5138 cmd_pipeline_table_rule_show(char **tokens,
5143 char *file_name = NULL, *pipeline_name;
5147 if (n_tokens != 8) {
5148 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5152 pipeline_name = tokens[1];
5154 if (strcmp(tokens[2], "table") != 0) {
5155 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5159 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5160 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5164 if (strcmp(tokens[4], "rule") != 0) {
5165 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5169 if (strcmp(tokens[5], "show") != 0) {
5170 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
5174 if (strcmp(tokens[6], "file") != 0) {
5175 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
5179 file_name = tokens[7];
5181 status = table_rule_show(pipeline_name, table_id, file_name);
5183 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5188 static const char cmd_pipeline_table_rule_stats_read_help[] =
5189 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
5193 cmd_pipeline_table_rule_stats_read(char **tokens,
5198 struct table_rule_match m;
5199 struct rte_table_action_stats_counters stats;
5200 char *pipeline_name;
5201 uint32_t table_id, n_tokens_parsed;
5202 int clear = 0, status;
5205 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5209 pipeline_name = tokens[1];
5211 if (strcmp(tokens[2], "table") != 0) {
5212 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5216 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5217 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5221 if (strcmp(tokens[4], "rule") != 0) {
5222 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5226 if (strcmp(tokens[5], "read") != 0) {
5227 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5231 if (strcmp(tokens[6], "stats") != 0) {
5232 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
5240 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5248 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5249 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5253 n_tokens_parsed = parse_match(tokens,
5258 if (n_tokens_parsed == 0)
5260 n_tokens -= n_tokens_parsed;
5261 tokens += n_tokens_parsed;
5265 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5269 /* Read table rule stats. */
5270 status = pipeline_table_rule_stats_read(pipeline_name,
5276 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5281 if (stats.n_packets_valid && stats.n_bytes_valid)
5282 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
5286 if (stats.n_packets_valid && !stats.n_bytes_valid)
5287 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
5290 if (!stats.n_packets_valid && stats.n_bytes_valid)
5291 snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
5294 if (!stats.n_packets_valid && !stats.n_bytes_valid)
5295 snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
5298 static const char cmd_pipeline_table_meter_profile_add_help[] =
5299 "pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
5300 " add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
5301 " | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
5304 cmd_pipeline_table_meter_profile_add(char **tokens,
5309 struct rte_table_action_meter_profile p;
5310 char *pipeline_name;
5311 uint32_t table_id, meter_profile_id;
5315 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5319 pipeline_name = tokens[1];
5321 if (strcmp(tokens[2], "table") != 0) {
5322 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5326 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5327 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5331 if (strcmp(tokens[4], "meter") != 0) {
5332 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5336 if (strcmp(tokens[5], "profile") != 0) {
5337 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5341 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5342 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5346 if (strcmp(tokens[7], "add") != 0) {
5347 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
5351 if (strcmp(tokens[8], "srtcm") == 0) {
5352 if (n_tokens != 15) {
5353 snprintf(out, out_size, MSG_ARG_MISMATCH,
5358 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
5360 if (strcmp(tokens[9], "cir") != 0) {
5361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5365 if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
5366 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5370 if (strcmp(tokens[11], "cbs") != 0) {
5371 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5375 if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
5376 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5380 if (strcmp(tokens[13], "ebs") != 0) {
5381 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
5385 if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
5386 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
5389 } else if (strcmp(tokens[8], "trtcm") == 0) {
5390 if (n_tokens != 17) {
5391 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5395 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
5397 if (strcmp(tokens[9], "cir") != 0) {
5398 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5402 if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
5403 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5407 if (strcmp(tokens[11], "pir") != 0) {
5408 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
5412 if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
5413 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
5416 if (strcmp(tokens[13], "cbs") != 0) {
5417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5421 if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
5422 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5426 if (strcmp(tokens[15], "pbs") != 0) {
5427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
5431 if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
5432 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
5436 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5440 status = pipeline_table_mtr_profile_add(pipeline_name,
5445 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5451 static const char cmd_pipeline_table_meter_profile_delete_help[] =
5452 "pipeline <pipeline_name> table <table_id>\n"
5453 " meter profile <meter_profile_id> delete\n";
5456 cmd_pipeline_table_meter_profile_delete(char **tokens,
5461 char *pipeline_name;
5462 uint32_t table_id, meter_profile_id;
5465 if (n_tokens != 8) {
5466 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5470 pipeline_name = tokens[1];
5472 if (strcmp(tokens[2], "table") != 0) {
5473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5477 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5478 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5482 if (strcmp(tokens[4], "meter") != 0) {
5483 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5487 if (strcmp(tokens[5], "profile") != 0) {
5488 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5492 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5493 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5497 if (strcmp(tokens[7], "delete") != 0) {
5498 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
5502 status = pipeline_table_mtr_profile_delete(pipeline_name,
5506 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5512 static const char cmd_pipeline_table_rule_meter_read_help[] =
5513 "pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
5517 cmd_pipeline_table_rule_meter_read(char **tokens,
5522 struct table_rule_match m;
5523 struct rte_table_action_mtr_counters stats;
5524 char *pipeline_name;
5525 uint32_t table_id, n_tokens_parsed;
5526 int clear = 0, status;
5529 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5533 pipeline_name = tokens[1];
5535 if (strcmp(tokens[2], "table") != 0) {
5536 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5540 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5541 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5545 if (strcmp(tokens[4], "rule") != 0) {
5546 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5550 if (strcmp(tokens[5], "read") != 0) {
5551 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5555 if (strcmp(tokens[6], "meter") != 0) {
5556 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5564 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5572 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5573 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5577 n_tokens_parsed = parse_match(tokens,
5582 if (n_tokens_parsed == 0)
5584 n_tokens -= n_tokens_parsed;
5585 tokens += n_tokens_parsed;
5589 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5593 /* Read table rule meter stats. */
5594 status = pipeline_table_rule_mtr_read(pipeline_name,
5600 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5608 static const char cmd_pipeline_table_dscp_help[] =
5609 "pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
5611 " File <file_name>:\n"
5612 " - exactly 64 lines\n"
5613 " - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
5616 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
5617 const char *file_name,
5618 uint32_t *line_number)
5623 /* Check input arguments */
5624 if ((dscp_table == NULL) ||
5625 (file_name == NULL) ||
5626 (line_number == NULL)) {
5632 /* Open input file */
5633 f = fopen(file_name, "r");
5640 for (dscp = 0, l = 1; ; l++) {
5643 enum rte_color color;
5644 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
5646 if (fgets(line, sizeof(line), f) == NULL)
5649 if (is_comment(line))
5652 if (parse_tokenize_string(line, tokens, &n_tokens)) {
5661 if ((dscp >= RTE_DIM(dscp_table->entry)) ||
5662 (n_tokens != RTE_DIM(tokens)) ||
5663 parser_read_uint32(&tc_id, tokens[0]) ||
5664 (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
5665 parser_read_uint32(&tc_queue_id, tokens[1]) ||
5666 (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
5667 (strlen(tokens[2]) != 1)) {
5673 switch (tokens[2][0]) {
5676 color = RTE_COLOR_GREEN;
5681 color = RTE_COLOR_YELLOW;
5686 color = RTE_COLOR_RED;
5695 dscp_table->entry[dscp].tc_id = tc_id;
5696 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
5697 dscp_table->entry[dscp].color = color;
5707 cmd_pipeline_table_dscp(char **tokens,
5712 struct rte_table_action_dscp_table dscp_table;
5713 char *pipeline_name, *file_name;
5714 uint32_t table_id, line_number;
5717 if (n_tokens != 6) {
5718 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5722 pipeline_name = tokens[1];
5724 if (strcmp(tokens[2], "table") != 0) {
5725 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5729 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5730 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5734 if (strcmp(tokens[4], "dscp") != 0) {
5735 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
5739 file_name = tokens[5];
5741 status = load_dscp_table(&dscp_table, file_name, &line_number);
5743 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
5747 status = pipeline_table_dscp_table_update(pipeline_name,
5752 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5758 static const char cmd_pipeline_table_rule_ttl_read_help[] =
5759 "pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
5763 cmd_pipeline_table_rule_ttl_read(char **tokens,
5768 struct table_rule_match m;
5769 struct rte_table_action_ttl_counters stats;
5770 char *pipeline_name;
5771 uint32_t table_id, n_tokens_parsed;
5772 int clear = 0, status;
5775 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5779 pipeline_name = tokens[1];
5781 if (strcmp(tokens[2], "table") != 0) {
5782 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5786 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5787 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5791 if (strcmp(tokens[4], "rule") != 0) {
5792 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5796 if (strcmp(tokens[5], "read") != 0) {
5797 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5801 if (strcmp(tokens[6], "ttl") != 0) {
5802 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
5810 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5818 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5819 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5823 n_tokens_parsed = parse_match(tokens,
5828 if (n_tokens_parsed == 0)
5830 n_tokens -= n_tokens_parsed;
5831 tokens += n_tokens_parsed;
5835 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5839 /* Read table rule TTL stats. */
5840 status = pipeline_table_rule_ttl_read(pipeline_name,
5846 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5851 snprintf(out, out_size, "Packets: %" PRIu64 "\n",
5855 static const char cmd_pipeline_table_rule_time_read_help[] =
5856 "pipeline <pipeline_name> table <table_id> rule read time\n"
5860 cmd_pipeline_table_rule_time_read(char **tokens,
5865 struct table_rule_match m;
5866 char *pipeline_name;
5868 uint32_t table_id, n_tokens_parsed;
5872 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5876 pipeline_name = tokens[1];
5878 if (strcmp(tokens[2], "table") != 0) {
5879 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5883 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5884 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5888 if (strcmp(tokens[4], "rule") != 0) {
5889 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5893 if (strcmp(tokens[5], "read") != 0) {
5894 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5898 if (strcmp(tokens[6], "time") != 0) {
5899 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
5907 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5908 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5912 n_tokens_parsed = parse_match(tokens,
5917 if (n_tokens_parsed == 0)
5919 n_tokens -= n_tokens_parsed;
5920 tokens += n_tokens_parsed;
5924 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5928 /* Read table rule timestamp. */
5929 status = pipeline_table_rule_time_read(pipeline_name,
5934 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5939 snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
5942 static const char cmd_thread_pipeline_enable_help[] =
5943 "thread <thread_id> pipeline <pipeline_name> enable\n";
5946 cmd_thread_pipeline_enable(char **tokens,
5951 char *pipeline_name;
5955 if (n_tokens != 5) {
5956 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5960 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
5961 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
5965 if (strcmp(tokens[2], "pipeline") != 0) {
5966 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5970 pipeline_name = tokens[3];
5972 if (strcmp(tokens[4], "enable") != 0) {
5973 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
5977 status = thread_pipeline_enable(thread_id, pipeline_name);
5979 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
5985 static const char cmd_thread_pipeline_disable_help[] =
5986 "thread <thread_id> pipeline <pipeline_name> disable\n";
5989 cmd_thread_pipeline_disable(char **tokens,
5994 char *pipeline_name;
5998 if (n_tokens != 5) {
5999 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6003 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
6004 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
6008 if (strcmp(tokens[2], "pipeline") != 0) {
6009 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
6013 pipeline_name = tokens[3];
6015 if (strcmp(tokens[4], "disable") != 0) {
6016 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
6020 status = thread_pipeline_disable(thread_id, pipeline_name);
6022 snprintf(out, out_size, MSG_CMD_FAIL,
6023 "thread pipeline disable");
6029 cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
6034 if (n_tokens == 0) {
6035 snprintf(out, out_size,
6036 "Type 'help <command>' for details on each command.\n\n"
6037 "List of commands:\n"
6041 "\ttmgr subport profile\n"
6042 "\ttmgr pipe profile\n"
6045 "\ttmgr subport pipe\n"
6048 "\tport in action profile\n"
6049 "\ttable action profile\n"
6051 "\tpipeline port in\n"
6052 "\tpipeline port out\n"
6053 "\tpipeline table\n"
6054 "\tpipeline port in table\n"
6055 "\tpipeline port in stats\n"
6056 "\tpipeline port in enable\n"
6057 "\tpipeline port in disable\n"
6058 "\tpipeline port out stats\n"
6059 "\tpipeline table stats\n"
6060 "\tpipeline table rule add\n"
6061 "\tpipeline table rule add default\n"
6062 "\tpipeline table rule add bulk\n"
6063 "\tpipeline table rule delete\n"
6064 "\tpipeline table rule delete default\n"
6065 "\tpipeline table rule show\n"
6066 "\tpipeline table rule stats read\n"
6067 "\tpipeline table meter profile add\n"
6068 "\tpipeline table meter profile delete\n"
6069 "\tpipeline table rule meter read\n"
6070 "\tpipeline table dscp\n"
6071 "\tpipeline table rule ttl read\n"
6072 "\tpipeline table rule time read\n"
6073 "\tthread pipeline enable\n"
6074 "\tthread pipeline disable\n\n");
6078 if (strcmp(tokens[0], "mempool") == 0) {
6079 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
6083 if (strcmp(tokens[0], "link") == 0) {
6084 snprintf(out, out_size, "\n%s\n", cmd_link_help);
6088 if (strcmp(tokens[0], "swq") == 0) {
6089 snprintf(out, out_size, "\n%s\n", cmd_swq_help);
6093 if (strcmp(tokens[0], "tmgr") == 0) {
6094 if (n_tokens == 1) {
6095 snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
6099 if ((n_tokens == 2) &&
6100 (strcmp(tokens[1], "subport")) == 0) {
6101 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
6105 if ((n_tokens == 3) &&
6106 (strcmp(tokens[1], "subport") == 0) &&
6107 (strcmp(tokens[2], "profile") == 0)) {
6108 snprintf(out, out_size, "\n%s\n",
6109 cmd_tmgr_subport_profile_help);
6113 if ((n_tokens == 3) &&
6114 (strcmp(tokens[1], "subport") == 0) &&
6115 (strcmp(tokens[2], "pipe") == 0)) {
6116 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
6120 if ((n_tokens == 3) &&
6121 (strcmp(tokens[1], "pipe") == 0) &&
6122 (strcmp(tokens[2], "profile") == 0)) {
6123 snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
6128 if (strcmp(tokens[0], "tap") == 0) {
6129 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
6133 if (strcmp(tokens[0], "kni") == 0) {
6134 snprintf(out, out_size, "\n%s\n", cmd_kni_help);
6138 if (strcmp(tokens[0], "cryptodev") == 0) {
6139 snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
6143 if ((n_tokens == 4) &&
6144 (strcmp(tokens[0], "port") == 0) &&
6145 (strcmp(tokens[1], "in") == 0) &&
6146 (strcmp(tokens[2], "action") == 0) &&
6147 (strcmp(tokens[3], "profile") == 0)) {
6148 snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
6152 if ((n_tokens == 3) &&
6153 (strcmp(tokens[0], "table") == 0) &&
6154 (strcmp(tokens[1], "action") == 0) &&
6155 (strcmp(tokens[2], "profile") == 0)) {
6156 snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
6160 if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
6161 snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
6165 if ((strcmp(tokens[0], "pipeline") == 0) &&
6166 (strcmp(tokens[1], "port") == 0)) {
6167 if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
6168 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
6172 if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
6173 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
6177 if ((n_tokens == 4) &&
6178 (strcmp(tokens[2], "in") == 0) &&
6179 (strcmp(tokens[3], "table") == 0)) {
6180 snprintf(out, out_size, "\n%s\n",
6181 cmd_pipeline_port_in_table_help);
6185 if ((n_tokens == 4) &&
6186 (strcmp(tokens[2], "in") == 0) &&
6187 (strcmp(tokens[3], "stats") == 0)) {
6188 snprintf(out, out_size, "\n%s\n",
6189 cmd_pipeline_port_in_stats_help);
6193 if ((n_tokens == 4) &&
6194 (strcmp(tokens[2], "in") == 0) &&
6195 (strcmp(tokens[3], "enable") == 0)) {
6196 snprintf(out, out_size, "\n%s\n",
6197 cmd_pipeline_port_in_enable_help);
6201 if ((n_tokens == 4) &&
6202 (strcmp(tokens[2], "in") == 0) &&
6203 (strcmp(tokens[3], "disable") == 0)) {
6204 snprintf(out, out_size, "\n%s\n",
6205 cmd_pipeline_port_in_disable_help);
6209 if ((n_tokens == 4) &&
6210 (strcmp(tokens[2], "out") == 0) &&
6211 (strcmp(tokens[3], "stats") == 0)) {
6212 snprintf(out, out_size, "\n%s\n",
6213 cmd_pipeline_port_out_stats_help);
6218 if ((strcmp(tokens[0], "pipeline") == 0) &&
6219 (strcmp(tokens[1], "table") == 0)) {
6220 if (n_tokens == 2) {
6221 snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
6225 if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
6226 snprintf(out, out_size, "\n%s\n",
6227 cmd_pipeline_table_stats_help);
6231 if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
6232 snprintf(out, out_size, "\n%s\n",
6233 cmd_pipeline_table_dscp_help);
6237 if ((n_tokens == 4) &&
6238 (strcmp(tokens[2], "rule") == 0) &&
6239 (strcmp(tokens[3], "add") == 0)) {
6240 snprintf(out, out_size, "\n%s\n",
6241 cmd_pipeline_table_rule_add_help);
6245 if ((n_tokens == 5) &&
6246 (strcmp(tokens[2], "rule") == 0) &&
6247 (strcmp(tokens[3], "add") == 0) &&
6248 (strcmp(tokens[4], "default") == 0)) {
6249 snprintf(out, out_size, "\n%s\n",
6250 cmd_pipeline_table_rule_add_default_help);
6254 if ((n_tokens == 5) &&
6255 (strcmp(tokens[2], "rule") == 0) &&
6256 (strcmp(tokens[3], "add") == 0) &&
6257 (strcmp(tokens[4], "bulk") == 0)) {
6258 snprintf(out, out_size, "\n%s\n",
6259 cmd_pipeline_table_rule_add_bulk_help);
6263 if ((n_tokens == 4) &&
6264 (strcmp(tokens[2], "rule") == 0) &&
6265 (strcmp(tokens[3], "delete") == 0)) {
6266 snprintf(out, out_size, "\n%s\n",
6267 cmd_pipeline_table_rule_delete_help);
6271 if ((n_tokens == 5) &&
6272 (strcmp(tokens[2], "rule") == 0) &&
6273 (strcmp(tokens[3], "delete") == 0) &&
6274 (strcmp(tokens[4], "default") == 0)) {
6275 snprintf(out, out_size, "\n%s\n",
6276 cmd_pipeline_table_rule_delete_default_help);
6280 if ((n_tokens == 4) &&
6281 (strcmp(tokens[2], "rule") == 0) &&
6282 (strcmp(tokens[3], "show") == 0)) {
6283 snprintf(out, out_size, "\n%s\n",
6284 cmd_pipeline_table_rule_show_help);
6288 if ((n_tokens == 5) &&
6289 (strcmp(tokens[2], "rule") == 0) &&
6290 (strcmp(tokens[3], "stats") == 0) &&
6291 (strcmp(tokens[4], "read") == 0)) {
6292 snprintf(out, out_size, "\n%s\n",
6293 cmd_pipeline_table_rule_stats_read_help);
6297 if ((n_tokens == 5) &&
6298 (strcmp(tokens[2], "meter") == 0) &&
6299 (strcmp(tokens[3], "profile") == 0) &&
6300 (strcmp(tokens[4], "add") == 0)) {
6301 snprintf(out, out_size, "\n%s\n",
6302 cmd_pipeline_table_meter_profile_add_help);
6306 if ((n_tokens == 5) &&
6307 (strcmp(tokens[2], "meter") == 0) &&
6308 (strcmp(tokens[3], "profile") == 0) &&
6309 (strcmp(tokens[4], "delete") == 0)) {
6310 snprintf(out, out_size, "\n%s\n",
6311 cmd_pipeline_table_meter_profile_delete_help);
6315 if ((n_tokens == 5) &&
6316 (strcmp(tokens[2], "rule") == 0) &&
6317 (strcmp(tokens[3], "meter") == 0) &&
6318 (strcmp(tokens[4], "read") == 0)) {
6319 snprintf(out, out_size, "\n%s\n",
6320 cmd_pipeline_table_rule_meter_read_help);
6324 if ((n_tokens == 5) &&
6325 (strcmp(tokens[2], "rule") == 0) &&
6326 (strcmp(tokens[3], "ttl") == 0) &&
6327 (strcmp(tokens[4], "read") == 0)) {
6328 snprintf(out, out_size, "\n%s\n",
6329 cmd_pipeline_table_rule_ttl_read_help);
6333 if ((n_tokens == 5) &&
6334 (strcmp(tokens[2], "rule") == 0) &&
6335 (strcmp(tokens[3], "time") == 0) &&
6336 (strcmp(tokens[4], "read") == 0)) {
6337 snprintf(out, out_size, "\n%s\n",
6338 cmd_pipeline_table_rule_time_read_help);
6343 if ((n_tokens == 3) &&
6344 (strcmp(tokens[0], "thread") == 0) &&
6345 (strcmp(tokens[1], "pipeline") == 0)) {
6346 if (strcmp(tokens[2], "enable") == 0) {
6347 snprintf(out, out_size, "\n%s\n",
6348 cmd_thread_pipeline_enable_help);
6352 if (strcmp(tokens[2], "disable") == 0) {
6353 snprintf(out, out_size, "\n%s\n",
6354 cmd_thread_pipeline_disable_help);
6359 snprintf(out, out_size, "Invalid command\n");
6363 cli_process(char *in, char *out, size_t out_size)
6365 char *tokens[CMD_MAX_TOKENS];
6366 uint32_t n_tokens = RTE_DIM(tokens);
6372 status = parse_tokenize_string(in, tokens, &n_tokens);
6374 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
6381 if (strcmp(tokens[0], "help") == 0) {
6382 cmd_help(tokens, n_tokens, out, out_size);
6386 if (strcmp(tokens[0], "mempool") == 0) {
6387 cmd_mempool(tokens, n_tokens, out, out_size);
6391 if (strcmp(tokens[0], "link") == 0) {
6392 if (strcmp(tokens[1], "show") == 0) {
6393 cmd_link_show(tokens, n_tokens, out, out_size);
6397 cmd_link(tokens, n_tokens, out, out_size);
6401 if (strcmp(tokens[0], "swq") == 0) {
6402 cmd_swq(tokens, n_tokens, out, out_size);
6406 if (strcmp(tokens[0], "tmgr") == 0) {
6407 if ((n_tokens >= 3) &&
6408 (strcmp(tokens[1], "subport") == 0) &&
6409 (strcmp(tokens[2], "profile") == 0)) {
6410 cmd_tmgr_subport_profile(tokens, n_tokens,
6415 if ((n_tokens >= 3) &&
6416 (strcmp(tokens[1], "pipe") == 0) &&
6417 (strcmp(tokens[2], "profile") == 0)) {
6418 cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
6422 if ((n_tokens >= 5) &&
6423 (strcmp(tokens[2], "subport") == 0) &&
6424 (strcmp(tokens[4], "profile") == 0)) {
6425 cmd_tmgr_subport(tokens, n_tokens, out, out_size);
6429 if ((n_tokens >= 5) &&
6430 (strcmp(tokens[2], "subport") == 0) &&
6431 (strcmp(tokens[4], "pipe") == 0)) {
6432 cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
6436 cmd_tmgr(tokens, n_tokens, out, out_size);
6440 if (strcmp(tokens[0], "tap") == 0) {
6441 cmd_tap(tokens, n_tokens, out, out_size);
6445 if (strcmp(tokens[0], "kni") == 0) {
6446 cmd_kni(tokens, n_tokens, out, out_size);
6450 if (strcmp(tokens[0], "cryptodev") == 0) {
6451 cmd_cryptodev(tokens, n_tokens, out, out_size);
6455 if (strcmp(tokens[0], "port") == 0) {
6456 cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
6460 if (strcmp(tokens[0], "table") == 0) {
6461 cmd_table_action_profile(tokens, n_tokens, out, out_size);
6465 if (strcmp(tokens[0], "pipeline") == 0) {
6466 if ((n_tokens >= 3) &&
6467 (strcmp(tokens[2], "period") == 0)) {
6468 cmd_pipeline(tokens, n_tokens, out, out_size);
6472 if ((n_tokens >= 5) &&
6473 (strcmp(tokens[2], "port") == 0) &&
6474 (strcmp(tokens[3], "in") == 0) &&
6475 (strcmp(tokens[4], "bsz") == 0)) {
6476 cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
6480 if ((n_tokens >= 5) &&
6481 (strcmp(tokens[2], "port") == 0) &&
6482 (strcmp(tokens[3], "out") == 0) &&
6483 (strcmp(tokens[4], "bsz") == 0)) {
6484 cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
6488 if ((n_tokens >= 4) &&
6489 (strcmp(tokens[2], "table") == 0) &&
6490 (strcmp(tokens[3], "match") == 0)) {
6491 cmd_pipeline_table(tokens, n_tokens, out, out_size);
6495 if ((n_tokens >= 6) &&
6496 (strcmp(tokens[2], "port") == 0) &&
6497 (strcmp(tokens[3], "in") == 0) &&
6498 (strcmp(tokens[5], "table") == 0)) {
6499 cmd_pipeline_port_in_table(tokens, n_tokens,
6504 if ((n_tokens >= 6) &&
6505 (strcmp(tokens[2], "port") == 0) &&
6506 (strcmp(tokens[3], "in") == 0) &&
6507 (strcmp(tokens[5], "stats") == 0)) {
6508 cmd_pipeline_port_in_stats(tokens, n_tokens,
6513 if ((n_tokens >= 6) &&
6514 (strcmp(tokens[2], "port") == 0) &&
6515 (strcmp(tokens[3], "in") == 0) &&
6516 (strcmp(tokens[5], "enable") == 0)) {
6517 cmd_pipeline_port_in_enable(tokens, n_tokens,
6522 if ((n_tokens >= 6) &&
6523 (strcmp(tokens[2], "port") == 0) &&
6524 (strcmp(tokens[3], "in") == 0) &&
6525 (strcmp(tokens[5], "disable") == 0)) {
6526 cmd_pipeline_port_in_disable(tokens, n_tokens,
6531 if ((n_tokens >= 6) &&
6532 (strcmp(tokens[2], "port") == 0) &&
6533 (strcmp(tokens[3], "out") == 0) &&
6534 (strcmp(tokens[5], "stats") == 0)) {
6535 cmd_pipeline_port_out_stats(tokens, n_tokens,
6540 if ((n_tokens >= 5) &&
6541 (strcmp(tokens[2], "table") == 0) &&
6542 (strcmp(tokens[4], "stats") == 0)) {
6543 cmd_pipeline_table_stats(tokens, n_tokens,
6548 if ((n_tokens >= 7) &&
6549 (strcmp(tokens[2], "table") == 0) &&
6550 (strcmp(tokens[4], "rule") == 0) &&
6551 (strcmp(tokens[5], "add") == 0) &&
6552 (strcmp(tokens[6], "match") == 0)) {
6553 if ((n_tokens >= 8) &&
6554 (strcmp(tokens[7], "default") == 0)) {
6555 cmd_pipeline_table_rule_add_default(tokens,
6556 n_tokens, out, out_size);
6560 cmd_pipeline_table_rule_add(tokens, n_tokens,
6565 if ((n_tokens >= 7) &&
6566 (strcmp(tokens[2], "table") == 0) &&
6567 (strcmp(tokens[4], "rule") == 0) &&
6568 (strcmp(tokens[5], "add") == 0) &&
6569 (strcmp(tokens[6], "bulk") == 0)) {
6570 cmd_pipeline_table_rule_add_bulk(tokens,
6571 n_tokens, out, out_size);
6575 if ((n_tokens >= 7) &&
6576 (strcmp(tokens[2], "table") == 0) &&
6577 (strcmp(tokens[4], "rule") == 0) &&
6578 (strcmp(tokens[5], "delete") == 0) &&
6579 (strcmp(tokens[6], "match") == 0)) {
6580 if ((n_tokens >= 8) &&
6581 (strcmp(tokens[7], "default") == 0)) {
6582 cmd_pipeline_table_rule_delete_default(tokens,
6583 n_tokens, out, out_size);
6587 cmd_pipeline_table_rule_delete(tokens, n_tokens,
6592 if ((n_tokens >= 6) &&
6593 (strcmp(tokens[2], "table") == 0) &&
6594 (strcmp(tokens[4], "rule") == 0) &&
6595 (strcmp(tokens[5], "show") == 0)) {
6596 cmd_pipeline_table_rule_show(tokens, n_tokens,
6601 if ((n_tokens >= 7) &&
6602 (strcmp(tokens[2], "table") == 0) &&
6603 (strcmp(tokens[4], "rule") == 0) &&
6604 (strcmp(tokens[5], "read") == 0) &&
6605 (strcmp(tokens[6], "stats") == 0)) {
6606 cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
6611 if ((n_tokens >= 8) &&
6612 (strcmp(tokens[2], "table") == 0) &&
6613 (strcmp(tokens[4], "meter") == 0) &&
6614 (strcmp(tokens[5], "profile") == 0) &&
6615 (strcmp(tokens[7], "add") == 0)) {
6616 cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
6621 if ((n_tokens >= 8) &&
6622 (strcmp(tokens[2], "table") == 0) &&
6623 (strcmp(tokens[4], "meter") == 0) &&
6624 (strcmp(tokens[5], "profile") == 0) &&
6625 (strcmp(tokens[7], "delete") == 0)) {
6626 cmd_pipeline_table_meter_profile_delete(tokens,
6627 n_tokens, out, out_size);
6631 if ((n_tokens >= 7) &&
6632 (strcmp(tokens[2], "table") == 0) &&
6633 (strcmp(tokens[4], "rule") == 0) &&
6634 (strcmp(tokens[5], "read") == 0) &&
6635 (strcmp(tokens[6], "meter") == 0)) {
6636 cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
6641 if ((n_tokens >= 5) &&
6642 (strcmp(tokens[2], "table") == 0) &&
6643 (strcmp(tokens[4], "dscp") == 0)) {
6644 cmd_pipeline_table_dscp(tokens, n_tokens,
6649 if ((n_tokens >= 7) &&
6650 (strcmp(tokens[2], "table") == 0) &&
6651 (strcmp(tokens[4], "rule") == 0) &&
6652 (strcmp(tokens[5], "read") == 0) &&
6653 (strcmp(tokens[6], "ttl") == 0)) {
6654 cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
6659 if ((n_tokens >= 7) &&
6660 (strcmp(tokens[2], "table") == 0) &&
6661 (strcmp(tokens[4], "rule") == 0) &&
6662 (strcmp(tokens[5], "read") == 0) &&
6663 (strcmp(tokens[6], "time") == 0)) {
6664 cmd_pipeline_table_rule_time_read(tokens, n_tokens,
6670 if (strcmp(tokens[0], "thread") == 0) {
6671 if ((n_tokens >= 5) &&
6672 (strcmp(tokens[4], "enable") == 0)) {
6673 cmd_thread_pipeline_enable(tokens, n_tokens,
6678 if ((n_tokens >= 5) &&
6679 (strcmp(tokens[4], "disable") == 0)) {
6680 cmd_thread_pipeline_disable(tokens, n_tokens,
6686 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
6690 cli_script_process(const char *file_name,
6691 size_t msg_in_len_max,
6692 size_t msg_out_len_max)
6694 char *msg_in = NULL, *msg_out = NULL;
6697 /* Check input arguments */
6698 if ((file_name == NULL) ||
6699 (strlen(file_name) == 0) ||
6700 (msg_in_len_max == 0) ||
6701 (msg_out_len_max == 0))
6704 msg_in = malloc(msg_in_len_max + 1);
6705 msg_out = malloc(msg_out_len_max + 1);
6706 if ((msg_in == NULL) ||
6707 (msg_out == NULL)) {
6713 /* Open input file */
6714 f = fopen(file_name, "r");
6723 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
6726 printf("%s", msg_in);
6733 if (strlen(msg_out))
6734 printf("%s", msg_out);
6745 cli_rule_file_process(const char *file_name,
6746 size_t line_len_max,
6747 struct table_rule_list **rule_list,
6749 uint32_t *line_number,
6753 struct table_rule_list *list = NULL;
6756 uint32_t rule_id = 0, line_id = 0;
6759 /* Check input arguments */
6760 if ((file_name == NULL) ||
6761 (strlen(file_name) == 0) ||
6762 (line_len_max == 0) ||
6763 (rule_list == NULL) ||
6764 (n_rules == NULL) ||
6765 (line_number == NULL) ||
6768 goto cli_rule_file_process_free;
6771 /* Memory allocation */
6772 list = malloc(sizeof(struct table_rule_list));
6775 goto cli_rule_file_process_free;
6780 line = malloc(line_len_max + 1);
6783 goto cli_rule_file_process_free;
6787 f = fopen(file_name, "r");
6790 goto cli_rule_file_process_free;
6794 for (line_id = 1, rule_id = 0; ; line_id++) {
6795 char *tokens[CMD_MAX_TOKENS];
6796 struct table_rule *rule = NULL;
6797 uint32_t n_tokens, n_tokens_parsed, t0;
6799 /* Read next line from file. */
6800 if (fgets(line, line_len_max + 1, f) == NULL)
6804 if (is_comment(line))
6808 n_tokens = RTE_DIM(tokens);
6809 status = parse_tokenize_string(line, tokens, &n_tokens);
6812 goto cli_rule_file_process_free;
6820 /* Rule alloc and insert. */
6821 rule = calloc(1, sizeof(struct table_rule));
6824 goto cli_rule_file_process_free;
6827 TAILQ_INSERT_TAIL(list, rule, node);
6830 n_tokens_parsed = parse_match(tokens + t0,
6835 if (n_tokens_parsed == 0) {
6837 goto cli_rule_file_process_free;
6839 t0 += n_tokens_parsed;
6842 n_tokens_parsed = parse_table_action(tokens + t0,
6847 if (n_tokens_parsed == 0) {
6849 goto cli_rule_file_process_free;
6851 t0 += n_tokens_parsed;
6853 /* Line completed. */
6854 if (t0 < n_tokens) {
6856 goto cli_rule_file_process_free;
6859 /* Increment rule count */
6871 *line_number = line_id;
6874 cli_rule_file_process_free:
6875 if (rule_list != NULL)
6878 if (n_rules != NULL)
6881 if (line_number != NULL)
6882 *line_number = line_id;
6886 struct table_rule *rule;
6888 rule = TAILQ_FIRST(list);
6892 TAILQ_REMOVE(list, rule, node);