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>
25 #ifndef CMD_MAX_TOKENS
26 #define CMD_MAX_TOKENS 256
29 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
30 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
31 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
32 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
33 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
34 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
35 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
36 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
37 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
38 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
39 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
44 if ((strlen(in) && index("!#%;", in[0])) ||
45 (strncmp(in, "//", 2) == 0) ||
46 (strncmp(in, "--", 2) == 0))
52 static const char cmd_mempool_help[] =
53 "mempool <mempool_name>\n"
54 " buffer <buffer_size>\n"
56 " cache <cache_size>\n"
60 cmd_mempool(char **tokens,
65 struct mempool_params p;
67 struct mempool *mempool;
70 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
76 if (strcmp(tokens[2], "buffer") != 0) {
77 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
81 if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
82 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
86 if (strcmp(tokens[4], "pool") != 0) {
87 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
91 if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
92 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
96 if (strcmp(tokens[6], "cache") != 0) {
97 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
101 if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
102 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
106 if (strcmp(tokens[8], "cpu") != 0) {
107 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
111 if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
112 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
116 mempool = mempool_create(name, &p);
117 if (mempool == NULL) {
118 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
123 static const char cmd_link_help[] =
125 " dev <device_name> | port <port_id>\n"
126 " rxq <n_queues> <queue_size> <mempool_name>\n"
127 " txq <n_queues> <queue_size>\n"
128 " promiscuous on | off\n"
129 " [rss <qid_0> ... <qid_n>]\n";
132 cmd_link(char **tokens,
137 struct link_params p;
138 struct link_params_rss rss;
142 memset(&p, 0, sizeof(p));
144 if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
145 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
150 if (strcmp(tokens[2], "dev") == 0)
151 p.dev_name = tokens[3];
152 else if (strcmp(tokens[2], "port") == 0) {
155 if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
156 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
160 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
164 if (strcmp(tokens[4], "rxq") != 0) {
165 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
169 if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
170 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
173 if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
174 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
178 p.rx.mempool_name = tokens[7];
180 if (strcmp(tokens[8], "txq") != 0) {
181 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
185 if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
186 snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
190 if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
191 snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
195 if (strcmp(tokens[11], "promiscuous") != 0) {
196 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
200 if (strcmp(tokens[12], "on") == 0)
202 else if (strcmp(tokens[12], "off") == 0)
205 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
212 uint32_t queue_id, i;
214 if (strcmp(tokens[13], "rss") != 0) {
215 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
222 for (i = 14; i < n_tokens; i++) {
223 if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
224 snprintf(out, out_size, MSG_ARG_INVALID,
229 rss.queue_id[rss.n_queues] = queue_id;
234 link = link_create(name, &p);
236 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
241 /* Print the link stats and info */
243 print_link_info(struct link *link, char *out, size_t out_size)
245 struct rte_eth_stats stats;
246 struct ether_addr mac_addr;
247 struct rte_eth_link eth_link;
250 memset(&stats, 0, sizeof(stats));
251 rte_eth_stats_get(link->port_id, &stats);
253 rte_eth_macaddr_get(link->port_id, &mac_addr);
254 rte_eth_link_get(link->port_id, ð_link);
255 rte_eth_dev_get_mtu(link->port_id, &mtu);
257 snprintf(out, out_size,
259 "%s: flags=<%s> mtu %u\n"
260 "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
261 "\tport# %u speed %u Mbps\n"
262 "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
263 "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
264 "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
265 "\tTX errors %" PRIu64"\n",
267 eth_link.link_status == 0 ? "DOWN" : "UP",
269 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
270 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
271 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
287 * link show [<link_name>]
290 cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
295 if (n_tokens != 2 && n_tokens != 3) {
296 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
301 link = link_next(NULL);
303 while (link != NULL) {
304 out_size = out_size - strlen(out);
305 out = &out[strlen(out)];
307 print_link_info(link, out, out_size);
308 link = link_next(link);
311 out_size = out_size - strlen(out);
312 out = &out[strlen(out)];
314 link_name = tokens[2];
315 link = link_find(link_name);
318 snprintf(out, out_size, MSG_ARG_INVALID,
319 "Link does not exist");
322 print_link_info(link, out, out_size);
326 static const char cmd_swq_help[] =
332 cmd_swq(char **tokens,
342 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
348 if (strcmp(tokens[2], "size") != 0) {
349 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
353 if (parser_read_uint32(&p.size, tokens[3]) != 0) {
354 snprintf(out, out_size, MSG_ARG_INVALID, "size");
358 if (strcmp(tokens[4], "cpu") != 0) {
359 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
363 if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
364 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
368 swq = swq_create(name, &p);
370 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
375 static const char cmd_tmgr_subport_profile_help[] =
376 "tmgr subport profile\n"
377 " <tb_rate> <tb_size>\n"
378 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n"
382 cmd_tmgr_subport_profile(char **tokens,
387 struct rte_sched_subport_params p;
390 if (n_tokens != 10) {
391 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
395 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
396 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
400 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
401 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
405 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
406 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
407 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
411 if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
412 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
416 status = tmgr_subport_profile_add(&p);
418 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
423 static const char cmd_tmgr_pipe_profile_help[] =
424 "tmgr pipe profile\n"
425 " <tb_rate> <tb_size>\n"
426 " <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n"
429 " <wrr_weight0..15>\n";
432 cmd_tmgr_pipe_profile(char **tokens,
437 struct rte_sched_pipe_params p;
440 if (n_tokens != 27) {
441 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
445 if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
446 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
450 if (parser_read_uint32(&p.tb_size, tokens[4]) != 0) {
451 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
455 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
456 if (parser_read_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
457 snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
461 if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
462 snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
466 #ifdef RTE_SCHED_SUBPORT_TC_OV
467 if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) {
468 snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
473 for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++)
474 if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + i]) != 0) {
475 snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
479 status = tmgr_pipe_profile_add(&p);
481 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
486 static const char cmd_tmgr_help[] =
489 " spp <n_subports_per_port>\n"
490 " pps <n_pipes_per_subport>\n"
491 " qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n"
492 " fo <frame_overhead>\n"
497 cmd_tmgr(char **tokens,
502 struct tmgr_port_params p;
504 struct tmgr_port *tmgr_port;
507 if (n_tokens != 19) {
508 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
514 if (strcmp(tokens[2], "rate") != 0) {
515 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
519 if (parser_read_uint32(&p.rate, tokens[3]) != 0) {
520 snprintf(out, out_size, MSG_ARG_INVALID, "rate");
524 if (strcmp(tokens[4], "spp") != 0) {
525 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
529 if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
530 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
534 if (strcmp(tokens[6], "pps") != 0) {
535 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
539 if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
540 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
544 if (strcmp(tokens[8], "qsize") != 0) {
545 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize");
549 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
550 if (parser_read_uint16(&p.qsize[i], tokens[9 + i]) != 0) {
551 snprintf(out, out_size, MSG_ARG_INVALID, "qsize");
555 if (strcmp(tokens[13], "fo") != 0) {
556 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
560 if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) {
561 snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
565 if (strcmp(tokens[15], "mtu") != 0) {
566 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
570 if (parser_read_uint32(&p.mtu, tokens[16]) != 0) {
571 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
575 if (strcmp(tokens[17], "cpu") != 0) {
576 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
580 if (parser_read_uint32(&p.cpu_id, tokens[18]) != 0) {
581 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
585 tmgr_port = tmgr_port_create(name, &p);
586 if (tmgr_port == NULL) {
587 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
592 static const char cmd_tmgr_subport_help[] =
593 "tmgr <tmgr_name> subport <subport_id>\n"
594 " profile <subport_profile_id>\n";
597 cmd_tmgr_subport(char **tokens,
602 uint32_t subport_id, subport_profile_id;
607 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
613 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
614 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
618 if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
619 snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
623 status = tmgr_subport_config(name, subport_id, subport_profile_id);
625 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
631 static const char cmd_tmgr_subport_pipe_help[] =
632 "tmgr <tmgr_name> subport <subport_id> pipe\n"
633 " from <pipe_id_first> to <pipe_id_last>\n"
634 " profile <pipe_profile_id>\n";
637 cmd_tmgr_subport_pipe(char **tokens,
642 uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
646 if (n_tokens != 11) {
647 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
653 if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
654 snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
658 if (strcmp(tokens[4], "pipe") != 0) {
659 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
663 if (strcmp(tokens[5], "from") != 0) {
664 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
668 if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
669 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
673 if (strcmp(tokens[7], "to") != 0) {
674 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
678 if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
679 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
683 if (strcmp(tokens[9], "profile") != 0) {
684 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
688 if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
689 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
693 status = tmgr_pipe_config(name, subport_id, pipe_id_first,
694 pipe_id_last, pipe_profile_id);
696 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
702 static const char cmd_tap_help[] =
706 cmd_tap(char **tokens,
715 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
721 tap = tap_create(name);
723 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
728 static const char cmd_kni_help[] =
730 " link <link_name>\n"
731 " mempool <mempool_name>\n"
732 " [thread <thread_id>]\n";
735 cmd_kni(char **tokens,
744 memset(&p, 0, sizeof(p));
745 if ((n_tokens != 6) && (n_tokens != 8)) {
746 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
752 if (strcmp(tokens[2], "link") != 0) {
753 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link");
757 p.link_name = tokens[3];
759 if (strcmp(tokens[4], "mempool") != 0) {
760 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool");
764 p.mempool_name = tokens[5];
767 if (strcmp(tokens[6], "thread") != 0) {
768 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread");
772 if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) {
773 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
781 kni = kni_create(name, &p);
783 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
789 static const char cmd_port_in_action_profile_help[] =
790 "port in action profile <profile_name>\n"
791 " [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
792 " [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
795 cmd_port_in_action_profile(char **tokens,
800 struct port_in_action_profile_params p;
801 struct port_in_action_profile *ap;
805 memset(&p, 0, sizeof(p));
808 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
812 if (strcmp(tokens[1], "in") != 0) {
813 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
817 if (strcmp(tokens[2], "action") != 0) {
818 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
822 if (strcmp(tokens[3], "profile") != 0) {
823 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
831 if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
834 if (n_tokens < t0 + 10) {
835 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
839 if (strcmp(tokens[t0 + 1], "match") == 0)
840 p.fltr.filter_on_match = 1;
841 else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
842 p.fltr.filter_on_match = 0;
844 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
848 if (strcmp(tokens[t0 + 2], "offset") != 0) {
849 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
853 if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
854 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
858 if (strcmp(tokens[t0 + 4], "mask") != 0) {
859 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
863 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
864 if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
865 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
866 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
870 if (strcmp(tokens[t0 + 6], "key") != 0) {
871 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
875 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
876 if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
877 (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
878 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
882 if (strcmp(tokens[t0 + 8], "port") != 0) {
883 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
887 if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
888 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
892 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
896 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
899 if (n_tokens < t0 + 22) {
900 snprintf(out, out_size, MSG_ARG_MISMATCH,
901 "port in action profile balance");
905 if (strcmp(tokens[t0 + 1], "offset") != 0) {
906 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
910 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
911 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
915 if (strcmp(tokens[t0 + 3], "mask") != 0) {
916 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
920 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
921 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
922 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
926 if (strcmp(tokens[t0 + 5], "port") != 0) {
927 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
931 for (i = 0; i < 16; i++)
932 if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
933 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
937 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
942 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
946 ap = port_in_action_profile_create(name, &p);
948 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
954 static const char cmd_table_action_profile_help[] =
955 "table action profile <profile_name>\n"
957 " offset <ip_offset>\n"
959 " [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
960 " [meter srtcm | trtcm\n"
962 " stats none | pkts | bytes | both]\n"
963 " [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
964 " [encap ether | vlan | qinq | mpls | pppoe]\n"
966 " proto udp | tcp]\n"
968 " stats none | pkts]\n"
969 " [stats pkts | bytes | both]\n"
973 cmd_table_action_profile(char **tokens,
978 struct table_action_profile_params p;
979 struct table_action_profile *ap;
983 memset(&p, 0, sizeof(p));
986 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
990 if (strcmp(tokens[1], "action") != 0) {
991 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
995 if (strcmp(tokens[2], "profile") != 0) {
996 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1002 if (strcmp(tokens[4], "ipv4") == 0)
1003 p.common.ip_version = 1;
1004 else if (strcmp(tokens[4], "ipv6") == 0)
1005 p.common.ip_version = 0;
1007 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1011 if (strcmp(tokens[5], "offset") != 0) {
1012 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1016 if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
1017 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1021 if (strcmp(tokens[7], "fwd") != 0) {
1022 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1026 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1029 if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
1030 if (n_tokens < t0 + 7) {
1031 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1035 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1036 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1040 if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
1041 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1045 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1046 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1050 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1051 if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
1052 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1056 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1057 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1061 if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
1062 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1066 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1070 if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
1071 if (n_tokens < t0 + 6) {
1072 snprintf(out, out_size, MSG_ARG_MISMATCH,
1073 "table action profile meter");
1077 if (strcmp(tokens[t0 + 1], "srtcm") == 0)
1078 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1079 else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
1080 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1082 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1087 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1088 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1092 if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
1093 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1097 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1098 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1102 if (strcmp(tokens[t0 + 5], "none") == 0) {
1103 p.mtr.n_packets_enabled = 0;
1104 p.mtr.n_bytes_enabled = 0;
1105 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1106 p.mtr.n_packets_enabled = 1;
1107 p.mtr.n_bytes_enabled = 0;
1108 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1109 p.mtr.n_packets_enabled = 0;
1110 p.mtr.n_bytes_enabled = 1;
1111 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1112 p.mtr.n_packets_enabled = 1;
1113 p.mtr.n_bytes_enabled = 1;
1115 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1116 "none or pkts or bytes or both");
1120 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1124 if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
1125 if (n_tokens < t0 + 5) {
1126 snprintf(out, out_size, MSG_ARG_MISMATCH,
1127 "table action profile tm");
1131 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1132 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1136 if (parser_read_uint32(&p.tm.n_subports_per_port,
1137 tokens[t0 + 2]) != 0) {
1138 snprintf(out, out_size, MSG_ARG_INVALID,
1139 "n_subports_per_port");
1143 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1144 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1148 if (parser_read_uint32(&p.tm.n_pipes_per_subport,
1149 tokens[t0 + 4]) != 0) {
1150 snprintf(out, out_size, MSG_ARG_INVALID,
1151 "n_pipes_per_subport");
1155 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1159 if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
1160 if (n_tokens < t0 + 2) {
1161 snprintf(out, out_size, MSG_ARG_MISMATCH,
1162 "action profile encap");
1166 if (strcmp(tokens[t0 + 1], "ether") == 0)
1167 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1168 else if (strcmp(tokens[t0 + 1], "vlan") == 0)
1169 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1170 else if (strcmp(tokens[t0 + 1], "qinq") == 0)
1171 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1172 else if (strcmp(tokens[t0 + 1], "mpls") == 0)
1173 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1174 else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
1175 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1177 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1181 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1185 if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
1186 if (n_tokens < t0 + 4) {
1187 snprintf(out, out_size, MSG_ARG_MISMATCH,
1188 "table action profile nat");
1192 if (strcmp(tokens[t0 + 1], "src") == 0)
1193 p.nat.source_nat = 1;
1194 else if (strcmp(tokens[t0 + 1], "dst") == 0)
1195 p.nat.source_nat = 0;
1197 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1202 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1203 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1207 if (strcmp(tokens[t0 + 3], "tcp") == 0)
1209 else if (strcmp(tokens[t0 + 3], "udp") == 0)
1212 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1217 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1221 if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
1222 if (n_tokens < t0 + 4) {
1223 snprintf(out, out_size, MSG_ARG_MISMATCH,
1224 "table action profile ttl");
1228 if (strcmp(tokens[t0 + 1], "drop") == 0)
1230 else if (strcmp(tokens[t0 + 1], "fwd") == 0)
1233 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1238 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1239 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1243 if (strcmp(tokens[t0 + 3], "none") == 0)
1244 p.ttl.n_packets_enabled = 0;
1245 else if (strcmp(tokens[t0 + 3], "pkts") == 0)
1246 p.ttl.n_packets_enabled = 1;
1248 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1253 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1257 if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
1258 if (n_tokens < t0 + 2) {
1259 snprintf(out, out_size, MSG_ARG_MISMATCH,
1260 "table action profile stats");
1264 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1265 p.stats.n_packets_enabled = 1;
1266 p.stats.n_bytes_enabled = 0;
1267 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1268 p.stats.n_packets_enabled = 0;
1269 p.stats.n_bytes_enabled = 1;
1270 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1271 p.stats.n_packets_enabled = 1;
1272 p.stats.n_bytes_enabled = 1;
1274 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1275 "pkts or bytes or both");
1279 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1283 if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
1284 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1288 if (t0 < n_tokens) {
1289 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1293 ap = table_action_profile_create(name, &p);
1295 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1300 static const char cmd_pipeline_help[] =
1301 "pipeline <pipeline_name>\n"
1302 " period <timer_period_ms>\n"
1303 " offset_port_id <offset_port_id>\n"
1307 cmd_pipeline(char **tokens,
1312 struct pipeline_params p;
1314 struct pipeline *pipeline;
1316 if (n_tokens != 8) {
1317 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1323 if (strcmp(tokens[2], "period") != 0) {
1324 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1328 if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
1329 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1333 if (strcmp(tokens[4], "offset_port_id") != 0) {
1334 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1338 if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
1339 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1343 if (strcmp(tokens[6], "cpu") != 0) {
1344 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
1348 if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
1349 snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
1353 pipeline = pipeline_create(name, &p);
1354 if (pipeline == NULL) {
1355 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1360 static const char cmd_pipeline_port_in_help[] =
1361 "pipeline <pipeline_name> port in\n"
1362 " bsz <burst_size>\n"
1363 " link <link_name> rxq <queue_id>\n"
1364 " | swq <swq_name>\n"
1365 " | tmgr <tmgr_name>\n"
1366 " | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
1367 " | kni <kni_name>\n"
1368 " | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
1369 " [action <port_in_action_profile_name>]\n"
1373 cmd_pipeline_port_in(char **tokens,
1378 struct port_in_params p;
1379 char *pipeline_name;
1381 int enabled, status;
1384 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1388 pipeline_name = tokens[1];
1390 if (strcmp(tokens[2], "port") != 0) {
1391 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1395 if (strcmp(tokens[3], "in") != 0) {
1396 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1400 if (strcmp(tokens[4], "bsz") != 0) {
1401 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1405 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1406 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1412 if (strcmp(tokens[t0], "link") == 0) {
1413 if (n_tokens < t0 + 4) {
1414 snprintf(out, out_size, MSG_ARG_MISMATCH,
1415 "pipeline port in link");
1419 p.type = PORT_IN_RXQ;
1421 p.dev_name = tokens[t0 + 1];
1423 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1428 if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
1429 snprintf(out, out_size, MSG_ARG_INVALID,
1434 } else if (strcmp(tokens[t0], "swq") == 0) {
1435 if (n_tokens < t0 + 2) {
1436 snprintf(out, out_size, MSG_ARG_MISMATCH,
1437 "pipeline port in swq");
1441 p.type = PORT_IN_SWQ;
1443 p.dev_name = tokens[t0 + 1];
1446 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1447 if (n_tokens < t0 + 2) {
1448 snprintf(out, out_size, MSG_ARG_MISMATCH,
1449 "pipeline port in tmgr");
1453 p.type = PORT_IN_TMGR;
1455 p.dev_name = tokens[t0 + 1];
1458 } else if (strcmp(tokens[t0], "tap") == 0) {
1459 if (n_tokens < t0 + 6) {
1460 snprintf(out, out_size, MSG_ARG_MISMATCH,
1461 "pipeline port in tap");
1465 p.type = PORT_IN_TAP;
1467 p.dev_name = tokens[t0 + 1];
1469 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1470 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1475 p.tap.mempool_name = tokens[t0 + 3];
1477 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1478 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1483 if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
1484 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1489 } else if (strcmp(tokens[t0], "kni") == 0) {
1490 if (n_tokens < t0 + 2) {
1491 snprintf(out, out_size, MSG_ARG_MISMATCH,
1492 "pipeline port in kni");
1496 p.type = PORT_IN_KNI;
1498 p.dev_name = tokens[t0 + 1];
1501 } else if (strcmp(tokens[t0], "source") == 0) {
1502 if (n_tokens < t0 + 6) {
1503 snprintf(out, out_size, MSG_ARG_MISMATCH,
1504 "pipeline port in source");
1508 p.type = PORT_IN_SOURCE;
1512 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1513 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1518 p.source.mempool_name = tokens[t0 + 2];
1520 if (strcmp(tokens[t0 + 3], "file") != 0) {
1521 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1526 p.source.file_name = tokens[t0 + 4];
1528 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1529 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1534 if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
1535 snprintf(out, out_size, MSG_ARG_INVALID,
1542 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1546 p.action_profile_name = NULL;
1547 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
1548 if (n_tokens < t0 + 2) {
1549 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1553 p.action_profile_name = tokens[t0 + 1];
1559 if ((n_tokens > t0) &&
1560 (strcmp(tokens[t0], "disabled") == 0)) {
1566 if (n_tokens != t0) {
1567 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1571 status = pipeline_port_in_create(pipeline_name,
1574 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1579 static const char cmd_pipeline_port_out_help[] =
1580 "pipeline <pipeline_name> port out\n"
1581 " bsz <burst_size>\n"
1582 " link <link_name> txq <txq_id>\n"
1583 " | swq <swq_name>\n"
1584 " | tmgr <tmgr_name>\n"
1585 " | tap <tap_name>\n"
1586 " | kni <kni_name>\n"
1587 " | sink [file <file_name> pkts <max_n_pkts>]\n";
1590 cmd_pipeline_port_out(char **tokens,
1595 struct port_out_params p;
1596 char *pipeline_name;
1599 memset(&p, 0, sizeof(p));
1602 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1606 pipeline_name = tokens[1];
1608 if (strcmp(tokens[2], "port") != 0) {
1609 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1613 if (strcmp(tokens[3], "out") != 0) {
1614 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1618 if (strcmp(tokens[4], "bsz") != 0) {
1619 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1623 if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1624 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1628 if (strcmp(tokens[6], "link") == 0) {
1629 if (n_tokens != 10) {
1630 snprintf(out, out_size, MSG_ARG_MISMATCH,
1631 "pipeline port out link");
1635 p.type = PORT_OUT_TXQ;
1637 p.dev_name = tokens[7];
1639 if (strcmp(tokens[8], "txq") != 0) {
1640 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1644 if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
1645 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1648 } else if (strcmp(tokens[6], "swq") == 0) {
1649 if (n_tokens != 8) {
1650 snprintf(out, out_size, MSG_ARG_MISMATCH,
1651 "pipeline port out swq");
1655 p.type = PORT_OUT_SWQ;
1657 p.dev_name = tokens[7];
1658 } else if (strcmp(tokens[6], "tmgr") == 0) {
1659 if (n_tokens != 8) {
1660 snprintf(out, out_size, MSG_ARG_MISMATCH,
1661 "pipeline port out tmgr");
1665 p.type = PORT_OUT_TMGR;
1667 p.dev_name = tokens[7];
1668 } else if (strcmp(tokens[6], "tap") == 0) {
1669 if (n_tokens != 8) {
1670 snprintf(out, out_size, MSG_ARG_MISMATCH,
1671 "pipeline port out tap");
1675 p.type = PORT_OUT_TAP;
1677 p.dev_name = tokens[7];
1678 } else if (strcmp(tokens[6], "kni") == 0) {
1679 if (n_tokens != 8) {
1680 snprintf(out, out_size, MSG_ARG_MISMATCH,
1681 "pipeline port out kni");
1685 p.type = PORT_OUT_KNI;
1687 p.dev_name = tokens[7];
1688 } else if (strcmp(tokens[6], "sink") == 0) {
1689 if ((n_tokens != 7) && (n_tokens != 11)) {
1690 snprintf(out, out_size, MSG_ARG_MISMATCH,
1691 "pipeline port out sink");
1695 p.type = PORT_OUT_SINK;
1699 if (n_tokens == 7) {
1700 p.sink.file_name = NULL;
1701 p.sink.max_n_pkts = 0;
1703 if (strcmp(tokens[7], "file") != 0) {
1704 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1709 p.sink.file_name = tokens[8];
1711 if (strcmp(tokens[9], "pkts") != 0) {
1712 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1716 if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
1717 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1722 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1726 status = pipeline_port_out_create(pipeline_name, &p);
1728 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1733 static const char cmd_pipeline_table_help[] =
1734 "pipeline <pipeline_name> table\n"
1738 " offset <ip_header_offset>\n"
1741 " offset <key_offset>\n"
1746 " mask <key_mask>\n"
1747 " offset <key_offset>\n"
1748 " buckets <n_buckets>\n"
1752 " offset <ip_header_offset>\n"
1755 " [action <table_action_profile_name>]\n";
1758 cmd_pipeline_table(char **tokens,
1763 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1764 struct table_params p;
1765 char *pipeline_name;
1770 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1774 pipeline_name = tokens[1];
1776 if (strcmp(tokens[2], "table") != 0) {
1777 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1781 if (strcmp(tokens[3], "match") != 0) {
1782 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1787 if (strcmp(tokens[t0], "acl") == 0) {
1788 if (n_tokens < t0 + 6) {
1789 snprintf(out, out_size, MSG_ARG_MISMATCH,
1790 "pipeline table acl");
1794 p.match_type = TABLE_ACL;
1796 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
1797 p.match.acl.ip_version = 1;
1798 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
1799 p.match.acl.ip_version = 0;
1801 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1806 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1807 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1811 if (parser_read_uint32(&p.match.acl.ip_header_offset,
1812 tokens[t0 + 3]) != 0) {
1813 snprintf(out, out_size, MSG_ARG_INVALID,
1814 "ip_header_offset");
1818 if (strcmp(tokens[t0 + 4], "size") != 0) {
1819 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1823 if (parser_read_uint32(&p.match.acl.n_rules,
1824 tokens[t0 + 5]) != 0) {
1825 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1830 } else if (strcmp(tokens[t0], "array") == 0) {
1831 if (n_tokens < t0 + 5) {
1832 snprintf(out, out_size, MSG_ARG_MISMATCH,
1833 "pipeline table array");
1837 p.match_type = TABLE_ARRAY;
1839 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1840 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1844 if (parser_read_uint32(&p.match.array.key_offset,
1845 tokens[t0 + 2]) != 0) {
1846 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1850 if (strcmp(tokens[t0 + 3], "size") != 0) {
1851 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1855 if (parser_read_uint32(&p.match.array.n_keys,
1856 tokens[t0 + 4]) != 0) {
1857 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1862 } else if (strcmp(tokens[t0], "hash") == 0) {
1863 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1865 if (n_tokens < t0 + 12) {
1866 snprintf(out, out_size, MSG_ARG_MISMATCH,
1867 "pipeline table hash");
1871 p.match_type = TABLE_HASH;
1873 if (strcmp(tokens[t0 + 1], "ext") == 0)
1874 p.match.hash.extendable_bucket = 1;
1875 else if (strcmp(tokens[t0 + 1], "lru") == 0)
1876 p.match.hash.extendable_bucket = 0;
1878 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1883 if (strcmp(tokens[t0 + 2], "key") != 0) {
1884 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1888 if ((parser_read_uint32(&p.match.hash.key_size,
1889 tokens[t0 + 3]) != 0) ||
1890 (p.match.hash.key_size == 0) ||
1891 (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
1892 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1896 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1897 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1901 if ((parse_hex_string(tokens[t0 + 5],
1902 key_mask, &key_mask_size) != 0) ||
1903 (key_mask_size != p.match.hash.key_size)) {
1904 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1907 p.match.hash.key_mask = key_mask;
1909 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1910 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1914 if (parser_read_uint32(&p.match.hash.key_offset,
1915 tokens[t0 + 7]) != 0) {
1916 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1920 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1921 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1925 if (parser_read_uint32(&p.match.hash.n_buckets,
1926 tokens[t0 + 9]) != 0) {
1927 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1931 if (strcmp(tokens[t0 + 10], "size") != 0) {
1932 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1936 if (parser_read_uint32(&p.match.hash.n_keys,
1937 tokens[t0 + 11]) != 0) {
1938 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1943 } else if (strcmp(tokens[t0], "lpm") == 0) {
1944 if (n_tokens < t0 + 6) {
1945 snprintf(out, out_size, MSG_ARG_MISMATCH,
1946 "pipeline table lpm");
1950 p.match_type = TABLE_LPM;
1952 if (strcmp(tokens[t0 + 1], "ipv4") == 0)
1953 p.match.lpm.key_size = 4;
1954 else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
1955 p.match.lpm.key_size = 16;
1957 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1962 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1963 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1967 if (parser_read_uint32(&p.match.lpm.key_offset,
1968 tokens[t0 + 3]) != 0) {
1969 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1973 if (strcmp(tokens[t0 + 4], "size") != 0) {
1974 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1978 if (parser_read_uint32(&p.match.lpm.n_rules,
1979 tokens[t0 + 5]) != 0) {
1980 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1985 } else if (strcmp(tokens[t0], "stub") == 0) {
1986 p.match_type = TABLE_STUB;
1990 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1994 p.action_profile_name = NULL;
1995 if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
1996 if (n_tokens < t0 + 2) {
1997 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2001 p.action_profile_name = tokens[t0 + 1];
2006 if (n_tokens > t0) {
2007 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2011 status = pipeline_table_create(pipeline_name, &p);
2013 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2018 static const char cmd_pipeline_port_in_table_help[] =
2019 "pipeline <pipeline_name> port in <port_id> table <table_id>\n";
2022 cmd_pipeline_port_in_table(char **tokens,
2027 char *pipeline_name;
2028 uint32_t port_id, table_id;
2031 if (n_tokens != 7) {
2032 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2036 pipeline_name = tokens[1];
2038 if (strcmp(tokens[2], "port") != 0) {
2039 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2043 if (strcmp(tokens[3], "in") != 0) {
2044 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2048 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2049 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2053 if (strcmp(tokens[5], "table") != 0) {
2054 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2058 if (parser_read_uint32(&table_id, tokens[6]) != 0) {
2059 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2063 status = pipeline_port_in_connect_to_table(pipeline_name,
2067 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2073 static const char cmd_pipeline_port_in_stats_help[] =
2074 "pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
2076 #define MSG_PIPELINE_PORT_IN_STATS \
2077 "Pkts in: %" PRIu64 "\n" \
2078 "Pkts dropped by AH: %" PRIu64 "\n" \
2079 "Pkts dropped by other: %" PRIu64 "\n"
2082 cmd_pipeline_port_in_stats(char **tokens,
2087 struct rte_pipeline_port_in_stats stats;
2088 char *pipeline_name;
2092 if ((n_tokens != 7) && (n_tokens != 8)) {
2093 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2097 pipeline_name = tokens[1];
2099 if (strcmp(tokens[2], "port") != 0) {
2100 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2104 if (strcmp(tokens[3], "in") != 0) {
2105 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2109 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2110 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2114 if (strcmp(tokens[5], "stats") != 0) {
2115 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2119 if (strcmp(tokens[6], "read") != 0) {
2120 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2125 if (n_tokens == 8) {
2126 if (strcmp(tokens[7], "clear") != 0) {
2127 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2134 status = pipeline_port_in_stats_read(pipeline_name,
2139 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2143 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2144 stats.stats.n_pkts_in,
2145 stats.n_pkts_dropped_by_ah,
2146 stats.stats.n_pkts_drop);
2150 static const char cmd_pipeline_port_in_enable_help[] =
2151 "pipeline <pipeline_name> port in <port_id> enable\n";
2154 cmd_pipeline_port_in_enable(char **tokens,
2159 char *pipeline_name;
2163 if (n_tokens != 6) {
2164 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2168 pipeline_name = tokens[1];
2170 if (strcmp(tokens[2], "port") != 0) {
2171 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2175 if (strcmp(tokens[3], "in") != 0) {
2176 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2180 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2181 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2185 if (strcmp(tokens[5], "enable") != 0) {
2186 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2190 status = pipeline_port_in_enable(pipeline_name, port_id);
2192 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2198 static const char cmd_pipeline_port_in_disable_help[] =
2199 "pipeline <pipeline_name> port in <port_id> disable\n";
2202 cmd_pipeline_port_in_disable(char **tokens,
2207 char *pipeline_name;
2211 if (n_tokens != 6) {
2212 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2216 pipeline_name = tokens[1];
2218 if (strcmp(tokens[2], "port") != 0) {
2219 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2223 if (strcmp(tokens[3], "in") != 0) {
2224 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2228 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2229 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2233 if (strcmp(tokens[5], "disable") != 0) {
2234 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2238 status = pipeline_port_in_disable(pipeline_name, port_id);
2240 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2246 static const char cmd_pipeline_port_out_stats_help[] =
2247 "pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
2249 #define MSG_PIPELINE_PORT_OUT_STATS \
2250 "Pkts in: %" PRIu64 "\n" \
2251 "Pkts dropped by AH: %" PRIu64 "\n" \
2252 "Pkts dropped by other: %" PRIu64 "\n"
2255 cmd_pipeline_port_out_stats(char **tokens,
2260 struct rte_pipeline_port_out_stats stats;
2261 char *pipeline_name;
2265 if ((n_tokens != 7) && (n_tokens != 8)) {
2266 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2270 pipeline_name = tokens[1];
2272 if (strcmp(tokens[2], "port") != 0) {
2273 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2277 if (strcmp(tokens[3], "out") != 0) {
2278 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2282 if (parser_read_uint32(&port_id, tokens[4]) != 0) {
2283 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2287 if (strcmp(tokens[5], "stats") != 0) {
2288 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2292 if (strcmp(tokens[6], "read") != 0) {
2293 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2298 if (n_tokens == 8) {
2299 if (strcmp(tokens[7], "clear") != 0) {
2300 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2307 status = pipeline_port_out_stats_read(pipeline_name,
2312 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2316 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2317 stats.stats.n_pkts_in,
2318 stats.n_pkts_dropped_by_ah,
2319 stats.stats.n_pkts_drop);
2323 static const char cmd_pipeline_table_stats_help[] =
2324 "pipeline <pipeline_name> table <table_id> stats read [clear]\n";
2326 #define MSG_PIPELINE_TABLE_STATS \
2327 "Pkts in: %" PRIu64 "\n" \
2328 "Pkts in with lookup miss: %" PRIu64 "\n" \
2329 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2330 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2331 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2332 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2335 cmd_pipeline_table_stats(char **tokens,
2340 struct rte_pipeline_table_stats stats;
2341 char *pipeline_name;
2345 if ((n_tokens != 6) && (n_tokens != 7)) {
2346 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2350 pipeline_name = tokens[1];
2352 if (strcmp(tokens[2], "table") != 0) {
2353 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2357 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
2358 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2362 if (strcmp(tokens[4], "stats") != 0) {
2363 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2367 if (strcmp(tokens[5], "read") != 0) {
2368 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2373 if (n_tokens == 7) {
2374 if (strcmp(tokens[6], "clear") != 0) {
2375 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2382 status = pipeline_table_stats_read(pipeline_name,
2387 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2391 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2392 stats.stats.n_pkts_in,
2393 stats.stats.n_pkts_lookup_miss,
2394 stats.n_pkts_dropped_by_lkp_hit_ah,
2395 stats.n_pkts_dropped_lkp_hit,
2396 stats.n_pkts_dropped_by_lkp_miss_ah,
2397 stats.n_pkts_dropped_lkp_miss);
2405 * priority <priority>
2406 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2407 * <sp0> <sp1> <dp0> <dp1> <proto>
2411 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2412 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2413 * | ipv4_addr <addr>
2414 * | ipv6_addr <addr>
2415 * | qinq <svlan> <cvlan>
2417 * ipv4 | ipv6 <addr> <depth>
2419 struct pkt_key_qinq {
2420 uint16_t ethertype_svlan;
2422 uint16_t ethertype_cvlan;
2424 } __attribute__((__packed__));
2426 struct pkt_key_ipv4_5tuple {
2427 uint8_t time_to_live;
2429 uint16_t hdr_checksum;
2434 } __attribute__((__packed__));
2436 struct pkt_key_ipv6_5tuple {
2437 uint16_t payload_length;
2444 } __attribute__((__packed__));
2446 struct pkt_key_ipv4_addr {
2448 } __attribute__((__packed__));
2450 struct pkt_key_ipv6_addr {
2452 } __attribute__((__packed__));
2455 parse_match(char **tokens,
2459 struct table_rule_match *m)
2461 memset(m, 0, sizeof(*m));
2466 if (strcmp(tokens[0], "match") != 0) {
2467 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2471 if (strcmp(tokens[1], "acl") == 0) {
2472 if (n_tokens < 14) {
2473 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2477 m->match_type = TABLE_ACL;
2479 if (strcmp(tokens[2], "priority") != 0) {
2480 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2484 if (parser_read_uint32(&m->match.acl.priority,
2486 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2490 if (strcmp(tokens[4], "ipv4") == 0) {
2491 struct in_addr saddr, daddr;
2493 m->match.acl.ip_version = 1;
2495 if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
2496 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2499 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2501 if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
2502 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2505 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2506 } else if (strcmp(tokens[4], "ipv6") == 0) {
2507 struct in6_addr saddr, daddr;
2509 m->match.acl.ip_version = 0;
2511 if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
2512 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2515 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2517 if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
2518 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2521 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2523 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2528 if (parser_read_uint32(&m->match.acl.sa_depth,
2530 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2534 if (parser_read_uint32(&m->match.acl.da_depth,
2536 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2540 if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2541 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2545 if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2546 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2550 if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2551 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2555 if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2556 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2560 if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2561 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2565 m->match.acl.proto_mask = 0xff;
2570 if (strcmp(tokens[1], "array") == 0) {
2572 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2576 m->match_type = TABLE_ARRAY;
2578 if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2579 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2586 if (strcmp(tokens[1], "hash") == 0) {
2588 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2592 m->match_type = TABLE_HASH;
2594 if (strcmp(tokens[2], "raw") == 0) {
2595 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2598 snprintf(out, out_size, MSG_ARG_MISMATCH,
2603 if (parse_hex_string(tokens[3],
2604 m->match.hash.key, &key_size) != 0) {
2605 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2612 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2613 struct pkt_key_ipv4_5tuple *ipv4 =
2614 (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
2615 struct in_addr saddr, daddr;
2620 snprintf(out, out_size, MSG_ARG_MISMATCH,
2625 if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
2626 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2630 if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
2631 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2635 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2636 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2640 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2641 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2645 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2646 snprintf(out, out_size, MSG_ARG_INVALID,
2651 ipv4->sa = saddr.s_addr;
2652 ipv4->da = daddr.s_addr;
2653 ipv4->sp = rte_cpu_to_be_16(sp);
2654 ipv4->dp = rte_cpu_to_be_16(dp);
2655 ipv4->proto = proto;
2658 } /* hash ipv4_5tuple */
2660 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2661 struct pkt_key_ipv6_5tuple *ipv6 =
2662 (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
2663 struct in6_addr saddr, daddr;
2668 snprintf(out, out_size, MSG_ARG_MISMATCH,
2673 if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
2674 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2678 if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
2679 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2683 if (parser_read_uint16(&sp, tokens[5]) != 0) {
2684 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2688 if (parser_read_uint16(&dp, tokens[6]) != 0) {
2689 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2693 if (parser_read_uint8(&proto, tokens[7]) != 0) {
2694 snprintf(out, out_size, MSG_ARG_INVALID,
2699 memcpy(ipv6->sa, saddr.s6_addr, 16);
2700 memcpy(ipv6->da, daddr.s6_addr, 16);
2701 ipv6->sp = rte_cpu_to_be_16(sp);
2702 ipv6->dp = rte_cpu_to_be_16(dp);
2703 ipv6->proto = proto;
2706 } /* hash ipv6_5tuple */
2708 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2709 struct pkt_key_ipv4_addr *ipv4_addr =
2710 (struct pkt_key_ipv4_addr *) m->match.hash.key;
2711 struct in_addr addr;
2714 snprintf(out, out_size, MSG_ARG_MISMATCH,
2719 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
2720 snprintf(out, out_size, MSG_ARG_INVALID,
2725 ipv4_addr->addr = addr.s_addr;
2728 } /* hash ipv4_addr */
2730 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2731 struct pkt_key_ipv6_addr *ipv6_addr =
2732 (struct pkt_key_ipv6_addr *) m->match.hash.key;
2733 struct in6_addr addr;
2736 snprintf(out, out_size, MSG_ARG_MISMATCH,
2741 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
2742 snprintf(out, out_size, MSG_ARG_INVALID,
2747 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2750 } /* hash ipv6_5tuple */
2752 if (strcmp(tokens[2], "qinq") == 0) {
2753 struct pkt_key_qinq *qinq =
2754 (struct pkt_key_qinq *) m->match.hash.key;
2755 uint16_t svlan, cvlan;
2758 snprintf(out, out_size, MSG_ARG_MISMATCH,
2763 if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
2765 snprintf(out, out_size, MSG_ARG_INVALID,
2770 if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2772 snprintf(out, out_size, MSG_ARG_INVALID,
2777 qinq->svlan = rte_cpu_to_be_16(svlan);
2778 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2783 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2787 if (strcmp(tokens[1], "lpm") == 0) {
2789 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2793 m->match_type = TABLE_LPM;
2795 if (strcmp(tokens[2], "ipv4") == 0) {
2796 struct in_addr addr;
2798 m->match.lpm.ip_version = 1;
2800 if (parse_ipv4_addr(tokens[3], &addr) != 0) {
2801 snprintf(out, out_size, MSG_ARG_INVALID,
2806 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2807 } else if (strcmp(tokens[2], "ipv6") == 0) {
2808 struct in6_addr addr;
2810 m->match.lpm.ip_version = 0;
2812 if (parse_ipv6_addr(tokens[3], &addr) != 0) {
2813 snprintf(out, out_size, MSG_ARG_INVALID,
2818 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2820 snprintf(out, out_size, MSG_ARG_MISMATCH,
2825 if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2826 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2833 snprintf(out, out_size, MSG_ARG_MISMATCH,
2834 "acl or array or hash or lpm");
2846 * | table <table_id>
2847 * [balance <out0> ... <out7>]
2849 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2850 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2851 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2852 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2853 * [tm subport <subport_id> pipe <pipe_id>]
2856 * | vlan <da> <sa> <pcp> <dei> <vid>
2857 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2858 * | mpls unicast | multicast
2860 * label0 <label> <tc> <ttl>
2861 * [label1 <label> <tc> <ttl>
2862 * [label2 <label> <tc> <ttl>
2863 * [label3 <label> <tc> <ttl>]]]
2864 * | pppoe <da> <sa> <session_id>]
2865 * [nat ipv4 | ipv6 <addr> <port>]
2871 * <pa> ::= g | y | r | drop
2874 parse_table_action_fwd(char **tokens,
2876 struct table_rule_action *a)
2878 if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
2884 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2885 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2886 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2890 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2893 if ((n_tokens < 2) ||
2894 parser_read_uint32(&id, tokens[1]))
2897 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2899 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2903 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2904 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2905 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2909 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2912 if ((n_tokens < 2) ||
2913 parser_read_uint32(&id, tokens[1]))
2916 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2918 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2926 parse_table_action_balance(char **tokens,
2928 struct table_rule_action *a)
2932 if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
2938 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2941 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2942 if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2945 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2946 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2951 parse_policer_action(char *token, enum rte_table_action_policer *a)
2953 if (strcmp(token, "g") == 0) {
2954 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2958 if (strcmp(token, "y") == 0) {
2959 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2963 if (strcmp(token, "r") == 0) {
2964 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2968 if (strcmp(token, "drop") == 0) {
2969 *a = RTE_TABLE_ACTION_POLICER_DROP;
2977 parse_table_action_meter_tc(char **tokens,
2979 struct rte_table_action_mtr_tc_params *mtr)
2981 if ((n_tokens < 9) ||
2982 strcmp(tokens[0], "meter") ||
2983 parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2984 strcmp(tokens[2], "policer") ||
2985 strcmp(tokens[3], "g") ||
2986 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2987 strcmp(tokens[5], "y") ||
2988 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2989 strcmp(tokens[7], "r") ||
2990 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2997 parse_table_action_meter(char **tokens,
2999 struct table_rule_action *a)
3001 if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
3007 if ((n_tokens < 10) ||
3008 strcmp(tokens[0], "tc0") ||
3009 (parse_table_action_meter_tc(tokens + 1,
3011 &a->mtr.mtr[0]) == 0))
3017 if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
3019 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3023 if ((n_tokens < 30) ||
3024 (parse_table_action_meter_tc(tokens + 1,
3025 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3026 strcmp(tokens[10], "tc2") ||
3027 (parse_table_action_meter_tc(tokens + 11,
3028 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3029 strcmp(tokens[20], "tc3") ||
3030 (parse_table_action_meter_tc(tokens + 21,
3031 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3034 a->mtr.tc_mask = 0xF;
3035 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3036 return 1 + 10 + 3 * 10;
3040 parse_table_action_tm(char **tokens,
3042 struct table_rule_action *a)
3044 uint32_t subport_id, pipe_id;
3046 if ((n_tokens < 5) ||
3047 strcmp(tokens[0], "tm") ||
3048 strcmp(tokens[1], "subport") ||
3049 parser_read_uint32(&subport_id, tokens[2]) ||
3050 strcmp(tokens[3], "pipe") ||
3051 parser_read_uint32(&pipe_id, tokens[4]))
3054 a->tm.subport_id = subport_id;
3055 a->tm.pipe_id = pipe_id;
3056 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3061 parse_table_action_encap(char **tokens,
3063 struct table_rule_action *a)
3065 if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
3072 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3073 if ((n_tokens < 3) ||
3074 parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3075 parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3078 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3079 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3084 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3085 uint32_t pcp, dei, vid;
3087 if ((n_tokens < 6) ||
3088 parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3089 parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3090 parser_read_uint32(&pcp, tokens[3]) ||
3092 parser_read_uint32(&dei, tokens[4]) ||
3094 parser_read_uint32(&vid, tokens[5]) ||
3098 a->encap.vlan.vlan.pcp = pcp & 0x7;
3099 a->encap.vlan.vlan.dei = dei & 0x1;
3100 a->encap.vlan.vlan.vid = vid & 0xFFF;
3101 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3102 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3107 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3108 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3109 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3111 if ((n_tokens < 9) ||
3112 parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3113 parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3114 parser_read_uint32(&svlan_pcp, tokens[3]) ||
3115 (svlan_pcp > 0x7) ||
3116 parser_read_uint32(&svlan_dei, tokens[4]) ||
3117 (svlan_dei > 0x1) ||
3118 parser_read_uint32(&svlan_vid, tokens[5]) ||
3119 (svlan_vid > 0xFFF) ||
3120 parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3121 (cvlan_pcp > 0x7) ||
3122 parser_read_uint32(&cvlan_dei, tokens[7]) ||
3123 (cvlan_dei > 0x1) ||
3124 parser_read_uint32(&cvlan_vid, tokens[8]) ||
3125 (cvlan_vid > 0xFFF))
3128 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3129 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3130 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3131 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3132 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3133 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3134 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3135 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3140 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3141 uint32_t label, tc, ttl;
3146 if (strcmp(tokens[1], "unicast") == 0)
3147 a->encap.mpls.unicast = 1;
3148 else if (strcmp(tokens[1], "multicast") == 0)
3149 a->encap.mpls.unicast = 0;
3153 if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3154 parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3155 strcmp(tokens[4], "label0") ||
3156 parser_read_uint32(&label, tokens[5]) ||
3157 (label > 0xFFFFF) ||
3158 parser_read_uint32(&tc, tokens[6]) ||
3160 parser_read_uint32(&ttl, tokens[7]) ||
3164 a->encap.mpls.mpls[0].label = label;
3165 a->encap.mpls.mpls[0].tc = tc;
3166 a->encap.mpls.mpls[0].ttl = ttl;
3171 if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
3172 a->encap.mpls.mpls_count = 1;
3173 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3174 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3178 if ((n_tokens < 4) ||
3179 parser_read_uint32(&label, tokens[1]) ||
3180 (label > 0xFFFFF) ||
3181 parser_read_uint32(&tc, tokens[2]) ||
3183 parser_read_uint32(&ttl, tokens[3]) ||
3187 a->encap.mpls.mpls[1].label = label;
3188 a->encap.mpls.mpls[1].tc = tc;
3189 a->encap.mpls.mpls[1].ttl = ttl;
3194 if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
3195 a->encap.mpls.mpls_count = 2;
3196 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3197 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3201 if ((n_tokens < 4) ||
3202 parser_read_uint32(&label, tokens[1]) ||
3203 (label > 0xFFFFF) ||
3204 parser_read_uint32(&tc, tokens[2]) ||
3206 parser_read_uint32(&ttl, tokens[3]) ||
3210 a->encap.mpls.mpls[2].label = label;
3211 a->encap.mpls.mpls[2].tc = tc;
3212 a->encap.mpls.mpls[2].ttl = ttl;
3217 if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
3218 a->encap.mpls.mpls_count = 3;
3219 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3220 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3221 return 1 + 8 + 4 + 4;
3224 if ((n_tokens < 4) ||
3225 parser_read_uint32(&label, tokens[1]) ||
3226 (label > 0xFFFFF) ||
3227 parser_read_uint32(&tc, tokens[2]) ||
3229 parser_read_uint32(&ttl, tokens[3]) ||
3233 a->encap.mpls.mpls[3].label = label;
3234 a->encap.mpls.mpls[3].tc = tc;
3235 a->encap.mpls.mpls[3].ttl = ttl;
3237 a->encap.mpls.mpls_count = 4;
3238 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3239 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3240 return 1 + 8 + 4 + 4 + 4;
3244 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3245 if ((n_tokens < 4) ||
3246 parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3247 parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3248 parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3252 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3253 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3261 parse_table_action_nat(char **tokens,
3263 struct table_rule_action *a)
3265 if ((n_tokens < 4) ||
3266 strcmp(tokens[0], "nat"))
3269 if (strcmp(tokens[1], "ipv4") == 0) {
3270 struct in_addr addr;
3273 if (parse_ipv4_addr(tokens[2], &addr) ||
3274 parser_read_uint16(&port, tokens[3]))
3277 a->nat.ip_version = 1;
3278 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3280 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3284 if (strcmp(tokens[1], "ipv6") == 0) {
3285 struct in6_addr addr;
3288 if (parse_ipv6_addr(tokens[2], &addr) ||
3289 parser_read_uint16(&port, tokens[3]))
3292 a->nat.ip_version = 0;
3293 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3295 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3303 parse_table_action_ttl(char **tokens,
3305 struct table_rule_action *a)
3307 if ((n_tokens < 2) ||
3308 strcmp(tokens[0], "ttl"))
3311 if (strcmp(tokens[1], "dec") == 0)
3312 a->ttl.decrement = 1;
3313 else if (strcmp(tokens[1], "keep") == 0)
3314 a->ttl.decrement = 0;
3318 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3323 parse_table_action_stats(char **tokens,
3325 struct table_rule_action *a)
3327 if ((n_tokens < 1) ||
3328 strcmp(tokens[0], "stats"))
3331 a->stats.n_packets = 0;
3332 a->stats.n_bytes = 0;
3333 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3338 parse_table_action_time(char **tokens,
3340 struct table_rule_action *a)
3342 if ((n_tokens < 1) ||
3343 strcmp(tokens[0], "time"))
3346 a->time.time = rte_rdtsc();
3347 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3352 parse_table_action(char **tokens,
3356 struct table_rule_action *a)
3358 uint32_t n_tokens0 = n_tokens;
3360 memset(a, 0, sizeof(*a));
3362 if ((n_tokens < 2) ||
3363 strcmp(tokens[0], "action"))
3369 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3372 n = parse_table_action_fwd(tokens, n_tokens, a);
3374 snprintf(out, out_size, MSG_ARG_INVALID,
3383 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3386 n = parse_table_action_balance(tokens, n_tokens, a);
3388 snprintf(out, out_size, MSG_ARG_INVALID,
3397 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3400 n = parse_table_action_meter(tokens, n_tokens, a);
3402 snprintf(out, out_size, MSG_ARG_INVALID,
3411 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3414 n = parse_table_action_tm(tokens, n_tokens, a);
3416 snprintf(out, out_size, MSG_ARG_INVALID,
3425 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3428 n = parse_table_action_encap(tokens, n_tokens, a);
3430 snprintf(out, out_size, MSG_ARG_INVALID,
3439 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3442 n = parse_table_action_nat(tokens, n_tokens, a);
3444 snprintf(out, out_size, MSG_ARG_INVALID,
3453 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3456 n = parse_table_action_ttl(tokens, n_tokens, a);
3458 snprintf(out, out_size, MSG_ARG_INVALID,
3467 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3470 n = parse_table_action_stats(tokens, n_tokens, a);
3472 snprintf(out, out_size, MSG_ARG_INVALID,
3481 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3484 n = parse_table_action_time(tokens, n_tokens, a);
3486 snprintf(out, out_size, MSG_ARG_INVALID,
3495 if (n_tokens0 - n_tokens == 1) {
3496 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3500 return n_tokens0 - n_tokens;
3504 static const char cmd_pipeline_table_rule_add_help[] =
3505 "pipeline <pipeline_name> table <table_id> rule add\n"
3507 " action <table_action>\n";
3510 cmd_pipeline_table_rule_add(char **tokens,
3515 struct table_rule_match m;
3516 struct table_rule_action a;
3517 char *pipeline_name;
3519 uint32_t table_id, t0, n_tokens_parsed;
3523 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3527 pipeline_name = tokens[1];
3529 if (strcmp(tokens[2], "table") != 0) {
3530 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3534 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
3535 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3539 if (strcmp(tokens[4], "rule") != 0) {
3540 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3544 if (strcmp(tokens[5], "add") != 0) {
3545 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3552 n_tokens_parsed = parse_match(tokens + t0,
3557 if (n_tokens_parsed == 0)
3559 t0 += n_tokens_parsed;
3562 n_tokens_parsed = parse_table_action(tokens + t0,
3567 if (n_tokens_parsed == 0)
3569 t0 += n_tokens_parsed;
3571 if (t0 != n_tokens) {
3572 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3576 status = pipeline_table_rule_add(pipeline_name, table_id,
3579 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3585 static const char cmd_pipeline_table_rule_add_default_help[] =
3586 "pipeline <pipeline_name> table <table_id> rule add\n"
3592 " | port <port_id>\n"
3594 " | table <table_id>\n";
3597 cmd_pipeline_table_rule_add_default(char **tokens,
3602 struct table_rule_action action;
3604 char *pipeline_name;
3608 if ((n_tokens != 11) && (n_tokens != 12)) {
3609 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3613 pipeline_name = tokens[1];
3615 if (strcmp(tokens[2], "table") != 0) {
3616 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3620 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
3621 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3625 if (strcmp(tokens[4], "rule") != 0) {
3626 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3630 if (strcmp(tokens[5], "add") != 0) {
3631 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3635 if (strcmp(tokens[6], "match") != 0) {
3636 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3640 if (strcmp(tokens[7], "default") != 0) {
3641 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3645 if (strcmp(tokens[8], "action") != 0) {
3646 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3650 if (strcmp(tokens[9], "fwd") != 0) {
3651 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3655 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3657 if (strcmp(tokens[10], "drop") == 0) {
3658 if (n_tokens != 11) {
3659 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3663 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3664 } else if (strcmp(tokens[10], "port") == 0) {
3667 if (n_tokens != 12) {
3668 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3672 if (parser_read_uint32(&id, tokens[11]) != 0) {
3673 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3677 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3679 } else if (strcmp(tokens[10], "meta") == 0) {
3680 if (n_tokens != 11) {
3681 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3685 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3686 } else if (strcmp(tokens[10], "table") == 0) {
3689 if (n_tokens != 12) {
3690 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3694 if (parser_read_uint32(&id, tokens[11]) != 0) {
3695 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3699 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3702 snprintf(out, out_size, MSG_ARG_INVALID,
3703 "drop or port or meta or table");
3707 status = pipeline_table_rule_add_default(pipeline_name,
3712 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3718 static const char cmd_pipeline_table_rule_add_bulk_help[] =
3719 "pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>\n"
3721 " File <file_name>:\n"
3722 " - line format: match <match> action <action>\n";
3725 cli_rule_file_process(const char *file_name,
3726 size_t line_len_max,
3727 struct table_rule_match *m,
3728 struct table_rule_action *a,
3730 uint32_t *line_number,
3735 cmd_pipeline_table_rule_add_bulk(char **tokens,
3740 struct table_rule_match *match;
3741 struct table_rule_action *action;
3743 char *pipeline_name, *file_name;
3744 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3747 if (n_tokens != 9) {
3748 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3752 pipeline_name = tokens[1];
3754 if (strcmp(tokens[2], "table") != 0) {
3755 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3759 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
3760 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3764 if (strcmp(tokens[4], "rule") != 0) {
3765 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3769 if (strcmp(tokens[5], "add") != 0) {
3770 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3774 if (strcmp(tokens[6], "bulk") != 0) {
3775 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3779 file_name = tokens[7];
3781 if ((parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3783 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3787 /* Memory allocation. */
3788 match = calloc(n_rules, sizeof(struct table_rule_match));
3789 action = calloc(n_rules, sizeof(struct table_rule_action));
3790 data = calloc(n_rules, sizeof(void *));
3791 if ((match == NULL) || (action == NULL) || (data == NULL)) {
3792 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3799 /* Load rule file */
3800 n_rules_parsed = n_rules;
3801 status = cli_rule_file_process(file_name,
3810 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3816 if (n_rules_parsed != n_rules) {
3817 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3825 status = pipeline_table_rule_add_bulk(pipeline_name,
3832 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3846 static const char cmd_pipeline_table_rule_delete_help[] =
3847 "pipeline <pipeline_name> table <table_id> rule delete\n"
3851 cmd_pipeline_table_rule_delete(char **tokens,
3856 struct table_rule_match m;
3857 char *pipeline_name;
3858 uint32_t table_id, n_tokens_parsed, t0;
3862 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3866 pipeline_name = tokens[1];
3868 if (strcmp(tokens[2], "table") != 0) {
3869 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3873 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
3874 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3878 if (strcmp(tokens[4], "rule") != 0) {
3879 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3883 if (strcmp(tokens[5], "delete") != 0) {
3884 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3891 n_tokens_parsed = parse_match(tokens + t0,
3896 if (n_tokens_parsed == 0)
3898 t0 += n_tokens_parsed;
3900 if (n_tokens != t0) {
3901 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3905 status = pipeline_table_rule_delete(pipeline_name,
3909 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3915 static const char cmd_pipeline_table_rule_delete_default_help[] =
3916 "pipeline <pipeline_name> table <table_id> rule delete\n"
3921 cmd_pipeline_table_rule_delete_default(char **tokens,
3926 char *pipeline_name;
3930 if (n_tokens != 8) {
3931 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3935 pipeline_name = tokens[1];
3937 if (strcmp(tokens[2], "table") != 0) {
3938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3942 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
3943 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3947 if (strcmp(tokens[4], "rule") != 0) {
3948 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3952 if (strcmp(tokens[5], "delete") != 0) {
3953 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3957 if (strcmp(tokens[6], "match") != 0) {
3958 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3962 if (strcmp(tokens[7], "default") != 0) {
3963 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3967 status = pipeline_table_rule_delete_default(pipeline_name,
3970 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3976 static const char cmd_pipeline_table_rule_stats_read_help[] =
3977 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n";
3980 cmd_pipeline_table_rule_stats_read(char **tokens,
3981 uint32_t n_tokens __rte_unused,
3985 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3989 static const char cmd_pipeline_table_meter_profile_add_help[] =
3990 "pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
3991 " add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
3992 " | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
3995 cmd_pipeline_table_meter_profile_add(char **tokens,
4000 struct rte_table_action_meter_profile p;
4001 char *pipeline_name;
4002 uint32_t table_id, meter_profile_id;
4006 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4010 pipeline_name = tokens[1];
4012 if (strcmp(tokens[2], "table") != 0) {
4013 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4017 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4018 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4022 if (strcmp(tokens[4], "meter") != 0) {
4023 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4027 if (strcmp(tokens[5], "profile") != 0) {
4028 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4032 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4033 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4037 if (strcmp(tokens[7], "add") != 0) {
4038 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4042 if (strcmp(tokens[8], "srtcm") == 0) {
4043 if (n_tokens != 15) {
4044 snprintf(out, out_size, MSG_ARG_MISMATCH,
4049 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
4051 if (strcmp(tokens[9], "cir") != 0) {
4052 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4056 if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
4057 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4061 if (strcmp(tokens[11], "cbs") != 0) {
4062 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4066 if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
4067 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4071 if (strcmp(tokens[13], "ebs") != 0) {
4072 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
4076 if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
4077 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
4080 } else if (strcmp(tokens[8], "trtcm") == 0) {
4081 if (n_tokens != 17) {
4082 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4086 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
4088 if (strcmp(tokens[9], "cir") != 0) {
4089 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4093 if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
4094 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4098 if (strcmp(tokens[11], "pir") != 0) {
4099 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
4103 if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
4104 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
4107 if (strcmp(tokens[13], "cbs") != 0) {
4108 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4112 if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
4113 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4117 if (strcmp(tokens[15], "pbs") != 0) {
4118 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
4122 if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
4123 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
4127 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4131 status = pipeline_table_mtr_profile_add(pipeline_name,
4136 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4142 static const char cmd_pipeline_table_meter_profile_delete_help[] =
4143 "pipeline <pipeline_name> table <table_id>\n"
4144 " meter profile <meter_profile_id> delete\n";
4147 cmd_pipeline_table_meter_profile_delete(char **tokens,
4152 char *pipeline_name;
4153 uint32_t table_id, meter_profile_id;
4156 if (n_tokens != 8) {
4157 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4161 pipeline_name = tokens[1];
4163 if (strcmp(tokens[2], "table") != 0) {
4164 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4168 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4169 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4173 if (strcmp(tokens[4], "meter") != 0) {
4174 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4178 if (strcmp(tokens[5], "profile") != 0) {
4179 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4183 if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4184 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4188 if (strcmp(tokens[7], "delete") != 0) {
4189 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4193 status = pipeline_table_mtr_profile_delete(pipeline_name,
4197 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4203 static const char cmd_pipeline_table_rule_meter_read_help[] =
4204 "pipeline <pipeline_name> table <table_id> rule read meter [clear]\n";
4207 cmd_pipeline_table_rule_meter_read(char **tokens,
4208 uint32_t n_tokens __rte_unused,
4212 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4216 static const char cmd_pipeline_table_dscp_help[] =
4217 "pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
4219 " File <file_name>:\n"
4220 " - exactly 64 lines\n"
4221 " - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
4224 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4225 const char *file_name,
4226 uint32_t *line_number)
4231 /* Check input arguments */
4232 if ((dscp_table == NULL) ||
4233 (file_name == NULL) ||
4234 (line_number == NULL)) {
4240 /* Open input file */
4241 f = fopen(file_name, "r");
4248 for (dscp = 0, l = 1; ; l++) {
4251 enum rte_meter_color color;
4252 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4254 if (fgets(line, sizeof(line), f) == NULL)
4257 if (is_comment(line))
4260 if (parse_tokenize_string(line, tokens, &n_tokens)) {
4269 if ((dscp >= RTE_DIM(dscp_table->entry)) ||
4270 (n_tokens != RTE_DIM(tokens)) ||
4271 parser_read_uint32(&tc_id, tokens[0]) ||
4272 (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
4273 parser_read_uint32(&tc_queue_id, tokens[1]) ||
4274 (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
4275 (strlen(tokens[2]) != 1)) {
4281 switch (tokens[2][0]) {
4284 color = e_RTE_METER_GREEN;
4289 color = e_RTE_METER_YELLOW;
4294 color = e_RTE_METER_RED;
4303 dscp_table->entry[dscp].tc_id = tc_id;
4304 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4305 dscp_table->entry[dscp].color = color;
4315 cmd_pipeline_table_dscp(char **tokens,
4320 struct rte_table_action_dscp_table dscp_table;
4321 char *pipeline_name, *file_name;
4322 uint32_t table_id, line_number;
4325 if (n_tokens != 6) {
4326 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4330 pipeline_name = tokens[1];
4332 if (strcmp(tokens[2], "table") != 0) {
4333 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4337 if (parser_read_uint32(&table_id, tokens[3]) != 0) {
4338 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4342 if (strcmp(tokens[4], "dscp") != 0) {
4343 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4347 file_name = tokens[5];
4349 status = load_dscp_table(&dscp_table, file_name, &line_number);
4351 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4355 status = pipeline_table_dscp_table_update(pipeline_name,
4360 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4366 static const char cmd_pipeline_table_rule_ttl_read_help[] =
4367 "pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n";
4370 cmd_pipeline_table_rule_ttl_read(char **tokens,
4371 uint32_t n_tokens __rte_unused,
4375 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4379 static const char cmd_thread_pipeline_enable_help[] =
4380 "thread <thread_id> pipeline <pipeline_name> enable\n";
4383 cmd_thread_pipeline_enable(char **tokens,
4388 char *pipeline_name;
4392 if (n_tokens != 5) {
4393 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4397 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
4398 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4402 if (strcmp(tokens[2], "pipeline") != 0) {
4403 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4407 pipeline_name = tokens[3];
4409 if (strcmp(tokens[4], "enable") != 0) {
4410 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4414 status = thread_pipeline_enable(thread_id, pipeline_name);
4416 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4422 static const char cmd_thread_pipeline_disable_help[] =
4423 "thread <thread_id> pipeline <pipeline_name> disable\n";
4426 cmd_thread_pipeline_disable(char **tokens,
4431 char *pipeline_name;
4435 if (n_tokens != 5) {
4436 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4440 if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
4441 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4445 if (strcmp(tokens[2], "pipeline") != 0) {
4446 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4450 pipeline_name = tokens[3];
4452 if (strcmp(tokens[4], "disable") != 0) {
4453 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4457 status = thread_pipeline_disable(thread_id, pipeline_name);
4459 snprintf(out, out_size, MSG_CMD_FAIL,
4460 "thread pipeline disable");
4466 cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
4471 if (n_tokens == 0) {
4472 snprintf(out, out_size,
4473 "Type 'help <command>' for details on each command.\n\n"
4474 "List of commands:\n"
4478 "\ttmgr subport profile\n"
4479 "\ttmgr pipe profile\n"
4482 "\ttmgr subport pipe\n"
4485 "\tport in action profile\n"
4486 "\ttable action profile\n"
4488 "\tpipeline port in\n"
4489 "\tpipeline port out\n"
4490 "\tpipeline table\n"
4491 "\tpipeline port in table\n"
4492 "\tpipeline port in stats\n"
4493 "\tpipeline port in enable\n"
4494 "\tpipeline port in disable\n"
4495 "\tpipeline port out stats\n"
4496 "\tpipeline table stats\n"
4497 "\tpipeline table rule add\n"
4498 "\tpipeline table rule add default\n"
4499 "\tpipeline table rule add bulk\n"
4500 "\tpipeline table rule delete\n"
4501 "\tpipeline table rule delete default\n"
4502 "\tpipeline table rule stats read\n"
4503 "\tpipeline table meter profile add\n"
4504 "\tpipeline table meter profile delete\n"
4505 "\tpipeline table rule meter read\n"
4506 "\tpipeline table dscp\n"
4507 "\tpipeline table rule ttl read\n"
4508 "\tthread pipeline enable\n"
4509 "\tthread pipeline disable\n\n");
4513 if (strcmp(tokens[0], "mempool") == 0) {
4514 snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
4518 if (strcmp(tokens[0], "link") == 0) {
4519 snprintf(out, out_size, "\n%s\n", cmd_link_help);
4523 if (strcmp(tokens[0], "swq") == 0) {
4524 snprintf(out, out_size, "\n%s\n", cmd_swq_help);
4528 if (strcmp(tokens[0], "tmgr") == 0) {
4529 if (n_tokens == 1) {
4530 snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
4534 if ((n_tokens == 2) &&
4535 (strcmp(tokens[1], "subport")) == 0) {
4536 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
4540 if ((n_tokens == 3) &&
4541 (strcmp(tokens[1], "subport") == 0) &&
4542 (strcmp(tokens[2], "profile") == 0)) {
4543 snprintf(out, out_size, "\n%s\n",
4544 cmd_tmgr_subport_profile_help);
4548 if ((n_tokens == 3) &&
4549 (strcmp(tokens[1], "subport") == 0) &&
4550 (strcmp(tokens[2], "pipe") == 0)) {
4551 snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
4555 if ((n_tokens == 3) &&
4556 (strcmp(tokens[1], "pipe") == 0) &&
4557 (strcmp(tokens[2], "profile") == 0)) {
4558 snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
4563 if (strcmp(tokens[0], "tap") == 0) {
4564 snprintf(out, out_size, "\n%s\n", cmd_tap_help);
4568 if (strcmp(tokens[0], "kni") == 0) {
4569 snprintf(out, out_size, "\n%s\n", cmd_kni_help);
4573 if ((n_tokens == 4) &&
4574 (strcmp(tokens[0], "port") == 0) &&
4575 (strcmp(tokens[1], "in") == 0) &&
4576 (strcmp(tokens[2], "action") == 0) &&
4577 (strcmp(tokens[3], "profile") == 0)) {
4578 snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
4582 if ((n_tokens == 3) &&
4583 (strcmp(tokens[0], "table") == 0) &&
4584 (strcmp(tokens[1], "action") == 0) &&
4585 (strcmp(tokens[2], "profile") == 0)) {
4586 snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
4590 if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
4591 snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
4595 if ((strcmp(tokens[0], "pipeline") == 0) &&
4596 (strcmp(tokens[1], "port") == 0)) {
4597 if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
4598 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
4602 if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
4603 snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
4607 if ((n_tokens == 4) &&
4608 (strcmp(tokens[2], "in") == 0) &&
4609 (strcmp(tokens[3], "table") == 0)) {
4610 snprintf(out, out_size, "\n%s\n",
4611 cmd_pipeline_port_in_table_help);
4615 if ((n_tokens == 4) &&
4616 (strcmp(tokens[2], "in") == 0) &&
4617 (strcmp(tokens[3], "stats") == 0)) {
4618 snprintf(out, out_size, "\n%s\n",
4619 cmd_pipeline_port_in_stats_help);
4623 if ((n_tokens == 4) &&
4624 (strcmp(tokens[2], "in") == 0) &&
4625 (strcmp(tokens[3], "enable") == 0)) {
4626 snprintf(out, out_size, "\n%s\n",
4627 cmd_pipeline_port_in_enable_help);
4631 if ((n_tokens == 4) &&
4632 (strcmp(tokens[2], "in") == 0) &&
4633 (strcmp(tokens[3], "disable") == 0)) {
4634 snprintf(out, out_size, "\n%s\n",
4635 cmd_pipeline_port_in_disable_help);
4639 if ((n_tokens == 4) &&
4640 (strcmp(tokens[2], "out") == 0) &&
4641 (strcmp(tokens[3], "stats") == 0)) {
4642 snprintf(out, out_size, "\n%s\n",
4643 cmd_pipeline_port_out_stats_help);
4648 if ((strcmp(tokens[0], "pipeline") == 0) &&
4649 (strcmp(tokens[1], "table") == 0)) {
4650 if (n_tokens == 2) {
4651 snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
4655 if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
4656 snprintf(out, out_size, "\n%s\n",
4657 cmd_pipeline_table_stats_help);
4661 if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
4662 snprintf(out, out_size, "\n%s\n",
4663 cmd_pipeline_table_dscp_help);
4667 if ((n_tokens == 4) &&
4668 (strcmp(tokens[2], "rule") == 0) &&
4669 (strcmp(tokens[3], "add") == 0)) {
4670 snprintf(out, out_size, "\n%s\n",
4671 cmd_pipeline_table_rule_add_help);
4675 if ((n_tokens == 5) &&
4676 (strcmp(tokens[2], "rule") == 0) &&
4677 (strcmp(tokens[3], "add") == 0) &&
4678 (strcmp(tokens[4], "default") == 0)) {
4679 snprintf(out, out_size, "\n%s\n",
4680 cmd_pipeline_table_rule_add_default_help);
4684 if ((n_tokens == 5) &&
4685 (strcmp(tokens[2], "rule") == 0) &&
4686 (strcmp(tokens[3], "add") == 0) &&
4687 (strcmp(tokens[4], "bulk") == 0)) {
4688 snprintf(out, out_size, "\n%s\n",
4689 cmd_pipeline_table_rule_add_bulk_help);
4693 if ((n_tokens == 4) &&
4694 (strcmp(tokens[2], "rule") == 0) &&
4695 (strcmp(tokens[3], "delete") == 0)) {
4696 snprintf(out, out_size, "\n%s\n",
4697 cmd_pipeline_table_rule_delete_help);
4701 if ((n_tokens == 5) &&
4702 (strcmp(tokens[2], "rule") == 0) &&
4703 (strcmp(tokens[3], "delete") == 0) &&
4704 (strcmp(tokens[4], "default") == 0)) {
4705 snprintf(out, out_size, "\n%s\n",
4706 cmd_pipeline_table_rule_delete_default_help);
4710 if ((n_tokens == 5) &&
4711 (strcmp(tokens[2], "rule") == 0) &&
4712 (strcmp(tokens[3], "stats") == 0) &&
4713 (strcmp(tokens[4], "read") == 0)) {
4714 snprintf(out, out_size, "\n%s\n",
4715 cmd_pipeline_table_rule_stats_read_help);
4719 if ((n_tokens == 5) &&
4720 (strcmp(tokens[2], "meter") == 0) &&
4721 (strcmp(tokens[3], "profile") == 0) &&
4722 (strcmp(tokens[4], "add") == 0)) {
4723 snprintf(out, out_size, "\n%s\n",
4724 cmd_pipeline_table_meter_profile_add_help);
4728 if ((n_tokens == 5) &&
4729 (strcmp(tokens[2], "meter") == 0) &&
4730 (strcmp(tokens[3], "profile") == 0) &&
4731 (strcmp(tokens[4], "delete") == 0)) {
4732 snprintf(out, out_size, "\n%s\n",
4733 cmd_pipeline_table_meter_profile_delete_help);
4737 if ((n_tokens == 5) &&
4738 (strcmp(tokens[2], "rule") == 0) &&
4739 (strcmp(tokens[3], "meter") == 0) &&
4740 (strcmp(tokens[4], "read") == 0)) {
4741 snprintf(out, out_size, "\n%s\n",
4742 cmd_pipeline_table_rule_meter_read_help);
4746 if ((n_tokens == 5) &&
4747 (strcmp(tokens[2], "rule") == 0) &&
4748 (strcmp(tokens[3], "ttl") == 0) &&
4749 (strcmp(tokens[4], "read") == 0)) {
4750 snprintf(out, out_size, "\n%s\n",
4751 cmd_pipeline_table_rule_ttl_read_help);
4756 if ((n_tokens == 3) &&
4757 (strcmp(tokens[0], "thread") == 0) &&
4758 (strcmp(tokens[1], "pipeline") == 0)) {
4759 if (strcmp(tokens[2], "enable") == 0) {
4760 snprintf(out, out_size, "\n%s\n",
4761 cmd_thread_pipeline_enable_help);
4765 if (strcmp(tokens[2], "disable") == 0) {
4766 snprintf(out, out_size, "\n%s\n",
4767 cmd_thread_pipeline_disable_help);
4772 snprintf(out, out_size, "Invalid command\n");
4776 cli_process(char *in, char *out, size_t out_size)
4778 char *tokens[CMD_MAX_TOKENS];
4779 uint32_t n_tokens = RTE_DIM(tokens);
4785 status = parse_tokenize_string(in, tokens, &n_tokens);
4787 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4794 if (strcmp(tokens[0], "help") == 0) {
4795 cmd_help(tokens, n_tokens, out, out_size);
4799 if (strcmp(tokens[0], "mempool") == 0) {
4800 cmd_mempool(tokens, n_tokens, out, out_size);
4804 if (strcmp(tokens[0], "link") == 0) {
4805 if (strcmp(tokens[1], "show") == 0) {
4806 cmd_link_show(tokens, n_tokens, out, out_size);
4810 cmd_link(tokens, n_tokens, out, out_size);
4814 if (strcmp(tokens[0], "swq") == 0) {
4815 cmd_swq(tokens, n_tokens, out, out_size);
4819 if (strcmp(tokens[0], "tmgr") == 0) {
4820 if ((n_tokens >= 3) &&
4821 (strcmp(tokens[1], "subport") == 0) &&
4822 (strcmp(tokens[2], "profile") == 0)) {
4823 cmd_tmgr_subport_profile(tokens, n_tokens,
4828 if ((n_tokens >= 3) &&
4829 (strcmp(tokens[1], "pipe") == 0) &&
4830 (strcmp(tokens[2], "profile") == 0)) {
4831 cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
4835 if ((n_tokens >= 5) &&
4836 (strcmp(tokens[2], "subport") == 0) &&
4837 (strcmp(tokens[4], "profile") == 0)) {
4838 cmd_tmgr_subport(tokens, n_tokens, out, out_size);
4842 if ((n_tokens >= 5) &&
4843 (strcmp(tokens[2], "subport") == 0) &&
4844 (strcmp(tokens[4], "pipe") == 0)) {
4845 cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
4849 cmd_tmgr(tokens, n_tokens, out, out_size);
4853 if (strcmp(tokens[0], "tap") == 0) {
4854 cmd_tap(tokens, n_tokens, out, out_size);
4858 if (strcmp(tokens[0], "kni") == 0) {
4859 cmd_kni(tokens, n_tokens, out, out_size);
4863 if (strcmp(tokens[0], "port") == 0) {
4864 cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
4868 if (strcmp(tokens[0], "table") == 0) {
4869 cmd_table_action_profile(tokens, n_tokens, out, out_size);
4873 if (strcmp(tokens[0], "pipeline") == 0) {
4874 if ((n_tokens >= 3) &&
4875 (strcmp(tokens[2], "period") == 0)) {
4876 cmd_pipeline(tokens, n_tokens, out, out_size);
4880 if ((n_tokens >= 5) &&
4881 (strcmp(tokens[2], "port") == 0) &&
4882 (strcmp(tokens[3], "in") == 0) &&
4883 (strcmp(tokens[4], "bsz") == 0)) {
4884 cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
4888 if ((n_tokens >= 5) &&
4889 (strcmp(tokens[2], "port") == 0) &&
4890 (strcmp(tokens[3], "out") == 0) &&
4891 (strcmp(tokens[4], "bsz") == 0)) {
4892 cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
4896 if ((n_tokens >= 4) &&
4897 (strcmp(tokens[2], "table") == 0) &&
4898 (strcmp(tokens[3], "match") == 0)) {
4899 cmd_pipeline_table(tokens, n_tokens, out, out_size);
4903 if ((n_tokens >= 6) &&
4904 (strcmp(tokens[2], "port") == 0) &&
4905 (strcmp(tokens[3], "in") == 0) &&
4906 (strcmp(tokens[5], "table") == 0)) {
4907 cmd_pipeline_port_in_table(tokens, n_tokens,
4912 if ((n_tokens >= 6) &&
4913 (strcmp(tokens[2], "port") == 0) &&
4914 (strcmp(tokens[3], "in") == 0) &&
4915 (strcmp(tokens[5], "stats") == 0)) {
4916 cmd_pipeline_port_in_stats(tokens, n_tokens,
4921 if ((n_tokens >= 6) &&
4922 (strcmp(tokens[2], "port") == 0) &&
4923 (strcmp(tokens[3], "in") == 0) &&
4924 (strcmp(tokens[5], "enable") == 0)) {
4925 cmd_pipeline_port_in_enable(tokens, n_tokens,
4930 if ((n_tokens >= 6) &&
4931 (strcmp(tokens[2], "port") == 0) &&
4932 (strcmp(tokens[3], "in") == 0) &&
4933 (strcmp(tokens[5], "disable") == 0)) {
4934 cmd_pipeline_port_in_disable(tokens, n_tokens,
4939 if ((n_tokens >= 6) &&
4940 (strcmp(tokens[2], "port") == 0) &&
4941 (strcmp(tokens[3], "out") == 0) &&
4942 (strcmp(tokens[5], "stats") == 0)) {
4943 cmd_pipeline_port_out_stats(tokens, n_tokens,
4948 if ((n_tokens >= 5) &&
4949 (strcmp(tokens[2], "table") == 0) &&
4950 (strcmp(tokens[4], "stats") == 0)) {
4951 cmd_pipeline_table_stats(tokens, n_tokens,
4956 if ((n_tokens >= 7) &&
4957 (strcmp(tokens[2], "table") == 0) &&
4958 (strcmp(tokens[4], "rule") == 0) &&
4959 (strcmp(tokens[5], "add") == 0) &&
4960 (strcmp(tokens[6], "match") == 0)) {
4961 if ((n_tokens >= 8) &&
4962 (strcmp(tokens[7], "default") == 0)) {
4963 cmd_pipeline_table_rule_add_default(tokens,
4964 n_tokens, out, out_size);
4968 cmd_pipeline_table_rule_add(tokens, n_tokens,
4973 if ((n_tokens >= 7) &&
4974 (strcmp(tokens[2], "table") == 0) &&
4975 (strcmp(tokens[4], "rule") == 0) &&
4976 (strcmp(tokens[5], "add") == 0) &&
4977 (strcmp(tokens[6], "bulk") == 0)) {
4978 cmd_pipeline_table_rule_add_bulk(tokens,
4979 n_tokens, out, out_size);
4983 if ((n_tokens >= 7) &&
4984 (strcmp(tokens[2], "table") == 0) &&
4985 (strcmp(tokens[4], "rule") == 0) &&
4986 (strcmp(tokens[5], "delete") == 0) &&
4987 (strcmp(tokens[6], "match") == 0)) {
4988 if ((n_tokens >= 8) &&
4989 (strcmp(tokens[7], "default") == 0)) {
4990 cmd_pipeline_table_rule_delete_default(tokens,
4991 n_tokens, out, out_size);
4995 cmd_pipeline_table_rule_delete(tokens, n_tokens,
5000 if ((n_tokens >= 7) &&
5001 (strcmp(tokens[2], "table") == 0) &&
5002 (strcmp(tokens[4], "rule") == 0) &&
5003 (strcmp(tokens[5], "read") == 0) &&
5004 (strcmp(tokens[6], "stats") == 0)) {
5005 cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
5010 if ((n_tokens >= 8) &&
5011 (strcmp(tokens[2], "table") == 0) &&
5012 (strcmp(tokens[4], "meter") == 0) &&
5013 (strcmp(tokens[5], "profile") == 0) &&
5014 (strcmp(tokens[7], "add") == 0)) {
5015 cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
5020 if ((n_tokens >= 8) &&
5021 (strcmp(tokens[2], "table") == 0) &&
5022 (strcmp(tokens[4], "meter") == 0) &&
5023 (strcmp(tokens[5], "profile") == 0) &&
5024 (strcmp(tokens[7], "delete") == 0)) {
5025 cmd_pipeline_table_meter_profile_delete(tokens,
5026 n_tokens, out, out_size);
5030 if ((n_tokens >= 7) &&
5031 (strcmp(tokens[2], "table") == 0) &&
5032 (strcmp(tokens[4], "rule") == 0) &&
5033 (strcmp(tokens[5], "read") == 0) &&
5034 (strcmp(tokens[6], "meter") == 0)) {
5035 cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
5040 if ((n_tokens >= 5) &&
5041 (strcmp(tokens[2], "table") == 0) &&
5042 (strcmp(tokens[4], "dscp") == 0)) {
5043 cmd_pipeline_table_dscp(tokens, n_tokens,
5048 if ((n_tokens >= 7) &&
5049 (strcmp(tokens[2], "table") == 0) &&
5050 (strcmp(tokens[4], "rule") == 0) &&
5051 (strcmp(tokens[5], "read") == 0) &&
5052 (strcmp(tokens[6], "ttl") == 0)) {
5053 cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
5059 if (strcmp(tokens[0], "thread") == 0) {
5060 if ((n_tokens >= 5) &&
5061 (strcmp(tokens[4], "enable") == 0)) {
5062 cmd_thread_pipeline_enable(tokens, n_tokens,
5067 if ((n_tokens >= 5) &&
5068 (strcmp(tokens[4], "disable") == 0)) {
5069 cmd_thread_pipeline_disable(tokens, n_tokens,
5075 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5079 cli_script_process(const char *file_name,
5080 size_t msg_in_len_max,
5081 size_t msg_out_len_max)
5083 char *msg_in = NULL, *msg_out = NULL;
5086 /* Check input arguments */
5087 if ((file_name == NULL) ||
5088 (strlen(file_name) == 0) ||
5089 (msg_in_len_max == 0) ||
5090 (msg_out_len_max == 0))
5093 msg_in = malloc(msg_in_len_max + 1);
5094 msg_out = malloc(msg_out_len_max + 1);
5095 if ((msg_in == NULL) ||
5096 (msg_out == NULL)) {
5102 /* Open input file */
5103 f = fopen(file_name, "r");
5112 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5115 printf("%s", msg_in);
5122 if (strlen(msg_out))
5123 printf("%s", msg_out);
5134 cli_rule_file_process(const char *file_name,
5135 size_t line_len_max,
5136 struct table_rule_match *m,
5137 struct table_rule_action *a,
5139 uint32_t *line_number,
5145 uint32_t rule_id, line_id;
5148 /* Check input arguments */
5149 if ((file_name == NULL) ||
5150 (strlen(file_name) == 0) ||
5151 (line_len_max == 0)) {
5156 /* Memory allocation */
5157 line = malloc(line_len_max + 1);
5164 f = fopen(file_name, "r");
5172 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
5173 char *tokens[CMD_MAX_TOKENS];
5174 uint32_t n_tokens, n_tokens_parsed, t0;
5176 /* Read next line from file. */
5177 if (fgets(line, line_len_max + 1, f) == NULL)
5181 if (is_comment(line))
5185 n_tokens = RTE_DIM(tokens);
5186 status = parse_tokenize_string(line, tokens, &n_tokens);
5198 n_tokens_parsed = parse_match(tokens + t0,
5203 if (n_tokens_parsed == 0) {
5207 t0 += n_tokens_parsed;
5210 n_tokens_parsed = parse_table_action(tokens + t0,
5215 if (n_tokens_parsed == 0) {
5219 t0 += n_tokens_parsed;
5221 /* Line completed. */
5222 if (t0 < n_tokens) {
5227 /* Increment rule count */
5238 *line_number = line_id;