1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_cycles.h>
12 #include <rte_ethdev.h>
16 #include "cryptodev.h"
27 #ifndef CMD_MAX_TOKENS
28 #define CMD_MAX_TOKENS 256
31 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
32 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
33 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
34 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
35 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
36 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
37 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
38 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
39 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
40 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
41 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
46 if ((strlen(in) && index("!#%;", in[0])) ||
47 (strncmp(in, "//", 2) == 0) ||
48 (strncmp(in, "--", 2) == 0))
54 static const char cmd_mempool_help[] =
55 "mempool <mempool_name>\n"
56 " buffer <buffer_size>\n"
58 " cache <cache_size>\n"
62 cmd_mempool(char **tokens,
67 struct mempool_params p;
69 struct mempool *mempool;
72 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
78 if (strcmp(tokens[2], "buffer") != 0) {
79 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
83 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
84 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
88 if (strcmp(tokens[4], "pool") != 0) {
89 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
93 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
94 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
98 if (strcmp(tokens[6], "cache") != 0) {
99 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
103 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
104 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
108 if (strcmp(tokens[8], "cpu") != 0) {
109 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
113 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
114 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
118 mempool = mempool_create(name, &p);
119 if (mempool == NULL) {
120 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
125 static const char cmd_link_help[] =
127 " dev <device_name> | port <port_id>\n"
128 " rxq <n_queues> <queue_size> <mempool_name>\n"
129 " txq <n_queues> <queue_size>\n"
130 " promiscuous on | off\n"
131 " [rss <qid_0> ... <qid_n>]\n";
134 cmd_link(char **tokens,
139 struct link_params p;
140 struct link_params_rss rss;
144 memset(&p, 0, sizeof(p));
146 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
147 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
152 if (strcmp(tokens[2], "dev") == 0)
153 p.dev_name = tokens[3];
154 else if (strcmp(tokens[2], "port") == 0) {
157 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
158 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
162 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
166 if (strcmp(tokens[4], "rxq") != 0) {
167 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
171 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
172 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
175 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
176 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
180 p.rx.mempool_name = tokens[7];
182 if (strcmp(tokens[8], "txq") != 0) {
183 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
187 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
188 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
192 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
193 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
197 if (strcmp(tokens[11], "promiscuous") != 0) {
198 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
202 if (strcmp(tokens[12], "on") == 0)
204 else if (strcmp(tokens[12], "off") == 0)
207 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
214 uint32_t queue_id, i;
216 if (strcmp(tokens[13], "rss") != 0) {
217 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
224 for (i = 14; i < n_tokens; i++) {
225 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
226 snprintf(out, out_size, MSG_ARG_INVALID,
231 rss.queue_id[rss.n_queues] = queue_id;
236 link = link_create(name, &p);
238 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
243 /* Print the link stats and info */
245 print_link_info(struct link *link, char *out, size_t out_size)
247 struct rte_eth_stats stats;
248 struct rte_ether_addr mac_addr;
249 struct rte_eth_link eth_link;
252 memset(&stats, 0, sizeof(stats));
253 rte_eth_stats_get(link->port_id, &stats);
255 rte_eth_macaddr_get(link->port_id, &mac_addr);
256 rte_eth_link_get(link->port_id, ð_link);
257 rte_eth_dev_get_mtu(link->port_id, &mtu);
259 snprintf(out, out_size,
261 "%s: flags=<%s> mtu %u\n"
262 "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
263 "\tport# %u speed %u Mbps\n"
264 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
265 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
266 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
267 "\tTX errors %" PRIu64"\n",
269 eth_link.link_status == 0 ? "DOWN" : "UP",
271 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
272 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
273 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
289 * link show [<link_name>]
292 cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
297 if (n_tokens != 2 && n_tokens != 3) {
298 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
303 link = link_next(NULL);
305 while (link != NULL) {
306 out_size = out_size - strlen(out);
307 out = &out[strlen(out)];
309 print_link_info(link, out, out_size);
310 link = link_next(link);
313 out_size = out_size - strlen(out);
314 out = &out[strlen(out)];
316 link_name = tokens[2];
317 link = link_find(link_name);
320 snprintf(out, out_size, MSG_ARG_INVALID,
321 "Link does not exist");
324 print_link_info(link, out, out_size);
328 static const char cmd_swq_help[] =
334 cmd_swq(char **tokens,
344 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
350 if (strcmp(tokens[2], "size") != 0) {
351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
355 if (parser_read_uint32(&p.size, tokens[3]) != 0) {
356 snprintf(out, out_size, MSG_ARG_INVALID, "size");
360 if (strcmp(tokens[4], "cpu") != 0) {
361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
365 if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
366 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
370 swq = swq_create(name, &p);
372 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
377 static const char cmd_tmgr_subport_profile_help[] =
378 "tmgr subport profile\n"
379 " <tb_rate> <tb_size>\n"
380 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
381 " <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
382 " <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
386 cmd_tmgr_subport_profile(char **tokens,
391 struct rte_sched_subport_params p;
394 if (n_tokens != 19) {
395 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
399 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
400 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
404 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
405 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
409 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
410 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
411 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
415 if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) {
416 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
420 status = tmgr_subport_profile_add(&p);
422 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
427 static const char cmd_tmgr_pipe_profile_help[] =
428 "tmgr pipe profile\n"
429 " <tb_rate> <tb_size>\n"
430 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
431 " <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
432 " <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
435 " <wrr_weight0..3>\n";
438 cmd_tmgr_pipe_profile(char **tokens,
443 struct rte_sched_pipe_params p;
446 if (n_tokens != 24) {
447 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
451 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
452 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
456 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
457 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
461 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
462 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
463 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
467 if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) {
468 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
472 #ifdef RTE_SCHED_SUBPORT_TC_OV
473 if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
474 snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
479 for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
480 if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
481 snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
485 status = tmgr_pipe_profile_add(&p);
487 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
492 static const char cmd_tmgr_help[] =
495 " spp <n_subports_per_port>\n"
496 " pps <n_pipes_per_subport>\n"
497 " qsize <qsize_tc0> <qsize_tc1> <qsize_tc2>"
498 " <qsize_tc3> <qsize_tc4> <qsize_tc5> <qsize_tc6>"
499 " <qsize_tc7> <qsize_tc8> <qsize_tc9> <qsize_tc10>"
500 " <qsize_tc11> <qsize_tc12>\n"
501 " fo <frame_overhead>\n"
506 cmd_tmgr(char **tokens,
511 struct tmgr_port_params p;
513 struct tmgr_port *tmgr_port;
516 if (n_tokens != 28) {
517 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
523 if (strcmp(tokens[2], "rate") != 0) {
524 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
528 if (parser_read_uint32(&p.rate, tokens[3]) != 0) {
529 snprintf(out, out_size, MSG_ARG_INVALID, "rate");
533 if (strcmp(tokens[4], "spp") != 0) {
534 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
538 if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
539 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
543 if (strcmp(tokens[6], "pps") != 0) {
544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
548 if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
549 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
553 if (strcmp(tokens[8], "qsize") != 0) {
554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize");
558 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
559 if (parser_read_uint16(&p.qsize[i], tokens[9 + i]) != 0) {
560 snprintf(out, out_size, MSG_ARG_INVALID, "qsize");
564 if (strcmp(tokens[22], "fo") != 0) {
565 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
569 if (parser_read_uint32(&p.frame_overhead, tokens[23]) != 0) {
570 snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
574 if (strcmp(tokens[24], "mtu") != 0) {
575 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
579 if (parser_read_uint32(&p.mtu, tokens[25]) != 0) {
580 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
584 if (strcmp(tokens[26], "cpu") != 0) {
585 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
589 if (parser_read_uint32(&p.cpu_id, tokens[27]) != 0) {
590 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
594 tmgr_port = tmgr_port_create(name, &p);
595 if (tmgr_port == NULL) {
596 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
601 static const char cmd_tmgr_subport_help[] =
602 "tmgr <tmgr_name> subport <subport_id>\n"
603 " profile <subport_profile_id>\n";
606 cmd_tmgr_subport(char **tokens,
611 uint32_t subport_id, subport_profile_id;
616 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
622 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
623 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
627 if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
628 snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
632 status = tmgr_subport_config(name, subport_id, subport_profile_id);
634 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
640 static const char cmd_tmgr_subport_pipe_help[] =
641 "tmgr <tmgr_name> subport <subport_id> pipe\n"
642 " from <pipe_id_first> to <pipe_id_last>\n"
643 " profile <pipe_profile_id>\n";
646 cmd_tmgr_subport_pipe(char **tokens,
651 uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
655 if (n_tokens != 11) {
656 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
662 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
663 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
667 if (strcmp(tokens[4], "pipe") != 0) {
668 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
672 if (strcmp(tokens[5], "from") != 0) {
673 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
677 if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
678 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
682 if (strcmp(tokens[7], "to") != 0) {
683 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
687 if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
688 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
692 if (strcmp(tokens[9], "profile") != 0) {
693 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
697 if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
698 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
702 status = tmgr_pipe_config(name, subport_id, pipe_id_first,
703 pipe_id_last, pipe_profile_id);
705 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
711 static const char cmd_tap_help[] =
715 cmd_tap(char **tokens,
724 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
730 tap = tap_create(name);
732 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
737 static const char cmd_kni_help[] =
739 " link <link_name>\n"
740 " mempool <mempool_name>\n"
741 " [thread <thread_id>]\n";
744 cmd_kni(char **tokens,
753 memset(&p, 0, sizeof(p));
754 if ((n_tokens != 6) && (n_tokens != 8)) {
755 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
761 if (strcmp(tokens[2], "link") != 0) {
762 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link");
766 p.link_name = tokens[3];
768 if (strcmp(tokens[4], "mempool") != 0) {
769 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool");
773 p.mempool_name = tokens[5];
776 if (strcmp(tokens[6], "thread") != 0) {
777 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread");
781 if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) {
782 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
790 kni = kni_create(name, &p);
792 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
797 static const char cmd_cryptodev_help[] =
798 "cryptodev <cryptodev_name>\n"
799 " dev <device_name> | dev_id <device_id>\n"
800 " queue <n_queues> <queue_size>\n"
801 " max_sessions <n_sessions>";
804 cmd_cryptodev(char **tokens,
809 struct cryptodev_params params;
812 memset(¶ms, 0, sizeof(params));
814 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
820 if (strcmp(tokens[2], "dev") == 0)
821 params.dev_name = tokens[3];
822 else if (strcmp(tokens[2], "dev_id") == 0) {
823 if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
824 snprintf(out, out_size, MSG_ARG_INVALID,
829 snprintf(out, out_size, MSG_ARG_INVALID,
834 if (strcmp(tokens[4], "queue")) {
835 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
840 if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
841 snprintf(out, out_size, MSG_ARG_INVALID,
846 if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
847 snprintf(out, out_size, MSG_ARG_INVALID,
852 if (strcmp(tokens[7], "max_sessions")) {
853 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
858 if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
859 snprintf(out, out_size, MSG_ARG_INVALID,
864 if (cryptodev_create(name, ¶ms) == NULL) {
865 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
870 static const char cmd_port_in_action_profile_help[] =
871 "port in action profile <profile_name>\n"
872 " [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
873 " [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
876 cmd_port_in_action_profile(char **tokens,
881 struct port_in_action_profile_params p;
882 struct port_in_action_profile *ap;
886 memset(&p, 0, sizeof(p));
889 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
893 if (strcmp(tokens[1], "in") != 0) {
894 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
898 if (strcmp(tokens[2], "action") != 0) {
899 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
903 if (strcmp(tokens[3], "profile") != 0) {
904 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
912 if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
915 if (n_tokens < t0 + 10) {
916 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
920 if (strcmp(tokens[t0 + 1], "match") == 0)
921 p.fltr.filter_on_match = 1;
922 else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
923 p.fltr.filter_on_match = 0;
925 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
929 if (strcmp(tokens[t0 + 2], "offset") != 0) {
930 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
934 if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
935 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
939 if (strcmp(tokens[t0 + 4], "mask") != 0) {
940 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
944 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
945 if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
946 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
947 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
951 if (strcmp(tokens[t0 + 6], "key") != 0) {
952 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
956 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
957 if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
958 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
959 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
963 if (strcmp(tokens[t0 + 8], "port") != 0) {
964 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
968 if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
969 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
973 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
977 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
980 if (n_tokens < t0 + 22) {
981 snprintf(out, out_size, MSG_ARG_MISMATCH,
982 "port in action profile balance");
986 if (strcmp(tokens[t0 + 1], "offset") != 0) {
987 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
991 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
992 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
996 if (strcmp(tokens[t0 + 3], "mask") != 0) {
997 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1001 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1002 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1003 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1007 if (strcmp(tokens[t0 + 5], "port") != 0) {
1008 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1012 for (i = 0; i < 16; i++)
1013 if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
1014 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1018 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
1022 if (t0 < n_tokens) {
1023 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1027 ap = port_in_action_profile_create(name, &p);
1029 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1035 static const char cmd_table_action_profile_help[] =
1036 "table action profile <profile_name>\n"
1038 " offset <ip_offset>\n"
1040 " [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
1041 " [meter srtcm | trtcm\n"
1043 " stats none | pkts | bytes | both]\n"
1044 " [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
1045 " [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
1046 " vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
1048 " proto udp | tcp]\n"
1049 " [ttl drop | fwd\n"
1050 " stats none | pkts]\n"
1051 " [stats pkts | bytes | both]\n"
1053 " [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
1058 cmd_table_action_profile(char **tokens,
1063 struct table_action_profile_params p;
1064 struct table_action_profile *ap;
1068 memset(&p, 0, sizeof(p));
1071 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1075 if (strcmp(tokens[1], "action") != 0) {
1076 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1080 if (strcmp(tokens[2], "profile") != 0) {
1081 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1087 if (strcmp(tokens[4], "ipv4") == 0)
1088 p.common.ip_version = 1;
1089 else if (strcmp(tokens[4], "ipv6") == 0)
1090 p.common.ip_version = 0;
1092 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1096 if (strcmp(tokens[5], "offset") != 0) {
1097 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1101 if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
1102 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1106 if (strcmp(tokens[7], "fwd") != 0) {
1107 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1111 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1114 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
1115 if (n_tokens < t0 + 7) {
1116 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1120 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1121 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1125 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
1126 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1130 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1131 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1135 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1136 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1137 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1141 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1142 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1146 if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
1147 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1151 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1155 if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
1156 if (n_tokens < t0 + 6) {
1157 snprintf(out, out_size, MSG_ARG_MISMATCH,
1158 "table action profile meter");
1162 if (strcmp(tokens[t0 + 1], "srtcm") == 0)
1163 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1164 else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
1165 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1167 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1172 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1173 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1177 if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
1178 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1182 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1183 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1187 if (strcmp(tokens[t0 + 5], "none") == 0) {
1188 p.mtr.n_packets_enabled = 0;
1189 p.mtr.n_bytes_enabled = 0;
1190 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1191 p.mtr.n_packets_enabled = 1;
1192 p.mtr.n_bytes_enabled = 0;
1193 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1194 p.mtr.n_packets_enabled = 0;
1195 p.mtr.n_bytes_enabled = 1;
1196 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1197 p.mtr.n_packets_enabled = 1;
1198 p.mtr.n_bytes_enabled = 1;
1200 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1201 "none or pkts or bytes or both");
1205 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1209 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
1210 if (n_tokens < t0 + 5) {
1211 snprintf(out, out_size, MSG_ARG_MISMATCH,
1212 "table action profile tm");
1216 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1217 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1221 if (parser_read_uint32(&p.tm.n_subports_per_port,
1222 tokens[t0 + 2]) != 0) {
1223 snprintf(out, out_size, MSG_ARG_INVALID,
1224 "n_subports_per_port");
1228 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1229 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1233 if (parser_read_uint32(&p.tm.n_pipes_per_subport,
1234 tokens[t0 + 4]) != 0) {
1235 snprintf(out, out_size, MSG_ARG_INVALID,
1236 "n_pipes_per_subport");
1240 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1244 if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
1245 uint32_t n_extra_tokens = 0;
1247 if (n_tokens < t0 + 2) {
1248 snprintf(out, out_size, MSG_ARG_MISMATCH,
1249 "action profile encap");
1253 if (strcmp(tokens[t0 + 1], "ether") == 0)
1254 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1255 else if (strcmp(tokens[t0 + 1], "vlan") == 0)
1256 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1257 else if (strcmp(tokens[t0 + 1], "qinq") == 0)
1258 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1259 else if (strcmp(tokens[t0 + 1], "mpls") == 0)
1260 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1261 else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
1262 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1263 else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
1264 if (n_tokens < t0 + 2 + 5) {
1265 snprintf(out, out_size, MSG_ARG_MISMATCH,
1266 "action profile encap vxlan");
1270 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1271 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1276 if (parser_read_uint32(&p.encap.vxlan.data_offset,
1277 tokens[t0 + 2 + 1]) != 0) {
1278 snprintf(out, out_size, MSG_ARG_INVALID,
1279 "vxlan: ether_offset");
1283 if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
1284 p.encap.vxlan.ip_version = 1;
1285 else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
1286 p.encap.vxlan.ip_version = 0;
1288 snprintf(out, out_size, MSG_ARG_INVALID,
1289 "vxlan: ipv4 or ipv6");
1293 if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
1294 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1299 if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
1300 p.encap.vxlan.vlan = 1;
1301 else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
1302 p.encap.vxlan.vlan = 0;
1304 snprintf(out, out_size, MSG_ARG_INVALID,
1305 "vxlan: on or off");
1309 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
1311 } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
1312 p.encap.encap_mask =
1313 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
1315 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1319 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1320 t0 += 2 + n_extra_tokens;
1323 if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
1324 if (n_tokens < t0 + 4) {
1325 snprintf(out, out_size, MSG_ARG_MISMATCH,
1326 "table action profile nat");
1330 if (strcmp(tokens[t0 + 1], "src") == 0)
1331 p.nat.source_nat = 1;
1332 else if (strcmp(tokens[t0 + 1], "dst") == 0)
1333 p.nat.source_nat = 0;
1335 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1340 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1341 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1345 if (strcmp(tokens[t0 + 3], "tcp") == 0)
1347 else if (strcmp(tokens[t0 + 3], "udp") == 0)
1350 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1355 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1359 if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
1360 if (n_tokens < t0 + 4) {
1361 snprintf(out, out_size, MSG_ARG_MISMATCH,
1362 "table action profile ttl");
1366 if (strcmp(tokens[t0 + 1], "drop") == 0)
1368 else if (strcmp(tokens[t0 + 1], "fwd") == 0)
1371 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1376 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1377 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1381 if (strcmp(tokens[t0 + 3], "none") == 0)
1382 p.ttl.n_packets_enabled = 0;
1383 else if (strcmp(tokens[t0 + 3], "pkts") == 0)
1384 p.ttl.n_packets_enabled = 1;
1386 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1391 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1395 if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
1396 if (n_tokens < t0 + 2) {
1397 snprintf(out, out_size, MSG_ARG_MISMATCH,
1398 "table action profile stats");
1402 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1403 p.stats.n_packets_enabled = 1;
1404 p.stats.n_bytes_enabled = 0;
1405 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1406 p.stats.n_packets_enabled = 0;
1407 p.stats.n_bytes_enabled = 1;
1408 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1409 p.stats.n_packets_enabled = 1;
1410 p.stats.n_bytes_enabled = 1;
1412 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1413 "pkts or bytes or both");
1417 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1421 if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
1422 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1426 if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
1427 struct cryptodev *cryptodev;
1429 if (n_tokens < t0 + 5 ||
1430 strcmp(tokens[t0 + 1], "dev") ||
1431 strcmp(tokens[t0 + 3], "offset")) {
1432 snprintf(out, out_size, MSG_ARG_MISMATCH,
1433 "table action profile sym_crypto");
1437 cryptodev = cryptodev_find(tokens[t0 + 2]);
1438 if (cryptodev == NULL) {
1439 snprintf(out, out_size, MSG_ARG_INVALID,
1440 "table action profile sym_crypto");
1444 p.sym_crypto.cryptodev_id = cryptodev->dev_id;
1446 if (parser_read_uint32(&p.sym_crypto.op_offset,
1447 tokens[t0 + 4]) != 0) {
1448 snprintf(out, out_size, MSG_ARG_INVALID,
1449 "table action profile sym_crypto");
1453 p.sym_crypto.mp_create = cryptodev->mp_create;
1454 p.sym_crypto.mp_init = cryptodev->mp_init;
1456 p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
1461 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
1462 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1466 if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
1467 p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
1471 if (t0 < n_tokens) {
1472 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1476 ap = table_action_profile_create(name, &p);
1478 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1483 static const char cmd_pipeline_help[] =
1484 "pipeline <pipeline_name>\n"
1485 " period <timer_period_ms>\n"
1486 " offset_port_id <offset_port_id>\n"
1490 cmd_pipeline(char **tokens,
1495 struct pipeline_params p;
1497 struct pipeline *pipeline;
1499 if (n_tokens != 8) {
1500 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1506 if (strcmp(tokens[2], "period") != 0) {
1507 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1511 if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
1512 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1516 if (strcmp(tokens[4], "offset_port_id") != 0) {
1517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1521 if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
1522 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1526 if (strcmp(tokens[6], "cpu") != 0) {
1527 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
1531 if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
1532 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
1536 pipeline = pipeline_create(name, &p);
1537 if (pipeline == NULL) {
1538 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1543 static const char cmd_pipeline_port_in_help[] =
1544 "pipeline <pipeline_name> port in\n"
1545 " bsz <burst_size>\n"
1546 " link <link_name> rxq <queue_id>\n"
1547 " | swq <swq_name>\n"
1548 " | tmgr <tmgr_name>\n"
1549 " | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
1550 " | kni <kni_name>\n"
1551 " | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
1552 " | cryptodev <cryptodev_name> rxq <queue_id>\n"
1553 " [action <port_in_action_profile_name>]\n"
1557 cmd_pipeline_port_in(char **tokens,
1562 struct port_in_params p;
1563 char *pipeline_name;
1565 int enabled, status;
1568 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1572 pipeline_name = tokens[1];
1574 if (strcmp(tokens[2], "port") != 0) {
1575 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1579 if (strcmp(tokens[3], "in") != 0) {
1580 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1584 if (strcmp(tokens[4], "bsz") != 0) {
1585 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1589 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1590 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1596 if (strcmp(tokens[t0], "link") == 0) {
1597 if (n_tokens < t0 + 4) {
1598 snprintf(out, out_size, MSG_ARG_MISMATCH,
1599 "pipeline port in link");
1603 p.type = PORT_IN_RXQ;
1605 p.dev_name = tokens[t0 + 1];
1607 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1608 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1612 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1613 snprintf(out, out_size, MSG_ARG_INVALID,
1618 } else if (strcmp(tokens[t0], "swq") == 0) {
1619 if (n_tokens < t0 + 2) {
1620 snprintf(out, out_size, MSG_ARG_MISMATCH,
1621 "pipeline port in swq");
1625 p.type = PORT_IN_SWQ;
1627 p.dev_name = tokens[t0 + 1];
1630 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1631 if (n_tokens < t0 + 2) {
1632 snprintf(out, out_size, MSG_ARG_MISMATCH,
1633 "pipeline port in tmgr");
1637 p.type = PORT_IN_TMGR;
1639 p.dev_name = tokens[t0 + 1];
1642 } else if (strcmp(tokens[t0], "tap") == 0) {
1643 if (n_tokens < t0 + 6) {
1644 snprintf(out, out_size, MSG_ARG_MISMATCH,
1645 "pipeline port in tap");
1649 p.type = PORT_IN_TAP;
1651 p.dev_name = tokens[t0 + 1];
1653 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1654 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1659 p.tap.mempool_name = tokens[t0 + 3];
1661 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1662 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1667 if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
1668 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1673 } else if (strcmp(tokens[t0], "kni") == 0) {
1674 if (n_tokens < t0 + 2) {
1675 snprintf(out, out_size, MSG_ARG_MISMATCH,
1676 "pipeline port in kni");
1680 p.type = PORT_IN_KNI;
1682 p.dev_name = tokens[t0 + 1];
1685 } else if (strcmp(tokens[t0], "source") == 0) {
1686 if (n_tokens < t0 + 6) {
1687 snprintf(out, out_size, MSG_ARG_MISMATCH,
1688 "pipeline port in source");
1692 p.type = PORT_IN_SOURCE;
1696 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1697 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1702 p.source.mempool_name = tokens[t0 + 2];
1704 if (strcmp(tokens[t0 + 3], "file") != 0) {
1705 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1710 p.source.file_name = tokens[t0 + 4];
1712 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1713 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1718 if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
1719 snprintf(out, out_size, MSG_ARG_INVALID,
1725 } else if (strcmp(tokens[t0], "cryptodev") == 0) {
1726 if (n_tokens < t0 + 3) {
1727 snprintf(out, out_size, MSG_ARG_MISMATCH,
1728 "pipeline port in cryptodev");
1732 p.type = PORT_IN_CRYPTODEV;
1734 p.dev_name = tokens[t0 + 1];
1735 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1736 snprintf(out, out_size, MSG_ARG_INVALID,
1741 p.cryptodev.arg_callback = NULL;
1742 p.cryptodev.f_callback = NULL;
1746 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1750 p.action_profile_name = NULL;
1751 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
1752 if (n_tokens < t0 + 2) {
1753 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1757 p.action_profile_name = tokens[t0 + 1];
1763 if ((n_tokens > t0) &&
1764 (strcmp(tokens[t0], "disabled") == 0)) {
1770 if (n_tokens != t0) {
1771 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1775 status = pipeline_port_in_create(pipeline_name,
1778 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1783 static const char cmd_pipeline_port_out_help[] =
1784 "pipeline <pipeline_name> port out\n"
1785 " bsz <burst_size>\n"
1786 " link <link_name> txq <txq_id>\n"
1787 " | swq <swq_name>\n"
1788 " | tmgr <tmgr_name>\n"
1789 " | tap <tap_name>\n"
1790 " | kni <kni_name>\n"
1791 " | sink [file <file_name> pkts <max_n_pkts>]\n"
1792 " | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
1795 cmd_pipeline_port_out(char **tokens,
1800 struct port_out_params p;
1801 char *pipeline_name;
1804 memset(&p, 0, sizeof(p));
1807 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1811 pipeline_name = tokens[1];
1813 if (strcmp(tokens[2], "port") != 0) {
1814 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1818 if (strcmp(tokens[3], "out") != 0) {
1819 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1823 if (strcmp(tokens[4], "bsz") != 0) {
1824 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1828 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1829 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1833 if (strcmp(tokens[6], "link") == 0) {
1834 if (n_tokens != 10) {
1835 snprintf(out, out_size, MSG_ARG_MISMATCH,
1836 "pipeline port out link");
1840 p.type = PORT_OUT_TXQ;
1842 p.dev_name = tokens[7];
1844 if (strcmp(tokens[8], "txq") != 0) {
1845 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1849 if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
1850 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1853 } else if (strcmp(tokens[6], "swq") == 0) {
1854 if (n_tokens != 8) {
1855 snprintf(out, out_size, MSG_ARG_MISMATCH,
1856 "pipeline port out swq");
1860 p.type = PORT_OUT_SWQ;
1862 p.dev_name = tokens[7];
1863 } else if (strcmp(tokens[6], "tmgr") == 0) {
1864 if (n_tokens != 8) {
1865 snprintf(out, out_size, MSG_ARG_MISMATCH,
1866 "pipeline port out tmgr");
1870 p.type = PORT_OUT_TMGR;
1872 p.dev_name = tokens[7];
1873 } else if (strcmp(tokens[6], "tap") == 0) {
1874 if (n_tokens != 8) {
1875 snprintf(out, out_size, MSG_ARG_MISMATCH,
1876 "pipeline port out tap");
1880 p.type = PORT_OUT_TAP;
1882 p.dev_name = tokens[7];
1883 } else if (strcmp(tokens[6], "kni") == 0) {
1884 if (n_tokens != 8) {
1885 snprintf(out, out_size, MSG_ARG_MISMATCH,
1886 "pipeline port out kni");
1890 p.type = PORT_OUT_KNI;
1892 p.dev_name = tokens[7];
1893 } else if (strcmp(tokens[6], "sink") == 0) {
1894 if ((n_tokens != 7) && (n_tokens != 11)) {
1895 snprintf(out, out_size, MSG_ARG_MISMATCH,
1896 "pipeline port out sink");
1900 p.type = PORT_OUT_SINK;
1904 if (n_tokens == 7) {
1905 p.sink.file_name = NULL;
1906 p.sink.max_n_pkts = 0;
1908 if (strcmp(tokens[7], "file") != 0) {
1909 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1914 p.sink.file_name = tokens[8];
1916 if (strcmp(tokens[9], "pkts") != 0) {
1917 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1921 if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
1922 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1927 } else if (strcmp(tokens[6], "cryptodev") == 0) {
1928 if (n_tokens != 12) {
1929 snprintf(out, out_size, MSG_ARG_MISMATCH,
1930 "pipeline port out cryptodev");
1934 p.type = PORT_OUT_CRYPTODEV;
1936 p.dev_name = tokens[7];
1938 if (strcmp(tokens[8], "txq")) {
1939 snprintf(out, out_size, MSG_ARG_MISMATCH,
1940 "pipeline port out cryptodev");
1944 if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
1946 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1950 if (strcmp(tokens[10], "offset")) {
1951 snprintf(out, out_size, MSG_ARG_MISMATCH,
1952 "pipeline port out cryptodev");
1956 if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
1958 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1962 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1966 status = pipeline_port_out_create(pipeline_name, &p);
1968 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1973 static const char cmd_pipeline_table_help[] =
1974 "pipeline <pipeline_name> table\n"
1978 " offset <ip_header_offset>\n"
1981 " offset <key_offset>\n"
1986 " mask <key_mask>\n"
1987 " offset <key_offset>\n"
1988 " buckets <n_buckets>\n"
1992 " offset <ip_header_offset>\n"
1995 " [action <table_action_profile_name>]\n";
1998 cmd_pipeline_table(char **tokens,
2003 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
2004 struct table_params p;
2005 char *pipeline_name;
2010 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2014 pipeline_name = tokens[1];
2016 if (strcmp(tokens[2], "table") != 0) {
2017 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2021 if (strcmp(tokens[3], "match") != 0) {
2022 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2027 if (strcmp(tokens[t0], "acl") == 0) {
2028 if (n_tokens < t0 + 6) {
2029 snprintf(out, out_size, MSG_ARG_MISMATCH,
2030 "pipeline table acl");
2034 p.match_type = TABLE_ACL;
2036 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2037 p.match.acl.ip_version = 1;
2038 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2039 p.match.acl.ip_version = 0;
2041 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2046 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2047 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2051 if (parser_read_uint32(&p.match.acl.ip_header_offset,
2052 tokens[t0 + 3]) != 0) {
2053 snprintf(out, out_size, MSG_ARG_INVALID,
2054 "ip_header_offset");
2058 if (strcmp(tokens[t0 + 4], "size") != 0) {
2059 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2063 if (parser_read_uint32(&p.match.acl.n_rules,
2064 tokens[t0 + 5]) != 0) {
2065 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2070 } else if (strcmp(tokens[t0], "array") == 0) {
2071 if (n_tokens < t0 + 5) {
2072 snprintf(out, out_size, MSG_ARG_MISMATCH,
2073 "pipeline table array");
2077 p.match_type = TABLE_ARRAY;
2079 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2080 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2084 if (parser_read_uint32(&p.match.array.key_offset,
2085 tokens[t0 + 2]) != 0) {
2086 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2090 if (strcmp(tokens[t0 + 3], "size") != 0) {
2091 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2095 if (parser_read_uint32(&p.match.array.n_keys,
2096 tokens[t0 + 4]) != 0) {
2097 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2102 } else if (strcmp(tokens[t0], "hash") == 0) {
2103 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2105 if (n_tokens < t0 + 12) {
2106 snprintf(out, out_size, MSG_ARG_MISMATCH,
2107 "pipeline table hash");
2111 p.match_type = TABLE_HASH;
2113 if (strcmp(tokens[t0 + 1], "ext") == 0)
2114 p.match.hash.extendable_bucket = 1;
2115 else if (strcmp(tokens[t0 + 1], "lru") == 0)
2116 p.match.hash.extendable_bucket = 0;
2118 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2123 if (strcmp(tokens[t0 + 2], "key") != 0) {
2124 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2128 if ((parser_read_uint32(&p.match.hash.key_size,
2129 tokens[t0 + 3]) != 0) ||
2130 (p.match.hash.key_size == 0) ||
2131 (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
2132 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2136 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2137 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2141 if ((parse_hex_string(tokens[t0 + 5],
2142 key_mask, &key_mask_size) != 0) ||
2143 (key_mask_size != p.match.hash.key_size)) {
2144 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2147 p.match.hash.key_mask = key_mask;
2149 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2150 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2154 if (parser_read_uint32(&p.match.hash.key_offset,
2155 tokens[t0 + 7]) != 0) {
2156 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2160 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2161 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2165 if (parser_read_uint32(&p.match.hash.n_buckets,
2166 tokens[t0 + 9]) != 0) {
2167 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2171 if (strcmp(tokens[t0 + 10], "size") != 0) {
2172 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2176 if (parser_read_uint32(&p.match.hash.n_keys,
2177 tokens[t0 + 11]) != 0) {
2178 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2183 } else if (strcmp(tokens[t0], "lpm") == 0) {
2184 if (n_tokens < t0 + 6) {
2185 snprintf(out, out_size, MSG_ARG_MISMATCH,
2186 "pipeline table lpm");
2190 p.match_type = TABLE_LPM;
2192 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
2193 p.match.lpm.key_size = 4;
2194 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
2195 p.match.lpm.key_size = 16;
2197 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2202 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2203 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2207 if (parser_read_uint32(&p.match.lpm.key_offset,
2208 tokens[t0 + 3]) != 0) {
2209 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2213 if (strcmp(tokens[t0 + 4], "size") != 0) {
2214 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2218 if (parser_read_uint32(&p.match.lpm.n_rules,
2219 tokens[t0 + 5]) != 0) {
2220 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2225 } else if (strcmp(tokens[t0], "stub") == 0) {
2226 p.match_type = TABLE_STUB;
2230 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2234 p.action_profile_name = NULL;
2235 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
2236 if (n_tokens < t0 + 2) {
2237 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2241 p.action_profile_name = tokens[t0 + 1];
2246 if (n_tokens > t0) {
2247 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2251 status = pipeline_table_create(pipeline_name, &p);
2253 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2258 static const char cmd_pipeline_port_in_table_help[] =
2259 "pipeline <pipeline_name> port in <port_id> table <table_id>\n";
2262 cmd_pipeline_port_in_table(char **tokens,
2267 char *pipeline_name;
2268 uint32_t port_id, table_id;
2271 if (n_tokens != 7) {
2272 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2276 pipeline_name = tokens[1];
2278 if (strcmp(tokens[2], "port") != 0) {
2279 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2283 if (strcmp(tokens[3], "in") != 0) {
2284 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2288 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2289 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2293 if (strcmp(tokens[5], "table") != 0) {
2294 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2298 if (parser_read_uint32(&table_id, tokens[6]) != 0) {
2299 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2303 status = pipeline_port_in_connect_to_table(pipeline_name,
2307 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2313 static const char cmd_pipeline_port_in_stats_help[] =
2314 "pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
2316 #define MSG_PIPELINE_PORT_IN_STATS \
2317 "Pkts in: %" PRIu64 "\n" \
2318 "Pkts dropped by AH: %" PRIu64 "\n" \
2319 "Pkts dropped by other: %" PRIu64 "\n"
2322 cmd_pipeline_port_in_stats(char **tokens,
2327 struct rte_pipeline_port_in_stats stats;
2328 char *pipeline_name;
2332 if ((n_tokens != 7) && (n_tokens != 8)) {
2333 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2337 pipeline_name = tokens[1];
2339 if (strcmp(tokens[2], "port") != 0) {
2340 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2344 if (strcmp(tokens[3], "in") != 0) {
2345 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2349 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2350 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2354 if (strcmp(tokens[5], "stats") != 0) {
2355 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2359 if (strcmp(tokens[6], "read") != 0) {
2360 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2365 if (n_tokens == 8) {
2366 if (strcmp(tokens[7], "clear") != 0) {
2367 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2374 status = pipeline_port_in_stats_read(pipeline_name,
2379 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2383 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2384 stats.stats.n_pkts_in,
2385 stats.n_pkts_dropped_by_ah,
2386 stats.stats.n_pkts_drop);
2390 static const char cmd_pipeline_port_in_enable_help[] =
2391 "pipeline <pipeline_name> port in <port_id> enable\n";
2394 cmd_pipeline_port_in_enable(char **tokens,
2399 char *pipeline_name;
2403 if (n_tokens != 6) {
2404 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2408 pipeline_name = tokens[1];
2410 if (strcmp(tokens[2], "port") != 0) {
2411 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2415 if (strcmp(tokens[3], "in") != 0) {
2416 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2420 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2421 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2425 if (strcmp(tokens[5], "enable") != 0) {
2426 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2430 status = pipeline_port_in_enable(pipeline_name, port_id);
2432 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2438 static const char cmd_pipeline_port_in_disable_help[] =
2439 "pipeline <pipeline_name> port in <port_id> disable\n";
2442 cmd_pipeline_port_in_disable(char **tokens,
2447 char *pipeline_name;
2451 if (n_tokens != 6) {
2452 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2456 pipeline_name = tokens[1];
2458 if (strcmp(tokens[2], "port") != 0) {
2459 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2463 if (strcmp(tokens[3], "in") != 0) {
2464 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2468 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2469 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2473 if (strcmp(tokens[5], "disable") != 0) {
2474 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2478 status = pipeline_port_in_disable(pipeline_name, port_id);
2480 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2486 static const char cmd_pipeline_port_out_stats_help[] =
2487 "pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
2489 #define MSG_PIPELINE_PORT_OUT_STATS \
2490 "Pkts in: %" PRIu64 "\n" \
2491 "Pkts dropped by AH: %" PRIu64 "\n" \
2492 "Pkts dropped by other: %" PRIu64 "\n"
2495 cmd_pipeline_port_out_stats(char **tokens,
2500 struct rte_pipeline_port_out_stats stats;
2501 char *pipeline_name;
2505 if ((n_tokens != 7) && (n_tokens != 8)) {
2506 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2510 pipeline_name = tokens[1];
2512 if (strcmp(tokens[2], "port") != 0) {
2513 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2517 if (strcmp(tokens[3], "out") != 0) {
2518 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2522 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2523 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2527 if (strcmp(tokens[5], "stats") != 0) {
2528 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2532 if (strcmp(tokens[6], "read") != 0) {
2533 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2538 if (n_tokens == 8) {
2539 if (strcmp(tokens[7], "clear") != 0) {
2540 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2547 status = pipeline_port_out_stats_read(pipeline_name,
2552 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2556 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2557 stats.stats.n_pkts_in,
2558 stats.n_pkts_dropped_by_ah,
2559 stats.stats.n_pkts_drop);
2563 static const char cmd_pipeline_table_stats_help[] =
2564 "pipeline <pipeline_name> table <table_id> stats read [clear]\n";
2566 #define MSG_PIPELINE_TABLE_STATS \
2567 "Pkts in: %" PRIu64 "\n" \
2568 "Pkts in with lookup miss: %" PRIu64 "\n" \
2569 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2570 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2571 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2572 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2575 cmd_pipeline_table_stats(char **tokens,
2580 struct rte_pipeline_table_stats stats;
2581 char *pipeline_name;
2585 if ((n_tokens != 6) && (n_tokens != 7)) {
2586 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2590 pipeline_name = tokens[1];
2592 if (strcmp(tokens[2], "table") != 0) {
2593 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2597 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
2598 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2602 if (strcmp(tokens[4], "stats") != 0) {
2603 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2607 if (strcmp(tokens[5], "read") != 0) {
2608 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2613 if (n_tokens == 7) {
2614 if (strcmp(tokens[6], "clear") != 0) {
2615 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2622 status = pipeline_table_stats_read(pipeline_name,
2627 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2631 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2632 stats.stats.n_pkts_in,
2633 stats.stats.n_pkts_lookup_miss,
2634 stats.n_pkts_dropped_by_lkp_hit_ah,
2635 stats.n_pkts_dropped_lkp_hit,
2636 stats.n_pkts_dropped_by_lkp_miss_ah,
2637 stats.n_pkts_dropped_lkp_miss);
2645 * priority <priority>
2646 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2647 * <sp0> <sp1> <dp0> <dp1> <proto>
2651 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2652 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2653 * | ipv4_addr <addr>
2654 * | ipv6_addr <addr>
2655 * | qinq <svlan> <cvlan>
2657 * ipv4 | ipv6 <addr> <depth>
2659 struct pkt_key_qinq {
2660 uint16_t ethertype_svlan;
2662 uint16_t ethertype_cvlan;
2664 } __attribute__((__packed__));
2666 struct pkt_key_ipv4_5tuple {
2667 uint8_t time_to_live;
2669 uint16_t hdr_checksum;
2674 } __attribute__((__packed__));
2676 struct pkt_key_ipv6_5tuple {
2677 uint16_t payload_length;
2684 } __attribute__((__packed__));
2686 struct pkt_key_ipv4_addr {
2688 } __attribute__((__packed__));
2690 struct pkt_key_ipv6_addr {
2692 } __attribute__((__packed__));
2695 parse_match(char **tokens,
2699 struct table_rule_match *m)
2701 memset(m, 0, sizeof(*m));
2706 if (strcmp(tokens[0], "match") != 0) {
2707 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2711 if (strcmp(tokens[1], "acl") == 0) {
2712 if (n_tokens < 14) {
2713 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2717 m->match_type = TABLE_ACL;
2719 if (strcmp(tokens[2], "priority") != 0) {
2720 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2724 if (parser_read_uint32(&m->match.acl.priority,
2726 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2730 if (strcmp(tokens[4], "ipv4") == 0) {
2731 struct in_addr saddr, daddr;
2733 m->match.acl.ip_version = 1;
2735 if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
2736 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2739 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2741 if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
2742 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2745 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2746 } else if (strcmp(tokens[4], "ipv6") == 0) {
2747 struct in6_addr saddr, daddr;
2749 m->match.acl.ip_version = 0;
2751 if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
2752 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2755 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2757 if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
2758 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2761 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2763 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2768 if (parser_read_uint32(&m->match.acl.sa_depth,
2770 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2774 if (parser_read_uint32(&m->match.acl.da_depth,
2776 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2780 if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2781 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2785 if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2786 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2790 if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2791 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2795 if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2796 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2800 if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2801 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2805 m->match.acl.proto_mask = 0xff;
2810 if (strcmp(tokens[1], "array") == 0) {
2812 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2816 m->match_type = TABLE_ARRAY;
2818 if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2819 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2826 if (strcmp(tokens[1], "hash") == 0) {
2828 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2832 m->match_type = TABLE_HASH;
2834 if (strcmp(tokens[2], "raw") == 0) {
2835 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2838 snprintf(out, out_size, MSG_ARG_MISMATCH,
2843 if (parse_hex_string(tokens[3],
2844 m->match.hash.key, &key_size) != 0) {
2845 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2852 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2853 struct pkt_key_ipv4_5tuple *ipv4 =
2854 (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
2855 struct in_addr saddr, daddr;
2860 snprintf(out, out_size, MSG_ARG_MISMATCH,
2865 if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
2866 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2870 if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
2871 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2875 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2876 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2880 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2881 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2885 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2886 snprintf(out, out_size, MSG_ARG_INVALID,
2891 ipv4->sa = saddr.s_addr;
2892 ipv4->da = daddr.s_addr;
2893 ipv4->sp = rte_cpu_to_be_16(sp);
2894 ipv4->dp = rte_cpu_to_be_16(dp);
2895 ipv4->proto = proto;
2898 } /* hash ipv4_5tuple */
2900 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2901 struct pkt_key_ipv6_5tuple *ipv6 =
2902 (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
2903 struct in6_addr saddr, daddr;
2908 snprintf(out, out_size, MSG_ARG_MISMATCH,
2913 if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
2914 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2918 if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
2919 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2923 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2924 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2928 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2929 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2933 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2934 snprintf(out, out_size, MSG_ARG_INVALID,
2939 memcpy(ipv6->sa, saddr.s6_addr, 16);
2940 memcpy(ipv6->da, daddr.s6_addr, 16);
2941 ipv6->sp = rte_cpu_to_be_16(sp);
2942 ipv6->dp = rte_cpu_to_be_16(dp);
2943 ipv6->proto = proto;
2946 } /* hash ipv6_5tuple */
2948 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2949 struct pkt_key_ipv4_addr *ipv4_addr =
2950 (struct pkt_key_ipv4_addr *) m->match.hash.key;
2951 struct in_addr addr;
2954 snprintf(out, out_size, MSG_ARG_MISMATCH,
2959 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
2960 snprintf(out, out_size, MSG_ARG_INVALID,
2965 ipv4_addr->addr = addr.s_addr;
2968 } /* hash ipv4_addr */
2970 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2971 struct pkt_key_ipv6_addr *ipv6_addr =
2972 (struct pkt_key_ipv6_addr *) m->match.hash.key;
2973 struct in6_addr addr;
2976 snprintf(out, out_size, MSG_ARG_MISMATCH,
2981 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
2982 snprintf(out, out_size, MSG_ARG_INVALID,
2987 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2990 } /* hash ipv6_5tuple */
2992 if (strcmp(tokens[2], "qinq") == 0) {
2993 struct pkt_key_qinq *qinq =
2994 (struct pkt_key_qinq *) m->match.hash.key;
2995 uint16_t svlan, cvlan;
2998 snprintf(out, out_size, MSG_ARG_MISMATCH,
3003 if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
3005 snprintf(out, out_size, MSG_ARG_INVALID,
3010 if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3012 snprintf(out, out_size, MSG_ARG_INVALID,
3017 qinq->svlan = rte_cpu_to_be_16(svlan);
3018 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3023 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3027 if (strcmp(tokens[1], "lpm") == 0) {
3029 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3033 m->match_type = TABLE_LPM;
3035 if (strcmp(tokens[2], "ipv4") == 0) {
3036 struct in_addr addr;
3038 m->match.lpm.ip_version = 1;
3040 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
3041 snprintf(out, out_size, MSG_ARG_INVALID,
3046 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3047 } else if (strcmp(tokens[2], "ipv6") == 0) {
3048 struct in6_addr addr;
3050 m->match.lpm.ip_version = 0;
3052 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
3053 snprintf(out, out_size, MSG_ARG_INVALID,
3058 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3060 snprintf(out, out_size, MSG_ARG_MISMATCH,
3065 if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3066 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3073 snprintf(out, out_size, MSG_ARG_MISMATCH,
3074 "acl or array or hash or lpm");
3086 * | table <table_id>
3087 * [balance <out0> ... <out7>]
3089 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3090 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3091 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3092 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3093 * [tm subport <subport_id> pipe <pipe_id>]
3096 * | vlan <da> <sa> <pcp> <dei> <vid>
3097 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3098 * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
3099 * | mpls unicast | multicast
3101 * label0 <label> <tc> <ttl>
3102 * [label1 <label> <tc> <ttl>
3103 * [label2 <label> <tc> <ttl>
3104 * [label3 <label> <tc> <ttl>]]]
3105 * | pppoe <da> <sa> <session_id>
3106 * | vxlan ether <da> <sa>
3107 * [vlan <pcp> <dei> <vid>]
3108 * ipv4 <sa> <da> <dscp> <ttl>
3109 * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
3112 * [nat ipv4 | ipv6 <addr> <port>]
3120 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3122 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3123 * auth_algo <algo> auth_key <key> digest_size <size>
3125 * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
3126 * digest_size <size>
3127 * data_offset <data_offset>]
3132 * <pa> ::= g | y | r | drop
3135 parse_table_action_fwd(char **tokens,
3137 struct table_rule_action *a)
3139 if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
3145 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3146 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3147 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3151 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3154 if ((n_tokens < 2) ||
3155 parser_read_uint32(&id, tokens[1]))
3158 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3160 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3164 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3165 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3166 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3170 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3173 if ((n_tokens < 2) ||
3174 parser_read_uint32(&id, tokens[1]))
3177 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3179 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3187 parse_table_action_balance(char **tokens,
3189 struct table_rule_action *a)
3193 if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
3199 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3202 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3203 if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3206 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3207 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3212 parse_policer_action(char *token, enum rte_table_action_policer *a)
3214 if (strcmp(token, "g") == 0) {
3215 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3219 if (strcmp(token, "y") == 0) {
3220 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3224 if (strcmp(token, "r") == 0) {
3225 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3229 if (strcmp(token, "drop") == 0) {
3230 *a = RTE_TABLE_ACTION_POLICER_DROP;
3238 parse_table_action_meter_tc(char **tokens,
3240 struct rte_table_action_mtr_tc_params *mtr)
3242 if ((n_tokens < 9) ||
3243 strcmp(tokens[0], "meter") ||
3244 parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3245 strcmp(tokens[2], "policer") ||
3246 strcmp(tokens[3], "g") ||
3247 parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
3248 strcmp(tokens[5], "y") ||
3249 parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
3250 strcmp(tokens[7], "r") ||
3251 parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
3258 parse_table_action_meter(char **tokens,
3260 struct table_rule_action *a)
3262 if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
3268 if ((n_tokens < 10) ||
3269 strcmp(tokens[0], "tc0") ||
3270 (parse_table_action_meter_tc(tokens + 1,
3272 &a->mtr.mtr[0]) == 0))
3278 if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
3280 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3284 if ((n_tokens < 30) ||
3285 (parse_table_action_meter_tc(tokens + 1,
3286 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3287 strcmp(tokens[10], "tc2") ||
3288 (parse_table_action_meter_tc(tokens + 11,
3289 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3290 strcmp(tokens[20], "tc3") ||
3291 (parse_table_action_meter_tc(tokens + 21,
3292 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3295 a->mtr.tc_mask = 0xF;
3296 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3297 return 1 + 10 + 3 * 10;
3301 parse_table_action_tm(char **tokens,
3303 struct table_rule_action *a)
3305 uint32_t subport_id, pipe_id;
3307 if ((n_tokens < 5) ||
3308 strcmp(tokens[0], "tm") ||
3309 strcmp(tokens[1], "subport") ||
3310 parser_read_uint32(&subport_id, tokens[2]) ||
3311 strcmp(tokens[3], "pipe") ||
3312 parser_read_uint32(&pipe_id, tokens[4]))
3315 a->tm.subport_id = subport_id;
3316 a->tm.pipe_id = pipe_id;
3317 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3322 parse_table_action_encap(char **tokens,
3324 struct table_rule_action *a)
3326 if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
3333 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3334 if ((n_tokens < 3) ||
3335 parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3336 parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3339 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3340 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3345 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3346 uint32_t pcp, dei, vid;
3348 if ((n_tokens < 6) ||
3349 parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3350 parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3351 parser_read_uint32(&pcp, tokens[3]) ||
3353 parser_read_uint32(&dei, tokens[4]) ||
3355 parser_read_uint32(&vid, tokens[5]) ||
3359 a->encap.vlan.vlan.pcp = pcp & 0x7;
3360 a->encap.vlan.vlan.dei = dei & 0x1;
3361 a->encap.vlan.vlan.vid = vid & 0xFFF;
3362 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3363 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3368 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3369 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3370 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3372 if ((n_tokens < 9) ||
3373 parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3374 parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3375 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3376 (svlan_pcp > 0x7) ||
3377 parser_read_uint32(&svlan_dei, tokens[4]) ||
3378 (svlan_dei > 0x1) ||
3379 parser_read_uint32(&svlan_vid, tokens[5]) ||
3380 (svlan_vid > 0xFFF) ||
3381 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3382 (cvlan_pcp > 0x7) ||
3383 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3384 (cvlan_dei > 0x1) ||
3385 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3386 (cvlan_vid > 0xFFF))
3389 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3390 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3391 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3392 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3393 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3394 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3395 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3396 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3401 if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
3402 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3403 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3405 if ((n_tokens < 10) ||
3406 parse_mac_addr(tokens[1],
3407 &a->encap.qinq_pppoe.ether.da) ||
3408 parse_mac_addr(tokens[2],
3409 &a->encap.qinq_pppoe.ether.sa) ||
3410 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3411 (svlan_pcp > 0x7) ||
3412 parser_read_uint32(&svlan_dei, tokens[4]) ||
3413 (svlan_dei > 0x1) ||
3414 parser_read_uint32(&svlan_vid, tokens[5]) ||
3415 (svlan_vid > 0xFFF) ||
3416 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3417 (cvlan_pcp > 0x7) ||
3418 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3419 (cvlan_dei > 0x1) ||
3420 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3421 (cvlan_vid > 0xFFF) ||
3422 parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
3426 a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
3427 a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
3428 a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
3429 a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
3430 a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
3431 a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
3432 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
3433 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3439 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3440 uint32_t label, tc, ttl;
3445 if (strcmp(tokens[1], "unicast") == 0)
3446 a->encap.mpls.unicast = 1;
3447 else if (strcmp(tokens[1], "multicast") == 0)
3448 a->encap.mpls.unicast = 0;
3452 if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3453 parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3454 strcmp(tokens[4], "label0") ||
3455 parser_read_uint32(&label, tokens[5]) ||
3456 (label > 0xFFFFF) ||
3457 parser_read_uint32(&tc, tokens[6]) ||
3459 parser_read_uint32(&ttl, tokens[7]) ||
3463 a->encap.mpls.mpls[0].label = label;
3464 a->encap.mpls.mpls[0].tc = tc;
3465 a->encap.mpls.mpls[0].ttl = ttl;
3470 if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
3471 a->encap.mpls.mpls_count = 1;
3472 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3473 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3477 if ((n_tokens < 4) ||
3478 parser_read_uint32(&label, tokens[1]) ||
3479 (label > 0xFFFFF) ||
3480 parser_read_uint32(&tc, tokens[2]) ||
3482 parser_read_uint32(&ttl, tokens[3]) ||
3486 a->encap.mpls.mpls[1].label = label;
3487 a->encap.mpls.mpls[1].tc = tc;
3488 a->encap.mpls.mpls[1].ttl = ttl;
3493 if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
3494 a->encap.mpls.mpls_count = 2;
3495 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3496 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3500 if ((n_tokens < 4) ||
3501 parser_read_uint32(&label, tokens[1]) ||
3502 (label > 0xFFFFF) ||
3503 parser_read_uint32(&tc, tokens[2]) ||
3505 parser_read_uint32(&ttl, tokens[3]) ||
3509 a->encap.mpls.mpls[2].label = label;
3510 a->encap.mpls.mpls[2].tc = tc;
3511 a->encap.mpls.mpls[2].ttl = ttl;
3516 if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
3517 a->encap.mpls.mpls_count = 3;
3518 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3519 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3520 return 1 + 8 + 4 + 4;
3523 if ((n_tokens < 4) ||
3524 parser_read_uint32(&label, tokens[1]) ||
3525 (label > 0xFFFFF) ||
3526 parser_read_uint32(&tc, tokens[2]) ||
3528 parser_read_uint32(&ttl, tokens[3]) ||
3532 a->encap.mpls.mpls[3].label = label;
3533 a->encap.mpls.mpls[3].tc = tc;
3534 a->encap.mpls.mpls[3].ttl = ttl;
3536 a->encap.mpls.mpls_count = 4;
3537 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3538 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3539 return 1 + 8 + 4 + 4 + 4;
3543 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3544 if ((n_tokens < 4) ||
3545 parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3546 parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3547 parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3551 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3552 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3557 if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
3564 /* ether <da> <sa> */
3565 if ((n_tokens < 3) ||
3566 strcmp(tokens[0], "ether") ||
3567 parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
3568 parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
3575 /* [vlan <pcp> <dei> <vid>] */
3576 if (strcmp(tokens[0], "vlan") == 0) {
3577 uint32_t pcp, dei, vid;
3579 if ((n_tokens < 4) ||
3580 parser_read_uint32(&pcp, tokens[1]) ||
3582 parser_read_uint32(&dei, tokens[2]) ||
3584 parser_read_uint32(&vid, tokens[3]) ||
3588 a->encap.vxlan.vlan.pcp = pcp;
3589 a->encap.vxlan.vlan.dei = dei;
3590 a->encap.vxlan.vlan.vid = vid;
3597 /* ipv4 <sa> <da> <dscp> <ttl>
3598 | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
3599 if (strcmp(tokens[0], "ipv4") == 0) {
3600 struct in_addr sa, da;
3603 if ((n_tokens < 5) ||
3604 parse_ipv4_addr(tokens[1], &sa) ||
3605 parse_ipv4_addr(tokens[2], &da) ||
3606 parser_read_uint8(&dscp, tokens[3]) ||
3608 parser_read_uint8(&ttl, tokens[4]))
3611 a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
3612 a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
3613 a->encap.vxlan.ipv4.dscp = dscp;
3614 a->encap.vxlan.ipv4.ttl = ttl;
3619 } else if (strcmp(tokens[0], "ipv6") == 0) {
3620 struct in6_addr sa, da;
3621 uint32_t flow_label;
3622 uint8_t dscp, hop_limit;
3624 if ((n_tokens < 6) ||
3625 parse_ipv6_addr(tokens[1], &sa) ||
3626 parse_ipv6_addr(tokens[2], &da) ||
3627 parser_read_uint32(&flow_label, tokens[3]) ||
3628 parser_read_uint8(&dscp, tokens[4]) ||
3630 parser_read_uint8(&hop_limit, tokens[5]))
3633 memcpy(a->encap.vxlan.ipv6.sa, sa.s6_addr, 16);
3634 memcpy(a->encap.vxlan.ipv6.da, da.s6_addr, 16);
3635 a->encap.vxlan.ipv6.flow_label = flow_label;
3636 a->encap.vxlan.ipv6.dscp = dscp;
3637 a->encap.vxlan.ipv6.hop_limit = hop_limit;
3646 if ((n_tokens < 3) ||
3647 strcmp(tokens[0], "udp") ||
3648 parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
3649 parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
3657 if ((n_tokens < 2) ||
3658 strcmp(tokens[0], "vxlan") ||
3659 parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
3660 (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
3667 a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
3668 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3676 parse_table_action_nat(char **tokens,
3678 struct table_rule_action *a)
3680 if ((n_tokens < 4) ||
3681 strcmp(tokens[0], "nat"))
3684 if (strcmp(tokens[1], "ipv4") == 0) {
3685 struct in_addr addr;
3688 if (parse_ipv4_addr(tokens[2], &addr) ||
3689 parser_read_uint16(&port, tokens[3]))
3692 a->nat.ip_version = 1;
3693 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3695 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3699 if (strcmp(tokens[1], "ipv6") == 0) {
3700 struct in6_addr addr;
3703 if (parse_ipv6_addr(tokens[2], &addr) ||
3704 parser_read_uint16(&port, tokens[3]))
3707 a->nat.ip_version = 0;
3708 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3710 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3718 parse_table_action_ttl(char **tokens,
3720 struct table_rule_action *a)
3722 if ((n_tokens < 2) ||
3723 strcmp(tokens[0], "ttl"))
3726 if (strcmp(tokens[1], "dec") == 0)
3727 a->ttl.decrement = 1;
3728 else if (strcmp(tokens[1], "keep") == 0)
3729 a->ttl.decrement = 0;
3733 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3738 parse_table_action_stats(char **tokens,
3740 struct table_rule_action *a)
3742 if ((n_tokens < 1) ||
3743 strcmp(tokens[0], "stats"))
3746 a->stats.n_packets = 0;
3747 a->stats.n_bytes = 0;
3748 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3753 parse_table_action_time(char **tokens,
3755 struct table_rule_action *a)
3757 if ((n_tokens < 1) ||
3758 strcmp(tokens[0], "time"))
3761 a->time.time = rte_rdtsc();
3762 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3767 parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
3769 struct rte_crypto_sym_xform *xform[2] = {NULL};
3772 xform[0] = p->xform;
3774 xform[1] = xform[0]->next;
3776 for (i = 0; i < 2; i++) {
3777 if (xform[i] == NULL)
3780 switch (xform[i]->type) {
3781 case RTE_CRYPTO_SYM_XFORM_CIPHER:
3782 if (p->cipher_auth.cipher_iv.val)
3783 free(p->cipher_auth.cipher_iv.val);
3784 if (p->cipher_auth.cipher_iv_update.val)
3785 free(p->cipher_auth.cipher_iv_update.val);
3787 case RTE_CRYPTO_SYM_XFORM_AUTH:
3788 if (p->cipher_auth.auth_iv.val)
3789 free(p->cipher_auth.cipher_iv.val);
3790 if (p->cipher_auth.auth_iv_update.val)
3791 free(p->cipher_auth.cipher_iv_update.val);
3793 case RTE_CRYPTO_SYM_XFORM_AEAD:
3795 free(p->aead.iv.val);
3796 if (p->aead.aad.val)
3797 free(p->aead.aad.val);
3806 static struct rte_crypto_sym_xform *
3807 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
3808 uint8_t *key, uint32_t max_key_len, char **tokens,
3809 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3811 struct rte_crypto_sym_xform *xform_cipher;
3815 if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
3816 strcmp(tokens[3], "cipher_key") ||
3817 strcmp(tokens[5], "cipher_iv"))
3820 xform_cipher = calloc(1, sizeof(*xform_cipher));
3821 if (xform_cipher == NULL)
3824 xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
3825 xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
3826 RTE_CRYPTO_CIPHER_OP_DECRYPT;
3829 status = rte_cryptodev_get_cipher_algo_enum(
3830 &xform_cipher->cipher.algo, tokens[2]);
3835 len = strlen(tokens[4]);
3836 if (len / 2 > max_key_len) {
3841 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
3845 xform_cipher->cipher.key.data = key;
3846 xform_cipher->cipher.key.length = (uint16_t)len;
3849 len = strlen(tokens[6]);
3851 p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
3852 if (p->cipher_auth.cipher_iv.val == NULL)
3855 status = parse_hex_string(tokens[6],
3856 p->cipher_auth.cipher_iv.val,
3861 xform_cipher->cipher.iv.length = (uint16_t)len;
3862 xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
3863 p->cipher_auth.cipher_iv.length = (uint32_t)len;
3866 return xform_cipher;
3869 if (p->cipher_auth.cipher_iv.val) {
3870 free(p->cipher_auth.cipher_iv.val);
3871 p->cipher_auth.cipher_iv.val = NULL;
3879 static struct rte_crypto_sym_xform *
3880 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
3881 uint8_t *key, uint32_t max_key_len, char **tokens,
3882 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3884 struct rte_crypto_sym_xform *xform_cipher;
3885 struct rte_crypto_sym_xform *xform_auth;
3889 if (n_tokens < 13 ||
3890 strcmp(tokens[7], "auth_algo") ||
3891 strcmp(tokens[9], "auth_key") ||
3892 strcmp(tokens[11], "digest_size"))
3895 xform_auth = calloc(1, sizeof(*xform_auth));
3896 if (xform_auth == NULL)
3899 xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
3900 xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
3901 RTE_CRYPTO_AUTH_OP_VERIFY;
3904 status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
3910 len = strlen(tokens[10]);
3911 if (len / 2 > max_key_len) {
3916 status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
3920 xform_auth->auth.key.data = key;
3921 xform_auth->auth.key.length = (uint16_t)len;
3923 key += xform_auth->auth.key.length;
3924 max_key_len -= xform_auth->auth.key.length;
3926 if (strcmp(tokens[11], "digest_size"))
3929 status = parser_read_uint16(&xform_auth->auth.digest_length,
3934 xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
3935 7, encrypt, used_n_tokens);
3936 if (xform_cipher == NULL)
3939 *used_n_tokens += 6;
3942 xform_cipher->next = xform_auth;
3943 return xform_cipher;
3945 xform_auth->next = xform_cipher;
3950 if (p->cipher_auth.auth_iv.val) {
3951 free(p->cipher_auth.auth_iv.val);
3952 p->cipher_auth.auth_iv.val = 0;
3960 static struct rte_crypto_sym_xform *
3961 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
3962 uint8_t *key, uint32_t max_key_len, char **tokens,
3963 uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
3965 struct rte_crypto_sym_xform *xform_aead;
3969 if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
3970 strcmp(tokens[3], "aead_key") ||
3971 strcmp(tokens[5], "aead_iv") ||
3972 strcmp(tokens[7], "aead_aad") ||
3973 strcmp(tokens[9], "digest_size"))
3976 xform_aead = calloc(1, sizeof(*xform_aead));
3977 if (xform_aead == NULL)
3980 xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
3981 xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
3982 RTE_CRYPTO_AEAD_OP_DECRYPT;
3985 status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
3991 len = strlen(tokens[4]);
3992 if (len / 2 > max_key_len) {
3997 status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
4001 xform_aead->aead.key.data = key;
4002 xform_aead->aead.key.length = (uint16_t)len;
4005 len = strlen(tokens[6]);
4006 p->aead.iv.val = calloc(1, len / 2 + 1);
4007 if (p->aead.iv.val == NULL)
4010 status = parse_hex_string(tokens[6], p->aead.iv.val,
4015 xform_aead->aead.iv.length = (uint16_t)len;
4016 xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
4017 p->aead.iv.length = (uint32_t)len;
4020 len = strlen(tokens[8]);
4021 p->aead.aad.val = calloc(1, len / 2 + 1);
4022 if (p->aead.aad.val == NULL)
4025 status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
4029 xform_aead->aead.aad_length = (uint16_t)len;
4030 p->aead.aad.length = (uint32_t)len;
4033 status = parser_read_uint16(&xform_aead->aead.digest_length,
4038 *used_n_tokens = 11;
4043 if (p->aead.iv.val) {
4044 free(p->aead.iv.val);
4045 p->aead.iv.val = NULL;
4047 if (p->aead.aad.val) {
4048 free(p->aead.aad.val);
4049 p->aead.aad.val = NULL;
4059 parse_table_action_sym_crypto(char **tokens,
4061 struct table_rule_action *a)
4063 struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
4064 struct rte_crypto_sym_xform *xform = NULL;
4065 uint8_t *key = a->sym_crypto_key;
4066 uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
4067 uint32_t used_n_tokens;
4071 if ((n_tokens < 12) ||
4072 strcmp(tokens[0], "sym_crypto") ||
4073 strcmp(tokens[2], "type"))
4076 memset(p, 0, sizeof(*p));
4078 if (strcmp(tokens[1], "encrypt") == 0)
4083 status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
4087 if (strcmp(tokens[3], "cipher") == 0) {
4091 xform = parse_table_action_cipher(p, key, max_key_len, tokens,
4092 n_tokens, encrypt, &used_n_tokens);
4093 } else if (strcmp(tokens[3], "cipher_auth") == 0) {
4097 xform = parse_table_action_cipher_auth(p, key, max_key_len,
4098 tokens, n_tokens, encrypt, &used_n_tokens);
4099 } else if (strcmp(tokens[3], "aead") == 0) {
4103 xform = parse_table_action_aead(p, key, max_key_len, tokens,
4104 n_tokens, encrypt, &used_n_tokens);
4112 if (strcmp(tokens[used_n_tokens], "data_offset")) {
4113 parse_free_sym_crypto_param_data(p);
4117 a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
4119 return used_n_tokens + 5;
4123 parse_table_action_tag(char **tokens,
4125 struct table_rule_action *a)
4127 if ((n_tokens < 2) ||
4128 strcmp(tokens[0], "tag"))
4131 if (parser_read_uint32(&a->tag.tag, tokens[1]))
4134 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
4139 parse_table_action_decap(char **tokens,
4141 struct table_rule_action *a)
4143 if ((n_tokens < 2) ||
4144 strcmp(tokens[0], "decap"))
4147 if (parser_read_uint16(&a->decap.n, tokens[1]))
4150 a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
4155 parse_table_action(char **tokens,
4159 struct table_rule_action *a)
4161 uint32_t n_tokens0 = n_tokens;
4163 memset(a, 0, sizeof(*a));
4165 if ((n_tokens < 2) ||
4166 strcmp(tokens[0], "action"))
4172 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
4175 n = parse_table_action_fwd(tokens, n_tokens, a);
4177 snprintf(out, out_size, MSG_ARG_INVALID,
4186 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
4189 n = parse_table_action_balance(tokens, n_tokens, a);
4191 snprintf(out, out_size, MSG_ARG_INVALID,
4200 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
4203 n = parse_table_action_meter(tokens, n_tokens, a);
4205 snprintf(out, out_size, MSG_ARG_INVALID,
4214 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
4217 n = parse_table_action_tm(tokens, n_tokens, a);
4219 snprintf(out, out_size, MSG_ARG_INVALID,
4228 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
4231 n = parse_table_action_encap(tokens, n_tokens, a);
4233 snprintf(out, out_size, MSG_ARG_INVALID,
4242 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
4245 n = parse_table_action_nat(tokens, n_tokens, a);
4247 snprintf(out, out_size, MSG_ARG_INVALID,
4256 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
4259 n = parse_table_action_ttl(tokens, n_tokens, a);
4261 snprintf(out, out_size, MSG_ARG_INVALID,
4270 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
4273 n = parse_table_action_stats(tokens, n_tokens, a);
4275 snprintf(out, out_size, MSG_ARG_INVALID,
4284 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
4287 n = parse_table_action_time(tokens, n_tokens, a);
4289 snprintf(out, out_size, MSG_ARG_INVALID,
4298 if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
4301 n = parse_table_action_sym_crypto(tokens, n_tokens, a);
4303 snprintf(out, out_size, MSG_ARG_INVALID,
4304 "action sym_crypto");
4311 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
4314 n = parse_table_action_tag(tokens, n_tokens, a);
4316 snprintf(out, out_size, MSG_ARG_INVALID,
4325 if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
4328 n = parse_table_action_decap(tokens, n_tokens, a);
4330 snprintf(out, out_size, MSG_ARG_INVALID,
4339 if (n_tokens0 - n_tokens == 1) {
4340 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4344 return n_tokens0 - n_tokens;
4348 static const char cmd_pipeline_table_rule_add_help[] =
4349 "pipeline <pipeline_name> table <table_id> rule add\n"
4351 " action <table_action>\n";
4354 cmd_pipeline_table_rule_add(char **tokens,
4359 struct table_rule_match m;
4360 struct table_rule_action a;
4361 char *pipeline_name;
4362 uint32_t table_id, t0, n_tokens_parsed;
4366 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4370 pipeline_name = tokens[1];
4372 if (strcmp(tokens[2], "table") != 0) {
4373 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4377 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4378 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4382 if (strcmp(tokens[4], "rule") != 0) {
4383 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4387 if (strcmp(tokens[5], "add") != 0) {
4388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4395 n_tokens_parsed = parse_match(tokens + t0,
4400 if (n_tokens_parsed == 0)
4402 t0 += n_tokens_parsed;
4405 n_tokens_parsed = parse_table_action(tokens + t0,
4410 if (n_tokens_parsed == 0)
4412 t0 += n_tokens_parsed;
4414 if (t0 != n_tokens) {
4415 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
4419 status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
4421 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4425 if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
4426 parse_free_sym_crypto_param_data(&a.sym_crypto);
4430 static const char cmd_pipeline_table_rule_add_default_help[] =
4431 "pipeline <pipeline_name> table <table_id> rule add\n"
4437 " | port <port_id>\n"
4439 " | table <table_id>\n";
4442 cmd_pipeline_table_rule_add_default(char **tokens,
4447 struct table_rule_action action;
4448 char *pipeline_name;
4452 if ((n_tokens != 11) && (n_tokens != 12)) {
4453 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4457 pipeline_name = tokens[1];
4459 if (strcmp(tokens[2], "table") != 0) {
4460 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4464 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4465 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4469 if (strcmp(tokens[4], "rule") != 0) {
4470 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4474 if (strcmp(tokens[5], "add") != 0) {
4475 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4479 if (strcmp(tokens[6], "match") != 0) {
4480 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4484 if (strcmp(tokens[7], "default") != 0) {
4485 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4489 if (strcmp(tokens[8], "action") != 0) {
4490 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4494 if (strcmp(tokens[9], "fwd") != 0) {
4495 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4499 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4501 if (strcmp(tokens[10], "drop") == 0) {
4502 if (n_tokens != 11) {
4503 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4507 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4508 } else if (strcmp(tokens[10], "port") == 0) {
4511 if (n_tokens != 12) {
4512 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4516 if (parser_read_uint32(&id, tokens[11]) != 0) {
4517 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4521 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4523 } else if (strcmp(tokens[10], "meta") == 0) {
4524 if (n_tokens != 11) {
4525 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4529 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4530 } else if (strcmp(tokens[10], "table") == 0) {
4533 if (n_tokens != 12) {
4534 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4538 if (parser_read_uint32(&id, tokens[11]) != 0) {
4539 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4543 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4546 snprintf(out, out_size, MSG_ARG_INVALID,
4547 "drop or port or meta or table");
4551 status = pipeline_table_rule_add_default(pipeline_name,
4555 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4561 static const char cmd_pipeline_table_rule_add_bulk_help[] =
4562 "pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
4564 " File <file_name>:\n"
4565 " - line format: match <match> action <action>\n";
4568 cli_rule_file_process(const char *file_name,
4569 size_t line_len_max,
4570 struct table_rule_list **rule_list,
4572 uint32_t *line_number,
4577 cmd_pipeline_table_rule_add_bulk(char **tokens,
4582 struct table_rule_list *list = NULL;
4583 char *pipeline_name, *file_name;
4584 uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
4587 if (n_tokens != 8) {
4588 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4592 pipeline_name = tokens[1];
4594 if (strcmp(tokens[2], "table") != 0) {
4595 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4599 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4600 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4604 if (strcmp(tokens[4], "rule") != 0) {
4605 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4609 if (strcmp(tokens[5], "add") != 0) {
4610 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4614 if (strcmp(tokens[6], "bulk") != 0) {
4615 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4619 file_name = tokens[7];
4621 /* Load rules from file. */
4622 status = cli_rule_file_process(file_name,
4630 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4635 status = pipeline_table_rule_add_bulk(pipeline_name,
4639 &n_rules_not_added);
4641 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4645 snprintf(out, out_size, "Added %u rules out of %u.\n",
4651 static const char cmd_pipeline_table_rule_delete_help[] =
4652 "pipeline <pipeline_name> table <table_id> rule delete\n"
4656 cmd_pipeline_table_rule_delete(char **tokens,
4661 struct table_rule_match m;
4662 char *pipeline_name;
4663 uint32_t table_id, n_tokens_parsed, t0;
4667 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4671 pipeline_name = tokens[1];
4673 if (strcmp(tokens[2], "table") != 0) {
4674 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4678 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4679 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4683 if (strcmp(tokens[4], "rule") != 0) {
4684 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4688 if (strcmp(tokens[5], "delete") != 0) {
4689 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4696 n_tokens_parsed = parse_match(tokens + t0,
4701 if (n_tokens_parsed == 0)
4703 t0 += n_tokens_parsed;
4705 if (n_tokens != t0) {
4706 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4710 status = pipeline_table_rule_delete(pipeline_name,
4714 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4720 static const char cmd_pipeline_table_rule_delete_default_help[] =
4721 "pipeline <pipeline_name> table <table_id> rule delete\n"
4726 cmd_pipeline_table_rule_delete_default(char **tokens,
4731 char *pipeline_name;
4735 if (n_tokens != 8) {
4736 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4740 pipeline_name = tokens[1];
4742 if (strcmp(tokens[2], "table") != 0) {
4743 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4747 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4748 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4752 if (strcmp(tokens[4], "rule") != 0) {
4753 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4757 if (strcmp(tokens[5], "delete") != 0) {
4758 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4762 if (strcmp(tokens[6], "match") != 0) {
4763 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4767 if (strcmp(tokens[7], "default") != 0) {
4768 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4772 status = pipeline_table_rule_delete_default(pipeline_name,
4775 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4781 ether_addr_show(FILE *f, struct rte_ether_addr *addr)
4783 fprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x",
4784 (uint32_t)addr->addr_bytes[0], (uint32_t)addr->addr_bytes[1],
4785 (uint32_t)addr->addr_bytes[2], (uint32_t)addr->addr_bytes[3],
4786 (uint32_t)addr->addr_bytes[4], (uint32_t)addr->addr_bytes[5]);
4790 ipv4_addr_show(FILE *f, uint32_t addr)
4792 fprintf(f, "%u.%u.%u.%u",
4794 (addr >> 16) & 0xFF,
4800 ipv6_addr_show(FILE *f, uint8_t *addr)
4802 fprintf(f, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
4803 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:",
4804 (uint32_t)addr[0], (uint32_t)addr[1],
4805 (uint32_t)addr[2], (uint32_t)addr[3],
4806 (uint32_t)addr[4], (uint32_t)addr[5],
4807 (uint32_t)addr[6], (uint32_t)addr[7],
4808 (uint32_t)addr[8], (uint32_t)addr[9],
4809 (uint32_t)addr[10], (uint32_t)addr[11],
4810 (uint32_t)addr[12], (uint32_t)addr[13],
4811 (uint32_t)addr[14], (uint32_t)addr[15]);
4815 policer_action_string(enum rte_table_action_policer action) {
4817 case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
4818 case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
4819 case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
4820 case RTE_TABLE_ACTION_POLICER_DROP: return "D";
4821 default: return "?";
4826 table_rule_show(const char *pipeline_name,
4828 const char *file_name)
4831 struct table *table;
4832 struct table_rule *rule;
4836 /* Check input params. */
4837 if ((pipeline_name == NULL) ||
4838 (file_name == NULL))
4841 p = pipeline_find(pipeline_name);
4843 (table_id >= p->n_tables))
4846 table = &p->table[table_id];
4849 f = fopen(file_name, "w");
4853 /* Write table rules to file. */
4854 TAILQ_FOREACH(rule, &table->rules, node) {
4855 struct table_rule_match *m = &rule->match;
4856 struct table_rule_action *a = &rule->action;
4858 fprintf(f, "match ");
4859 switch (m->match_type) {
4861 fprintf(f, "acl priority %u ",
4862 m->match.acl.priority);
4864 fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
4866 if (m->match.acl.ip_version)
4867 ipv4_addr_show(f, m->match.acl.ipv4.sa);
4869 ipv6_addr_show(f, m->match.acl.ipv6.sa);
4871 fprintf(f, "%u", m->match.acl.sa_depth);
4873 if (m->match.acl.ip_version)
4874 ipv4_addr_show(f, m->match.acl.ipv4.da);
4876 ipv6_addr_show(f, m->match.acl.ipv6.da);
4878 fprintf(f, "%u", m->match.acl.da_depth);
4880 fprintf(f, "%u %u %u %u %u ",
4881 (uint32_t)m->match.acl.sp0,
4882 (uint32_t)m->match.acl.sp1,
4883 (uint32_t)m->match.acl.dp0,
4884 (uint32_t)m->match.acl.dp1,
4885 (uint32_t)m->match.acl.proto);
4889 fprintf(f, "array %u ",
4890 m->match.array.pos);
4894 fprintf(f, "hash raw ");
4895 for (i = 0; i < table->params.match.hash.key_size; i++)
4896 fprintf(f, "%02x", m->match.hash.key[i]);
4903 fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
4905 if (m->match.acl.ip_version)
4906 ipv4_addr_show(f, m->match.lpm.ipv4);
4908 ipv6_addr_show(f, m->match.lpm.ipv6);
4911 (uint32_t)m->match.lpm.depth);
4915 fprintf(f, "unknown ");
4918 fprintf(f, "action ");
4919 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
4921 switch (a->fwd.action) {
4922 case RTE_PIPELINE_ACTION_DROP:
4923 fprintf(f, "drop ");
4926 case RTE_PIPELINE_ACTION_PORT:
4927 fprintf(f, "port %u ", a->fwd.id);
4930 case RTE_PIPELINE_ACTION_PORT_META:
4931 fprintf(f, "meta ");
4934 case RTE_PIPELINE_ACTION_TABLE:
4936 fprintf(f, "table %u ", a->fwd.id);
4940 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
4941 fprintf(f, "balance ");
4942 for (i = 0; i < RTE_DIM(a->lb.out); i++)
4943 fprintf(f, "%u ", a->lb.out[i]);
4946 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
4948 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
4949 if (a->mtr.tc_mask & (1 << i)) {
4950 struct rte_table_action_mtr_tc_params *p =
4952 enum rte_table_action_policer ga =
4953 p->policer[RTE_COLOR_GREEN];
4954 enum rte_table_action_policer ya =
4955 p->policer[RTE_COLOR_YELLOW];
4956 enum rte_table_action_policer ra =
4957 p->policer[RTE_COLOR_RED];
4959 fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
4961 a->mtr.mtr[i].meter_profile_id,
4962 policer_action_string(ga),
4963 policer_action_string(ya),
4964 policer_action_string(ra));
4968 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
4969 fprintf(f, "tm subport %u pipe %u ",
4973 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
4974 fprintf(f, "encap ");
4975 switch (a->encap.type) {
4976 case RTE_TABLE_ACTION_ENCAP_ETHER:
4977 fprintf(f, "ether ");
4978 ether_addr_show(f, &a->encap.ether.ether.da);
4980 ether_addr_show(f, &a->encap.ether.ether.sa);
4984 case RTE_TABLE_ACTION_ENCAP_VLAN:
4985 fprintf(f, "vlan ");
4986 ether_addr_show(f, &a->encap.vlan.ether.da);
4988 ether_addr_show(f, &a->encap.vlan.ether.sa);
4989 fprintf(f, " pcp %u dei %u vid %u ",
4990 a->encap.vlan.vlan.pcp,
4991 a->encap.vlan.vlan.dei,
4992 a->encap.vlan.vlan.vid);
4995 case RTE_TABLE_ACTION_ENCAP_QINQ:
4996 fprintf(f, "qinq ");
4997 ether_addr_show(f, &a->encap.qinq.ether.da);
4999 ether_addr_show(f, &a->encap.qinq.ether.sa);
5000 fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
5001 a->encap.qinq.svlan.pcp,
5002 a->encap.qinq.svlan.dei,
5003 a->encap.qinq.svlan.vid,
5004 a->encap.qinq.cvlan.pcp,
5005 a->encap.qinq.cvlan.dei,
5006 a->encap.qinq.cvlan.vid);
5009 case RTE_TABLE_ACTION_ENCAP_MPLS:
5010 fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
5011 "unicast " : "multicast ");
5012 ether_addr_show(f, &a->encap.mpls.ether.da);
5014 ether_addr_show(f, &a->encap.mpls.ether.sa);
5016 for (i = 0; i < a->encap.mpls.mpls_count; i++) {
5017 struct rte_table_action_mpls_hdr *l =
5018 &a->encap.mpls.mpls[i];
5020 fprintf(f, "label%u %u %u %u ",
5028 case RTE_TABLE_ACTION_ENCAP_PPPOE:
5029 fprintf(f, "pppoe ");
5030 ether_addr_show(f, &a->encap.pppoe.ether.da);
5032 ether_addr_show(f, &a->encap.pppoe.ether.sa);
5033 fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
5036 case RTE_TABLE_ACTION_ENCAP_VXLAN:
5037 fprintf(f, "vxlan ether ");
5038 ether_addr_show(f, &a->encap.vxlan.ether.da);
5040 ether_addr_show(f, &a->encap.vxlan.ether.sa);
5041 if (table->ap->params.encap.vxlan.vlan)
5042 fprintf(f, " vlan pcp %u dei %u vid %u ",
5043 a->encap.vxlan.vlan.pcp,
5044 a->encap.vxlan.vlan.dei,
5045 a->encap.vxlan.vlan.vid);
5046 if (table->ap->params.encap.vxlan.ip_version) {
5047 fprintf(f, " ipv4 ");
5048 ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
5050 ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
5051 fprintf(f, " %u %u ",
5052 (uint32_t)a->encap.vxlan.ipv4.dscp,
5053 (uint32_t)a->encap.vxlan.ipv4.ttl);
5055 fprintf(f, " ipv6 ");
5056 ipv6_addr_show(f, a->encap.vxlan.ipv6.sa);
5058 ipv6_addr_show(f, a->encap.vxlan.ipv6.da);
5059 fprintf(f, " %u %u %u ",
5060 a->encap.vxlan.ipv6.flow_label,
5061 (uint32_t)a->encap.vxlan.ipv6.dscp,
5062 (uint32_t)a->encap.vxlan.ipv6.hop_limit);
5063 fprintf(f, " udp %u %u vxlan %u ",
5064 a->encap.vxlan.udp.sp,
5065 a->encap.vxlan.udp.dp,
5066 a->encap.vxlan.vxlan.vni);
5071 fprintf(f, "unknown ");
5075 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
5076 fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
5077 if (a->nat.ip_version)
5078 ipv4_addr_show(f, a->nat.addr.ipv4);
5080 ipv6_addr_show(f, a->nat.addr.ipv6);
5081 fprintf(f, " %u ", (uint32_t)(a->nat.port));
5084 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
5085 fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
5087 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
5088 fprintf(f, "stats ");
5090 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
5091 fprintf(f, "time ");
5093 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
5094 fprintf(f, "sym_crypto ");
5096 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
5097 fprintf(f, "tag %u ", a->tag.tag);
5099 if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
5100 fprintf(f, "decap %u ", a->decap.n);
5106 /* Write table default rule to file. */
5107 if (table->rule_default) {
5108 struct table_rule_action *a = &table->rule_default->action;
5110 fprintf(f, "# match default action fwd ");
5112 switch (a->fwd.action) {
5113 case RTE_PIPELINE_ACTION_DROP:
5114 fprintf(f, "drop ");
5117 case RTE_PIPELINE_ACTION_PORT:
5118 fprintf(f, "port %u ", a->fwd.id);
5121 case RTE_PIPELINE_ACTION_PORT_META:
5122 fprintf(f, "meta ");
5125 case RTE_PIPELINE_ACTION_TABLE:
5127 fprintf(f, "table %u ", a->fwd.id);
5130 fprintf(f, "# match default action fwd drop ");
5140 static const char cmd_pipeline_table_rule_show_help[] =
5141 "pipeline <pipeline_name> table <table_id> rule show\n"
5142 " file <file_name>\n";
5145 cmd_pipeline_table_rule_show(char **tokens,
5150 char *file_name = NULL, *pipeline_name;
5154 if (n_tokens != 8) {
5155 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5159 pipeline_name = tokens[1];
5161 if (strcmp(tokens[2], "table") != 0) {
5162 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5166 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5167 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5171 if (strcmp(tokens[4], "rule") != 0) {
5172 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5176 if (strcmp(tokens[5], "show") != 0) {
5177 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
5181 if (strcmp(tokens[6], "file") != 0) {
5182 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
5186 file_name = tokens[7];
5188 status = table_rule_show(pipeline_name, table_id, file_name);
5190 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5195 static const char cmd_pipeline_table_rule_stats_read_help[] =
5196 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
5200 cmd_pipeline_table_rule_stats_read(char **tokens,
5205 struct table_rule_match m;
5206 struct rte_table_action_stats_counters stats;
5207 char *pipeline_name;
5208 uint32_t table_id, n_tokens_parsed;
5209 int clear = 0, status;
5212 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5216 pipeline_name = tokens[1];
5218 if (strcmp(tokens[2], "table") != 0) {
5219 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5223 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5224 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5228 if (strcmp(tokens[4], "rule") != 0) {
5229 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5233 if (strcmp(tokens[5], "read") != 0) {
5234 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5238 if (strcmp(tokens[6], "stats") != 0) {
5239 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
5247 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5255 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5256 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5260 n_tokens_parsed = parse_match(tokens,
5265 if (n_tokens_parsed == 0)
5267 n_tokens -= n_tokens_parsed;
5268 tokens += n_tokens_parsed;
5272 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5276 /* Read table rule stats. */
5277 status = pipeline_table_rule_stats_read(pipeline_name,
5283 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5288 if (stats.n_packets_valid && stats.n_bytes_valid)
5289 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
5293 if (stats.n_packets_valid && !stats.n_bytes_valid)
5294 snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
5297 if (!stats.n_packets_valid && stats.n_bytes_valid)
5298 snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
5301 if (!stats.n_packets_valid && !stats.n_bytes_valid)
5302 snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
5305 static const char cmd_pipeline_table_meter_profile_add_help[] =
5306 "pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
5307 " add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
5308 " | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
5311 cmd_pipeline_table_meter_profile_add(char **tokens,
5316 struct rte_table_action_meter_profile p;
5317 char *pipeline_name;
5318 uint32_t table_id, meter_profile_id;
5322 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5326 pipeline_name = tokens[1];
5328 if (strcmp(tokens[2], "table") != 0) {
5329 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5333 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5334 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5338 if (strcmp(tokens[4], "meter") != 0) {
5339 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5343 if (strcmp(tokens[5], "profile") != 0) {
5344 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5348 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5349 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5353 if (strcmp(tokens[7], "add") != 0) {
5354 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
5358 if (strcmp(tokens[8], "srtcm") == 0) {
5359 if (n_tokens != 15) {
5360 snprintf(out, out_size, MSG_ARG_MISMATCH,
5365 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
5367 if (strcmp(tokens[9], "cir") != 0) {
5368 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5372 if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
5373 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5377 if (strcmp(tokens[11], "cbs") != 0) {
5378 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5382 if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
5383 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5387 if (strcmp(tokens[13], "ebs") != 0) {
5388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
5392 if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
5393 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
5396 } else if (strcmp(tokens[8], "trtcm") == 0) {
5397 if (n_tokens != 17) {
5398 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5402 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
5404 if (strcmp(tokens[9], "cir") != 0) {
5405 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5409 if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
5410 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5414 if (strcmp(tokens[11], "pir") != 0) {
5415 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
5419 if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
5420 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
5423 if (strcmp(tokens[13], "cbs") != 0) {
5424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5428 if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
5429 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5433 if (strcmp(tokens[15], "pbs") != 0) {
5434 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
5438 if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
5439 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
5443 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5447 status = pipeline_table_mtr_profile_add(pipeline_name,
5452 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5458 static const char cmd_pipeline_table_meter_profile_delete_help[] =
5459 "pipeline <pipeline_name> table <table_id>\n"
5460 " meter profile <meter_profile_id> delete\n";
5463 cmd_pipeline_table_meter_profile_delete(char **tokens,
5468 char *pipeline_name;
5469 uint32_t table_id, meter_profile_id;
5472 if (n_tokens != 8) {
5473 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5477 pipeline_name = tokens[1];
5479 if (strcmp(tokens[2], "table") != 0) {
5480 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5484 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5485 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5489 if (strcmp(tokens[4], "meter") != 0) {
5490 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5494 if (strcmp(tokens[5], "profile") != 0) {
5495 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5499 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5500 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5504 if (strcmp(tokens[7], "delete") != 0) {
5505 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
5509 status = pipeline_table_mtr_profile_delete(pipeline_name,
5513 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5519 static const char cmd_pipeline_table_rule_meter_read_help[] =
5520 "pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
5524 cmd_pipeline_table_rule_meter_read(char **tokens,
5529 struct table_rule_match m;
5530 struct rte_table_action_mtr_counters stats;
5531 char *pipeline_name;
5532 uint32_t table_id, n_tokens_parsed;
5533 int clear = 0, status;
5536 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5540 pipeline_name = tokens[1];
5542 if (strcmp(tokens[2], "table") != 0) {
5543 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5547 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5548 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5552 if (strcmp(tokens[4], "rule") != 0) {
5553 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5557 if (strcmp(tokens[5], "read") != 0) {
5558 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5562 if (strcmp(tokens[6], "meter") != 0) {
5563 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5571 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5579 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5580 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5584 n_tokens_parsed = parse_match(tokens,
5589 if (n_tokens_parsed == 0)
5591 n_tokens -= n_tokens_parsed;
5592 tokens += n_tokens_parsed;
5596 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5600 /* Read table rule meter stats. */
5601 status = pipeline_table_rule_mtr_read(pipeline_name,
5607 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5615 static const char cmd_pipeline_table_dscp_help[] =
5616 "pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
5618 " File <file_name>:\n"
5619 " - exactly 64 lines\n"
5620 " - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
5623 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
5624 const char *file_name,
5625 uint32_t *line_number)
5630 /* Check input arguments */
5631 if ((dscp_table == NULL) ||
5632 (file_name == NULL) ||
5633 (line_number == NULL)) {
5639 /* Open input file */
5640 f = fopen(file_name, "r");
5647 for (dscp = 0, l = 1; ; l++) {
5650 enum rte_color color;
5651 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
5653 if (fgets(line, sizeof(line), f) == NULL)
5656 if (is_comment(line))
5659 if (parse_tokenize_string(line, tokens, &n_tokens)) {
5668 if ((dscp >= RTE_DIM(dscp_table->entry)) ||
5669 (n_tokens != RTE_DIM(tokens)) ||
5670 parser_read_uint32(&tc_id, tokens[0]) ||
5671 (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
5672 parser_read_uint32(&tc_queue_id, tokens[1]) ||
5673 (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
5674 (strlen(tokens[2]) != 1)) {
5680 switch (tokens[2][0]) {
5683 color = RTE_COLOR_GREEN;
5688 color = RTE_COLOR_YELLOW;
5693 color = RTE_COLOR_RED;
5702 dscp_table->entry[dscp].tc_id = tc_id;
5703 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
5704 dscp_table->entry[dscp].color = color;
5714 cmd_pipeline_table_dscp(char **tokens,
5719 struct rte_table_action_dscp_table dscp_table;
5720 char *pipeline_name, *file_name;
5721 uint32_t table_id, line_number;
5724 if (n_tokens != 6) {
5725 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5729 pipeline_name = tokens[1];
5731 if (strcmp(tokens[2], "table") != 0) {
5732 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5736 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5737 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5741 if (strcmp(tokens[4], "dscp") != 0) {
5742 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
5746 file_name = tokens[5];
5748 status = load_dscp_table(&dscp_table, file_name, &line_number);
5750 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
5754 status = pipeline_table_dscp_table_update(pipeline_name,
5759 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5765 static const char cmd_pipeline_table_rule_ttl_read_help[] =
5766 "pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
5770 cmd_pipeline_table_rule_ttl_read(char **tokens,
5775 struct table_rule_match m;
5776 struct rte_table_action_ttl_counters stats;
5777 char *pipeline_name;
5778 uint32_t table_id, n_tokens_parsed;
5779 int clear = 0, status;
5782 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5786 pipeline_name = tokens[1];
5788 if (strcmp(tokens[2], "table") != 0) {
5789 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5793 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5794 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5798 if (strcmp(tokens[4], "rule") != 0) {
5799 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5803 if (strcmp(tokens[5], "read") != 0) {
5804 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5808 if (strcmp(tokens[6], "ttl") != 0) {
5809 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
5817 if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
5825 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5826 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5830 n_tokens_parsed = parse_match(tokens,
5835 if (n_tokens_parsed == 0)
5837 n_tokens -= n_tokens_parsed;
5838 tokens += n_tokens_parsed;
5842 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5846 /* Read table rule TTL stats. */
5847 status = pipeline_table_rule_ttl_read(pipeline_name,
5853 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5858 snprintf(out, out_size, "Packets: %" PRIu64 "\n",
5862 static const char cmd_pipeline_table_rule_time_read_help[] =
5863 "pipeline <pipeline_name> table <table_id> rule read time\n"
5867 cmd_pipeline_table_rule_time_read(char **tokens,
5872 struct table_rule_match m;
5873 char *pipeline_name;
5875 uint32_t table_id, n_tokens_parsed;
5879 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5883 pipeline_name = tokens[1];
5885 if (strcmp(tokens[2], "table") != 0) {
5886 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5890 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
5891 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5895 if (strcmp(tokens[4], "rule") != 0) {
5896 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5900 if (strcmp(tokens[5], "read") != 0) {
5901 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
5905 if (strcmp(tokens[6], "time") != 0) {
5906 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
5914 if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
5915 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
5919 n_tokens_parsed = parse_match(tokens,
5924 if (n_tokens_parsed == 0)
5926 n_tokens -= n_tokens_parsed;
5927 tokens += n_tokens_parsed;
5931 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5935 /* Read table rule timestamp. */
5936 status = pipeline_table_rule_time_read(pipeline_name,
5941 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5946 snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
5949 static const char cmd_thread_pipeline_enable_help[] =
5950 "thread <thread_id> pipeline <pipeline_name> enable\n";
5953 cmd_thread_pipeline_enable(char **tokens,
5958 char *pipeline_name;
5962 if (n_tokens != 5) {
5963 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5967 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
5968 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
5972 if (strcmp(tokens[2], "pipeline") != 0) {
5973 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5977 pipeline_name = tokens[3];
5979 if (strcmp(tokens[4], "enable") != 0) {
5980 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
5984 status = thread_pipeline_enable(thread_id, pipeline_name);
5986 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
5992 static const char cmd_thread_pipeline_disable_help[] =
5993 "thread <thread_id> pipeline <pipeline_name> disable\n";
5996 cmd_thread_pipeline_disable(char **tokens,
6001 char *pipeline_name;
6005 if (n_tokens != 5) {
6006 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6010 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
6011 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
6015 if (strcmp(tokens[2], "pipeline") != 0) {
6016 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
6020 pipeline_name = tokens[3];
6022 if (strcmp(tokens[4], "disable") != 0) {
6023 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
6027 status = thread_pipeline_disable(thread_id, pipeline_name);
6029 snprintf(out, out_size, MSG_CMD_FAIL,
6030 "thread pipeline disable");
6036 cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
6041 if (n_tokens == 0) {
6042 snprintf(out, out_size,
6043 "Type 'help <command>' for details on each command.\n\n"
6044 "List of commands:\n"
6048 "\ttmgr subport profile\n"
6049 "\ttmgr pipe profile\n"
6052 "\ttmgr subport pipe\n"
6055 "\tport in action profile\n"
6056 "\ttable action profile\n"
6058 "\tpipeline port in\n"
6059 "\tpipeline port out\n"
6060 "\tpipeline table\n"
6061 "\tpipeline port in table\n"
6062 "\tpipeline port in stats\n"
6063 "\tpipeline port in enable\n"
6064 "\tpipeline port in disable\n"
6065 "\tpipeline port out stats\n"
6066 "\tpipeline table stats\n"
6067 "\tpipeline table rule add\n"
6068 "\tpipeline table rule add default\n"
6069 "\tpipeline table rule add bulk\n"
6070 "\tpipeline table rule delete\n"
6071 "\tpipeline table rule delete default\n"
6072 "\tpipeline table rule show\n"
6073 "\tpipeline table rule stats read\n"
6074 "\tpipeline table meter profile add\n"
6075 "\tpipeline table meter profile delete\n"
6076 "\tpipeline table rule meter read\n"
6077 "\tpipeline table dscp\n"
6078 "\tpipeline table rule ttl read\n"
6079 "\tpipeline table rule time read\n"
6080 "\tthread pipeline enable\n"
6081 "\tthread pipeline disable\n\n");
6085 if (strcmp(tokens[0], "mempool") == 0) {
6086 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
6090 if (strcmp(tokens[0], "link") == 0) {
6091 snprintf(out, out_size, "\n%s\n", cmd_link_help);
6095 if (strcmp(tokens[0], "swq") == 0) {
6096 snprintf(out, out_size, "\n%s\n", cmd_swq_help);
6100 if (strcmp(tokens[0], "tmgr") == 0) {
6101 if (n_tokens == 1) {
6102 snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
6106 if ((n_tokens == 2) &&
6107 (strcmp(tokens[1], "subport")) == 0) {
6108 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
6112 if ((n_tokens == 3) &&
6113 (strcmp(tokens[1], "subport") == 0) &&
6114 (strcmp(tokens[2], "profile") == 0)) {
6115 snprintf(out, out_size, "\n%s\n",
6116 cmd_tmgr_subport_profile_help);
6120 if ((n_tokens == 3) &&
6121 (strcmp(tokens[1], "subport") == 0) &&
6122 (strcmp(tokens[2], "pipe") == 0)) {
6123 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
6127 if ((n_tokens == 3) &&
6128 (strcmp(tokens[1], "pipe") == 0) &&
6129 (strcmp(tokens[2], "profile") == 0)) {
6130 snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
6135 if (strcmp(tokens[0], "tap") == 0) {
6136 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
6140 if (strcmp(tokens[0], "kni") == 0) {
6141 snprintf(out, out_size, "\n%s\n", cmd_kni_help);
6145 if (strcmp(tokens[0], "cryptodev") == 0) {
6146 snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
6150 if ((n_tokens == 4) &&
6151 (strcmp(tokens[0], "port") == 0) &&
6152 (strcmp(tokens[1], "in") == 0) &&
6153 (strcmp(tokens[2], "action") == 0) &&
6154 (strcmp(tokens[3], "profile") == 0)) {
6155 snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
6159 if ((n_tokens == 3) &&
6160 (strcmp(tokens[0], "table") == 0) &&
6161 (strcmp(tokens[1], "action") == 0) &&
6162 (strcmp(tokens[2], "profile") == 0)) {
6163 snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
6167 if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
6168 snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
6172 if ((strcmp(tokens[0], "pipeline") == 0) &&
6173 (strcmp(tokens[1], "port") == 0)) {
6174 if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
6175 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
6179 if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
6180 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
6184 if ((n_tokens == 4) &&
6185 (strcmp(tokens[2], "in") == 0) &&
6186 (strcmp(tokens[3], "table") == 0)) {
6187 snprintf(out, out_size, "\n%s\n",
6188 cmd_pipeline_port_in_table_help);
6192 if ((n_tokens == 4) &&
6193 (strcmp(tokens[2], "in") == 0) &&
6194 (strcmp(tokens[3], "stats") == 0)) {
6195 snprintf(out, out_size, "\n%s\n",
6196 cmd_pipeline_port_in_stats_help);
6200 if ((n_tokens == 4) &&
6201 (strcmp(tokens[2], "in") == 0) &&
6202 (strcmp(tokens[3], "enable") == 0)) {
6203 snprintf(out, out_size, "\n%s\n",
6204 cmd_pipeline_port_in_enable_help);
6208 if ((n_tokens == 4) &&
6209 (strcmp(tokens[2], "in") == 0) &&
6210 (strcmp(tokens[3], "disable") == 0)) {
6211 snprintf(out, out_size, "\n%s\n",
6212 cmd_pipeline_port_in_disable_help);
6216 if ((n_tokens == 4) &&
6217 (strcmp(tokens[2], "out") == 0) &&
6218 (strcmp(tokens[3], "stats") == 0)) {
6219 snprintf(out, out_size, "\n%s\n",
6220 cmd_pipeline_port_out_stats_help);
6225 if ((strcmp(tokens[0], "pipeline") == 0) &&
6226 (strcmp(tokens[1], "table") == 0)) {
6227 if (n_tokens == 2) {
6228 snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
6232 if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
6233 snprintf(out, out_size, "\n%s\n",
6234 cmd_pipeline_table_stats_help);
6238 if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
6239 snprintf(out, out_size, "\n%s\n",
6240 cmd_pipeline_table_dscp_help);
6244 if ((n_tokens == 4) &&
6245 (strcmp(tokens[2], "rule") == 0) &&
6246 (strcmp(tokens[3], "add") == 0)) {
6247 snprintf(out, out_size, "\n%s\n",
6248 cmd_pipeline_table_rule_add_help);
6252 if ((n_tokens == 5) &&
6253 (strcmp(tokens[2], "rule") == 0) &&
6254 (strcmp(tokens[3], "add") == 0) &&
6255 (strcmp(tokens[4], "default") == 0)) {
6256 snprintf(out, out_size, "\n%s\n",
6257 cmd_pipeline_table_rule_add_default_help);
6261 if ((n_tokens == 5) &&
6262 (strcmp(tokens[2], "rule") == 0) &&
6263 (strcmp(tokens[3], "add") == 0) &&
6264 (strcmp(tokens[4], "bulk") == 0)) {
6265 snprintf(out, out_size, "\n%s\n",
6266 cmd_pipeline_table_rule_add_bulk_help);
6270 if ((n_tokens == 4) &&
6271 (strcmp(tokens[2], "rule") == 0) &&
6272 (strcmp(tokens[3], "delete") == 0)) {
6273 snprintf(out, out_size, "\n%s\n",
6274 cmd_pipeline_table_rule_delete_help);
6278 if ((n_tokens == 5) &&
6279 (strcmp(tokens[2], "rule") == 0) &&
6280 (strcmp(tokens[3], "delete") == 0) &&
6281 (strcmp(tokens[4], "default") == 0)) {
6282 snprintf(out, out_size, "\n%s\n",
6283 cmd_pipeline_table_rule_delete_default_help);
6287 if ((n_tokens == 4) &&
6288 (strcmp(tokens[2], "rule") == 0) &&
6289 (strcmp(tokens[3], "show") == 0)) {
6290 snprintf(out, out_size, "\n%s\n",
6291 cmd_pipeline_table_rule_show_help);
6295 if ((n_tokens == 5) &&
6296 (strcmp(tokens[2], "rule") == 0) &&
6297 (strcmp(tokens[3], "stats") == 0) &&
6298 (strcmp(tokens[4], "read") == 0)) {
6299 snprintf(out, out_size, "\n%s\n",
6300 cmd_pipeline_table_rule_stats_read_help);
6304 if ((n_tokens == 5) &&
6305 (strcmp(tokens[2], "meter") == 0) &&
6306 (strcmp(tokens[3], "profile") == 0) &&
6307 (strcmp(tokens[4], "add") == 0)) {
6308 snprintf(out, out_size, "\n%s\n",
6309 cmd_pipeline_table_meter_profile_add_help);
6313 if ((n_tokens == 5) &&
6314 (strcmp(tokens[2], "meter") == 0) &&
6315 (strcmp(tokens[3], "profile") == 0) &&
6316 (strcmp(tokens[4], "delete") == 0)) {
6317 snprintf(out, out_size, "\n%s\n",
6318 cmd_pipeline_table_meter_profile_delete_help);
6322 if ((n_tokens == 5) &&
6323 (strcmp(tokens[2], "rule") == 0) &&
6324 (strcmp(tokens[3], "meter") == 0) &&
6325 (strcmp(tokens[4], "read") == 0)) {
6326 snprintf(out, out_size, "\n%s\n",
6327 cmd_pipeline_table_rule_meter_read_help);
6331 if ((n_tokens == 5) &&
6332 (strcmp(tokens[2], "rule") == 0) &&
6333 (strcmp(tokens[3], "ttl") == 0) &&
6334 (strcmp(tokens[4], "read") == 0)) {
6335 snprintf(out, out_size, "\n%s\n",
6336 cmd_pipeline_table_rule_ttl_read_help);
6340 if ((n_tokens == 5) &&
6341 (strcmp(tokens[2], "rule") == 0) &&
6342 (strcmp(tokens[3], "time") == 0) &&
6343 (strcmp(tokens[4], "read") == 0)) {
6344 snprintf(out, out_size, "\n%s\n",
6345 cmd_pipeline_table_rule_time_read_help);
6350 if ((n_tokens == 3) &&
6351 (strcmp(tokens[0], "thread") == 0) &&
6352 (strcmp(tokens[1], "pipeline") == 0)) {
6353 if (strcmp(tokens[2], "enable") == 0) {
6354 snprintf(out, out_size, "\n%s\n",
6355 cmd_thread_pipeline_enable_help);
6359 if (strcmp(tokens[2], "disable") == 0) {
6360 snprintf(out, out_size, "\n%s\n",
6361 cmd_thread_pipeline_disable_help);
6366 snprintf(out, out_size, "Invalid command\n");
6370 cli_process(char *in, char *out, size_t out_size)
6372 char *tokens[CMD_MAX_TOKENS];
6373 uint32_t n_tokens = RTE_DIM(tokens);
6379 status = parse_tokenize_string(in, tokens, &n_tokens);
6381 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
6388 if (strcmp(tokens[0], "help") == 0) {
6389 cmd_help(tokens, n_tokens, out, out_size);
6393 if (strcmp(tokens[0], "mempool") == 0) {
6394 cmd_mempool(tokens, n_tokens, out, out_size);
6398 if (strcmp(tokens[0], "link") == 0) {
6399 if (strcmp(tokens[1], "show") == 0) {
6400 cmd_link_show(tokens, n_tokens, out, out_size);
6404 cmd_link(tokens, n_tokens, out, out_size);
6408 if (strcmp(tokens[0], "swq") == 0) {
6409 cmd_swq(tokens, n_tokens, out, out_size);
6413 if (strcmp(tokens[0], "tmgr") == 0) {
6414 if ((n_tokens >= 3) &&
6415 (strcmp(tokens[1], "subport") == 0) &&
6416 (strcmp(tokens[2], "profile") == 0)) {
6417 cmd_tmgr_subport_profile(tokens, n_tokens,
6422 if ((n_tokens >= 3) &&
6423 (strcmp(tokens[1], "pipe") == 0) &&
6424 (strcmp(tokens[2], "profile") == 0)) {
6425 cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
6429 if ((n_tokens >= 5) &&
6430 (strcmp(tokens[2], "subport") == 0) &&
6431 (strcmp(tokens[4], "profile") == 0)) {
6432 cmd_tmgr_subport(tokens, n_tokens, out, out_size);
6436 if ((n_tokens >= 5) &&
6437 (strcmp(tokens[2], "subport") == 0) &&
6438 (strcmp(tokens[4], "pipe") == 0)) {
6439 cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
6443 cmd_tmgr(tokens, n_tokens, out, out_size);
6447 if (strcmp(tokens[0], "tap") == 0) {
6448 cmd_tap(tokens, n_tokens, out, out_size);
6452 if (strcmp(tokens[0], "kni") == 0) {
6453 cmd_kni(tokens, n_tokens, out, out_size);
6457 if (strcmp(tokens[0], "cryptodev") == 0) {
6458 cmd_cryptodev(tokens, n_tokens, out, out_size);
6462 if (strcmp(tokens[0], "port") == 0) {
6463 cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
6467 if (strcmp(tokens[0], "table") == 0) {
6468 cmd_table_action_profile(tokens, n_tokens, out, out_size);
6472 if (strcmp(tokens[0], "pipeline") == 0) {
6473 if ((n_tokens >= 3) &&
6474 (strcmp(tokens[2], "period") == 0)) {
6475 cmd_pipeline(tokens, n_tokens, out, out_size);
6479 if ((n_tokens >= 5) &&
6480 (strcmp(tokens[2], "port") == 0) &&
6481 (strcmp(tokens[3], "in") == 0) &&
6482 (strcmp(tokens[4], "bsz") == 0)) {
6483 cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
6487 if ((n_tokens >= 5) &&
6488 (strcmp(tokens[2], "port") == 0) &&
6489 (strcmp(tokens[3], "out") == 0) &&
6490 (strcmp(tokens[4], "bsz") == 0)) {
6491 cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
6495 if ((n_tokens >= 4) &&
6496 (strcmp(tokens[2], "table") == 0) &&
6497 (strcmp(tokens[3], "match") == 0)) {
6498 cmd_pipeline_table(tokens, n_tokens, out, out_size);
6502 if ((n_tokens >= 6) &&
6503 (strcmp(tokens[2], "port") == 0) &&
6504 (strcmp(tokens[3], "in") == 0) &&
6505 (strcmp(tokens[5], "table") == 0)) {
6506 cmd_pipeline_port_in_table(tokens, n_tokens,
6511 if ((n_tokens >= 6) &&
6512 (strcmp(tokens[2], "port") == 0) &&
6513 (strcmp(tokens[3], "in") == 0) &&
6514 (strcmp(tokens[5], "stats") == 0)) {
6515 cmd_pipeline_port_in_stats(tokens, n_tokens,
6520 if ((n_tokens >= 6) &&
6521 (strcmp(tokens[2], "port") == 0) &&
6522 (strcmp(tokens[3], "in") == 0) &&
6523 (strcmp(tokens[5], "enable") == 0)) {
6524 cmd_pipeline_port_in_enable(tokens, n_tokens,
6529 if ((n_tokens >= 6) &&
6530 (strcmp(tokens[2], "port") == 0) &&
6531 (strcmp(tokens[3], "in") == 0) &&
6532 (strcmp(tokens[5], "disable") == 0)) {
6533 cmd_pipeline_port_in_disable(tokens, n_tokens,
6538 if ((n_tokens >= 6) &&
6539 (strcmp(tokens[2], "port") == 0) &&
6540 (strcmp(tokens[3], "out") == 0) &&
6541 (strcmp(tokens[5], "stats") == 0)) {
6542 cmd_pipeline_port_out_stats(tokens, n_tokens,
6547 if ((n_tokens >= 5) &&
6548 (strcmp(tokens[2], "table") == 0) &&
6549 (strcmp(tokens[4], "stats") == 0)) {
6550 cmd_pipeline_table_stats(tokens, n_tokens,
6555 if ((n_tokens >= 7) &&
6556 (strcmp(tokens[2], "table") == 0) &&
6557 (strcmp(tokens[4], "rule") == 0) &&
6558 (strcmp(tokens[5], "add") == 0) &&
6559 (strcmp(tokens[6], "match") == 0)) {
6560 if ((n_tokens >= 8) &&
6561 (strcmp(tokens[7], "default") == 0)) {
6562 cmd_pipeline_table_rule_add_default(tokens,
6563 n_tokens, out, out_size);
6567 cmd_pipeline_table_rule_add(tokens, n_tokens,
6572 if ((n_tokens >= 7) &&
6573 (strcmp(tokens[2], "table") == 0) &&
6574 (strcmp(tokens[4], "rule") == 0) &&
6575 (strcmp(tokens[5], "add") == 0) &&
6576 (strcmp(tokens[6], "bulk") == 0)) {
6577 cmd_pipeline_table_rule_add_bulk(tokens,
6578 n_tokens, out, out_size);
6582 if ((n_tokens >= 7) &&
6583 (strcmp(tokens[2], "table") == 0) &&
6584 (strcmp(tokens[4], "rule") == 0) &&
6585 (strcmp(tokens[5], "delete") == 0) &&
6586 (strcmp(tokens[6], "match") == 0)) {
6587 if ((n_tokens >= 8) &&
6588 (strcmp(tokens[7], "default") == 0)) {
6589 cmd_pipeline_table_rule_delete_default(tokens,
6590 n_tokens, out, out_size);
6594 cmd_pipeline_table_rule_delete(tokens, n_tokens,
6599 if ((n_tokens >= 6) &&
6600 (strcmp(tokens[2], "table") == 0) &&
6601 (strcmp(tokens[4], "rule") == 0) &&
6602 (strcmp(tokens[5], "show") == 0)) {
6603 cmd_pipeline_table_rule_show(tokens, n_tokens,
6608 if ((n_tokens >= 7) &&
6609 (strcmp(tokens[2], "table") == 0) &&
6610 (strcmp(tokens[4], "rule") == 0) &&
6611 (strcmp(tokens[5], "read") == 0) &&
6612 (strcmp(tokens[6], "stats") == 0)) {
6613 cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
6618 if ((n_tokens >= 8) &&
6619 (strcmp(tokens[2], "table") == 0) &&
6620 (strcmp(tokens[4], "meter") == 0) &&
6621 (strcmp(tokens[5], "profile") == 0) &&
6622 (strcmp(tokens[7], "add") == 0)) {
6623 cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
6628 if ((n_tokens >= 8) &&
6629 (strcmp(tokens[2], "table") == 0) &&
6630 (strcmp(tokens[4], "meter") == 0) &&
6631 (strcmp(tokens[5], "profile") == 0) &&
6632 (strcmp(tokens[7], "delete") == 0)) {
6633 cmd_pipeline_table_meter_profile_delete(tokens,
6634 n_tokens, out, out_size);
6638 if ((n_tokens >= 7) &&
6639 (strcmp(tokens[2], "table") == 0) &&
6640 (strcmp(tokens[4], "rule") == 0) &&
6641 (strcmp(tokens[5], "read") == 0) &&
6642 (strcmp(tokens[6], "meter") == 0)) {
6643 cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
6648 if ((n_tokens >= 5) &&
6649 (strcmp(tokens[2], "table") == 0) &&
6650 (strcmp(tokens[4], "dscp") == 0)) {
6651 cmd_pipeline_table_dscp(tokens, n_tokens,
6656 if ((n_tokens >= 7) &&
6657 (strcmp(tokens[2], "table") == 0) &&
6658 (strcmp(tokens[4], "rule") == 0) &&
6659 (strcmp(tokens[5], "read") == 0) &&
6660 (strcmp(tokens[6], "ttl") == 0)) {
6661 cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
6666 if ((n_tokens >= 7) &&
6667 (strcmp(tokens[2], "table") == 0) &&
6668 (strcmp(tokens[4], "rule") == 0) &&
6669 (strcmp(tokens[5], "read") == 0) &&
6670 (strcmp(tokens[6], "time") == 0)) {
6671 cmd_pipeline_table_rule_time_read(tokens, n_tokens,
6677 if (strcmp(tokens[0], "thread") == 0) {
6678 if ((n_tokens >= 5) &&
6679 (strcmp(tokens[4], "enable") == 0)) {
6680 cmd_thread_pipeline_enable(tokens, n_tokens,
6685 if ((n_tokens >= 5) &&
6686 (strcmp(tokens[4], "disable") == 0)) {
6687 cmd_thread_pipeline_disable(tokens, n_tokens,
6693 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
6697 cli_script_process(const char *file_name,
6698 size_t msg_in_len_max,
6699 size_t msg_out_len_max)
6701 char *msg_in = NULL, *msg_out = NULL;
6704 /* Check input arguments */
6705 if ((file_name == NULL) ||
6706 (strlen(file_name) == 0) ||
6707 (msg_in_len_max == 0) ||
6708 (msg_out_len_max == 0))
6711 msg_in = malloc(msg_in_len_max + 1);
6712 msg_out = malloc(msg_out_len_max + 1);
6713 if ((msg_in == NULL) ||
6714 (msg_out == NULL)) {
6720 /* Open input file */
6721 f = fopen(file_name, "r");
6730 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
6733 printf("%s", msg_in);
6740 if (strlen(msg_out))
6741 printf("%s", msg_out);
6752 cli_rule_file_process(const char *file_name,
6753 size_t line_len_max,
6754 struct table_rule_list **rule_list,
6756 uint32_t *line_number,
6760 struct table_rule_list *list = NULL;
6763 uint32_t rule_id = 0, line_id = 0;
6766 /* Check input arguments */
6767 if ((file_name == NULL) ||
6768 (strlen(file_name) == 0) ||
6769 (line_len_max == 0) ||
6770 (rule_list == NULL) ||
6771 (n_rules == NULL) ||
6772 (line_number == NULL) ||
6775 goto cli_rule_file_process_free;
6778 /* Memory allocation */
6779 list = malloc(sizeof(struct table_rule_list));
6782 goto cli_rule_file_process_free;
6787 line = malloc(line_len_max + 1);
6790 goto cli_rule_file_process_free;
6794 f = fopen(file_name, "r");
6797 goto cli_rule_file_process_free;
6801 for (line_id = 1, rule_id = 0; ; line_id++) {
6802 char *tokens[CMD_MAX_TOKENS];
6803 struct table_rule *rule = NULL;
6804 uint32_t n_tokens, n_tokens_parsed, t0;
6806 /* Read next line from file. */
6807 if (fgets(line, line_len_max + 1, f) == NULL)
6811 if (is_comment(line))
6815 n_tokens = RTE_DIM(tokens);
6816 status = parse_tokenize_string(line, tokens, &n_tokens);
6819 goto cli_rule_file_process_free;
6827 /* Rule alloc and insert. */
6828 rule = calloc(1, sizeof(struct table_rule));
6831 goto cli_rule_file_process_free;
6834 TAILQ_INSERT_TAIL(list, rule, node);
6837 n_tokens_parsed = parse_match(tokens + t0,
6842 if (n_tokens_parsed == 0) {
6844 goto cli_rule_file_process_free;
6846 t0 += n_tokens_parsed;
6849 n_tokens_parsed = parse_table_action(tokens + t0,
6854 if (n_tokens_parsed == 0) {
6856 goto cli_rule_file_process_free;
6858 t0 += n_tokens_parsed;
6860 /* Line completed. */
6861 if (t0 < n_tokens) {
6863 goto cli_rule_file_process_free;
6866 /* Increment rule count */
6878 *line_number = line_id;
6881 cli_rule_file_process_free:
6882 if (rule_list != NULL)
6885 if (n_rules != NULL)
6888 if (line_number != NULL)
6889 *line_number = line_id;
6893 struct table_rule *rule;
6895 rule = TAILQ_FIRST(list);
6899 TAILQ_REMOVE(list, rule, node);