1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_cycles.h>
13 #include "rte_eth_softnic_internals.h"
16 #ifndef CMD_MAX_TOKENS
17 #define CMD_MAX_TOKENS 256
20 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
21 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
22 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
23 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
24 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
25 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
26 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
27 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
28 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
29 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
30 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
35 if ((strlen(in) && index("!#%;", in[0])) ||
36 (strncmp(in, "//", 2) == 0) ||
37 (strncmp(in, "--", 2) == 0))
44 * mempool <mempool_name>
45 * buffer <buffer_size>
50 cmd_mempool(struct pmd_internals *softnic,
56 struct softnic_mempool_params p;
58 struct softnic_mempool *mempool;
61 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
67 if (strcmp(tokens[2], "buffer") != 0) {
68 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
72 if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
73 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
77 if (strcmp(tokens[4], "pool") != 0) {
78 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
82 if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
83 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
87 if (strcmp(tokens[6], "cache") != 0) {
88 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
92 if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
93 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
97 mempool = softnic_mempool_create(softnic, name, &p);
98 if (mempool == NULL) {
99 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
106 * dev <device_name> | port <port_id>
109 cmd_link(struct pmd_internals *softnic,
115 struct softnic_link_params p;
116 struct softnic_link *link;
119 memset(&p, 0, sizeof(p));
122 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
127 if (strcmp(tokens[2], "dev") == 0) {
128 p.dev_name = tokens[3];
129 } else if (strcmp(tokens[2], "port") == 0) {
132 if (softnic_parser_read_uint16(&p.port_id, tokens[3]) != 0) {
133 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
137 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
141 link = softnic_link_create(softnic, name, &p);
143 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
153 cmd_swq(struct pmd_internals *softnic,
159 struct softnic_swq_params p;
161 struct softnic_swq *swq;
164 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
170 if (strcmp(tokens[2], "size") != 0) {
171 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
175 if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
176 snprintf(out, out_size, MSG_ARG_INVALID, "size");
180 swq = softnic_swq_create(softnic, name, &p);
182 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
188 * tmgr shaper profile
190 * rate <tb_rate> size <tb_size>
191 * adj <packet_length_adjust>
194 cmd_tmgr_shaper_profile(struct pmd_internals *softnic,
200 struct rte_tm_shaper_params sp;
201 struct rte_tm_error error;
202 uint32_t shaper_profile_id;
206 memset(&sp, 0, sizeof(struct rte_tm_shaper_params));
208 if (n_tokens != 11) {
209 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
213 if (strcmp(tokens[1], "shaper") != 0) {
214 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
218 if (strcmp(tokens[2], "profile") != 0) {
219 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
223 if (strcmp(tokens[3], "id") != 0) {
224 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
228 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[4]) != 0) {
229 snprintf(out, out_size, MSG_ARG_INVALID, "profile_id");
233 if (strcmp(tokens[5], "rate") != 0) {
234 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
238 if (softnic_parser_read_uint64(&sp.peak.rate, tokens[6]) != 0) {
239 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
243 if (strcmp(tokens[7], "size") != 0) {
244 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
248 if (softnic_parser_read_uint64(&sp.peak.size, tokens[8]) != 0) {
249 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
253 if (strcmp(tokens[9], "adj") != 0) {
254 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "adj");
258 if (softnic_parser_read_int32(&sp.pkt_length_adjust, tokens[10]) != 0) {
259 snprintf(out, out_size, MSG_ARG_INVALID, "packet_length_adjust");
263 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
267 status = rte_tm_shaper_profile_add(port_id, shaper_profile_id, &sp, &error);
269 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
276 * id <shared_shaper_id>
277 * profile <shaper_profile_id>
280 cmd_tmgr_shared_shaper(struct pmd_internals *softnic,
286 struct rte_tm_error error;
287 uint32_t shared_shaper_id, shaper_profile_id;
292 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
296 if (strcmp(tokens[1], "shared") != 0) {
297 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared");
301 if (strcmp(tokens[2], "shaper") != 0) {
302 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
306 if (strcmp(tokens[3], "id") != 0) {
307 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
311 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[4]) != 0) {
312 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
316 if (strcmp(tokens[5], "profile") != 0) {
317 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
321 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[6]) != 0) {
322 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
326 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
330 status = rte_tm_shared_shaper_add_update(port_id,
335 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
343 * parent <parent_node_id | none>
344 * priority <priority>
346 * [shaper profile <shaper_profile_id>]
347 * [shared shaper <shared_shaper_id>]
348 * [nonleaf sp <n_sp_priorities>]
351 cmd_tmgr_node(struct pmd_internals *softnic,
357 struct rte_tm_error error;
358 struct rte_tm_node_params np;
359 uint32_t node_id, parent_node_id, priority, weight, shared_shaper_id;
363 memset(&np, 0, sizeof(struct rte_tm_node_params));
364 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
365 np.nonleaf.n_sp_priorities = 1;
368 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
372 if (strcmp(tokens[1], "node") != 0) {
373 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "node");
377 if (strcmp(tokens[2], "id") != 0) {
378 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
382 if (softnic_parser_read_uint32(&node_id, tokens[3]) != 0) {
383 snprintf(out, out_size, MSG_ARG_INVALID, "node_id");
387 if (strcmp(tokens[4], "parent") != 0) {
388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "parent");
392 if (strcmp(tokens[5], "none") == 0)
393 parent_node_id = RTE_TM_NODE_ID_NULL;
395 if (softnic_parser_read_uint32(&parent_node_id, tokens[5]) != 0) {
396 snprintf(out, out_size, MSG_ARG_INVALID, "parent_node_id");
401 if (strcmp(tokens[6], "priority") != 0) {
402 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
406 if (softnic_parser_read_uint32(&priority, tokens[7]) != 0) {
407 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
411 if (strcmp(tokens[8], "weight") != 0) {
412 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight");
416 if (softnic_parser_read_uint32(&weight, tokens[9]) != 0) {
417 snprintf(out, out_size, MSG_ARG_INVALID, "weight");
425 (strcmp(tokens[0], "shaper") == 0) &&
426 (strcmp(tokens[1], "profile") == 0)) {
428 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
432 if (strcmp(tokens[2], "none") == 0) {
433 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
435 if (softnic_parser_read_uint32(&np.shaper_profile_id, tokens[2]) != 0) {
436 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
443 } /* shaper profile */
446 (strcmp(tokens[0], "shared") == 0) &&
447 (strcmp(tokens[1], "shaper") == 0)) {
449 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
453 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[2]) != 0) {
454 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
458 np.shared_shaper_id = &shared_shaper_id;
459 np.n_shared_shapers = 1;
463 } /* shared shaper */
466 (strcmp(tokens[0], "nonleaf") == 0) &&
467 (strcmp(tokens[1], "sp") == 0)) {
469 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
473 if (softnic_parser_read_uint32(&np.nonleaf.n_sp_priorities, tokens[2]) != 0) {
474 snprintf(out, out_size, MSG_ARG_INVALID, "n_sp_priorities");
480 } /* nonleaf sp <n_sp_priorities> */
483 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
487 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
491 status = rte_tm_node_add(port_id,
496 RTE_TM_NODE_LEVEL_ID_ANY,
500 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
509 cmd_tmgr(struct pmd_internals *softnic,
516 struct softnic_tmgr_port *tmgr_port;
519 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
525 tmgr_port = softnic_tmgr_port_create(softnic, name);
526 if (tmgr_port == NULL) {
527 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
536 cmd_tap(struct pmd_internals *softnic,
543 struct softnic_tap *tap;
546 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
552 tap = softnic_tap_create(softnic, name);
554 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
560 * port in action profile <profile_name>
561 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
562 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
565 cmd_port_in_action_profile(struct pmd_internals *softnic,
571 struct softnic_port_in_action_profile_params p;
572 struct softnic_port_in_action_profile *ap;
576 memset(&p, 0, sizeof(p));
579 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
583 if (strcmp(tokens[1], "in") != 0) {
584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
588 if (strcmp(tokens[2], "action") != 0) {
589 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
593 if (strcmp(tokens[3], "profile") != 0) {
594 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
603 (strcmp(tokens[t0], "filter") == 0)) {
606 if (n_tokens < t0 + 10) {
607 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
611 if (strcmp(tokens[t0 + 1], "match") == 0) {
612 p.fltr.filter_on_match = 1;
613 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
614 p.fltr.filter_on_match = 0;
616 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
620 if (strcmp(tokens[t0 + 2], "offset") != 0) {
621 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
625 if (softnic_parser_read_uint32(&p.fltr.key_offset,
626 tokens[t0 + 3]) != 0) {
627 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
631 if (strcmp(tokens[t0 + 4], "mask") != 0) {
632 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
636 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
637 if ((softnic_parse_hex_string(tokens[t0 + 5],
638 p.fltr.key_mask, &size) != 0) ||
639 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
640 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
644 if (strcmp(tokens[t0 + 6], "key") != 0) {
645 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
649 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
650 if ((softnic_parse_hex_string(tokens[t0 + 7],
651 p.fltr.key, &size) != 0) ||
652 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
653 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
657 if (strcmp(tokens[t0 + 8], "port") != 0) {
658 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
662 if (softnic_parser_read_uint32(&p.fltr.port_id,
663 tokens[t0 + 9]) != 0) {
664 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
668 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
673 (strcmp(tokens[t0], "balance") == 0)) {
676 if (n_tokens < t0 + 22) {
677 snprintf(out, out_size, MSG_ARG_MISMATCH,
678 "port in action profile balance");
682 if (strcmp(tokens[t0 + 1], "offset") != 0) {
683 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
687 if (softnic_parser_read_uint32(&p.lb.key_offset,
688 tokens[t0 + 2]) != 0) {
689 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
693 if (strcmp(tokens[t0 + 3], "mask") != 0) {
694 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
698 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
699 if (softnic_parse_hex_string(tokens[t0 + 4],
700 p.lb.key_mask, &p.lb.key_size) != 0) {
701 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
705 if (strcmp(tokens[t0 + 5], "port") != 0) {
706 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
710 for (i = 0; i < 16; i++)
711 if (softnic_parser_read_uint32(&p.lb.port_id[i],
712 tokens[t0 + 6 + i]) != 0) {
713 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
717 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
722 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
726 ap = softnic_port_in_action_profile_create(softnic, name, &p);
728 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
734 * table action profile <profile_name>
738 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
739 * [meter srtcm | trtcm
741 * stats none | pkts | bytes | both]
742 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
743 * [encap ether | vlan | qinq | mpls | pppoe]
748 * [stats pkts | bytes | both]
752 cmd_table_action_profile(struct pmd_internals *softnic,
758 struct softnic_table_action_profile_params p;
759 struct softnic_table_action_profile *ap;
763 memset(&p, 0, sizeof(p));
766 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
770 if (strcmp(tokens[1], "action") != 0) {
771 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
775 if (strcmp(tokens[2], "profile") != 0) {
776 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
782 if (strcmp(tokens[4], "ipv4") == 0) {
783 p.common.ip_version = 1;
784 } else if (strcmp(tokens[4], "ipv6") == 0) {
785 p.common.ip_version = 0;
787 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
791 if (strcmp(tokens[5], "offset") != 0) {
792 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
796 if (softnic_parser_read_uint32(&p.common.ip_offset,
798 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
802 if (strcmp(tokens[7], "fwd") != 0) {
803 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
807 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
811 (strcmp(tokens[t0], "balance") == 0)) {
812 if (n_tokens < t0 + 7) {
813 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
817 if (strcmp(tokens[t0 + 1], "offset") != 0) {
818 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
822 if (softnic_parser_read_uint32(&p.lb.key_offset,
823 tokens[t0 + 2]) != 0) {
824 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
828 if (strcmp(tokens[t0 + 3], "mask") != 0) {
829 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
833 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
834 if (softnic_parse_hex_string(tokens[t0 + 4],
835 p.lb.key_mask, &p.lb.key_size) != 0) {
836 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
840 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
841 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
845 if (softnic_parser_read_uint32(&p.lb.out_offset,
846 tokens[t0 + 6]) != 0) {
847 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
851 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
856 (strcmp(tokens[t0], "meter") == 0)) {
857 if (n_tokens < t0 + 6) {
858 snprintf(out, out_size, MSG_ARG_MISMATCH,
859 "table action profile meter");
863 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
864 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
865 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
866 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
868 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
873 if (strcmp(tokens[t0 + 2], "tc") != 0) {
874 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
878 if (softnic_parser_read_uint32(&p.mtr.n_tc,
879 tokens[t0 + 3]) != 0) {
880 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
884 if (strcmp(tokens[t0 + 4], "stats") != 0) {
885 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
889 if (strcmp(tokens[t0 + 5], "none") == 0) {
890 p.mtr.n_packets_enabled = 0;
891 p.mtr.n_bytes_enabled = 0;
892 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
893 p.mtr.n_packets_enabled = 1;
894 p.mtr.n_bytes_enabled = 0;
895 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
896 p.mtr.n_packets_enabled = 0;
897 p.mtr.n_bytes_enabled = 1;
898 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
899 p.mtr.n_packets_enabled = 1;
900 p.mtr.n_bytes_enabled = 1;
902 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
903 "none or pkts or bytes or both");
907 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
912 (strcmp(tokens[t0], "tm") == 0)) {
913 if (n_tokens < t0 + 5) {
914 snprintf(out, out_size, MSG_ARG_MISMATCH,
915 "table action profile tm");
919 if (strcmp(tokens[t0 + 1], "spp") != 0) {
920 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
924 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
925 tokens[t0 + 2]) != 0) {
926 snprintf(out, out_size, MSG_ARG_INVALID,
927 "n_subports_per_port");
931 if (strcmp(tokens[t0 + 3], "pps") != 0) {
932 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
936 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
937 tokens[t0 + 4]) != 0) {
938 snprintf(out, out_size, MSG_ARG_INVALID,
939 "n_pipes_per_subport");
943 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
948 (strcmp(tokens[t0], "encap") == 0)) {
949 if (n_tokens < t0 + 2) {
950 snprintf(out, out_size, MSG_ARG_MISMATCH,
951 "action profile encap");
955 if (strcmp(tokens[t0 + 1], "ether") == 0) {
956 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
957 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
958 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
959 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
960 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
961 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
962 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
963 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
964 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
966 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
970 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
975 (strcmp(tokens[t0], "nat") == 0)) {
976 if (n_tokens < t0 + 4) {
977 snprintf(out, out_size, MSG_ARG_MISMATCH,
978 "table action profile nat");
982 if (strcmp(tokens[t0 + 1], "src") == 0) {
983 p.nat.source_nat = 1;
984 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
985 p.nat.source_nat = 0;
987 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
992 if (strcmp(tokens[t0 + 2], "proto") != 0) {
993 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
997 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
999 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
1002 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1007 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1011 if (t0 < n_tokens &&
1012 (strcmp(tokens[t0], "ttl") == 0)) {
1013 if (n_tokens < t0 + 4) {
1014 snprintf(out, out_size, MSG_ARG_MISMATCH,
1015 "table action profile ttl");
1019 if (strcmp(tokens[t0 + 1], "drop") == 0) {
1021 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
1024 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1029 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1030 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1034 if (strcmp(tokens[t0 + 3], "none") == 0) {
1035 p.ttl.n_packets_enabled = 0;
1036 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
1037 p.ttl.n_packets_enabled = 1;
1039 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1044 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1048 if (t0 < n_tokens &&
1049 (strcmp(tokens[t0], "stats") == 0)) {
1050 if (n_tokens < t0 + 2) {
1051 snprintf(out, out_size, MSG_ARG_MISMATCH,
1052 "table action profile stats");
1056 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1057 p.stats.n_packets_enabled = 1;
1058 p.stats.n_bytes_enabled = 0;
1059 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1060 p.stats.n_packets_enabled = 0;
1061 p.stats.n_bytes_enabled = 1;
1062 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1063 p.stats.n_packets_enabled = 1;
1064 p.stats.n_bytes_enabled = 1;
1066 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1067 "pkts or bytes or both");
1071 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1075 if (t0 < n_tokens &&
1076 (strcmp(tokens[t0], "time") == 0)) {
1077 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1081 if (t0 < n_tokens) {
1082 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1086 ap = softnic_table_action_profile_create(softnic, name, &p);
1088 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1094 * pipeline <pipeline_name>
1095 * period <timer_period_ms>
1096 * offset_port_id <offset_port_id>
1099 cmd_pipeline(struct pmd_internals *softnic,
1105 struct pipeline_params p;
1107 struct pipeline *pipeline;
1109 if (n_tokens != 6) {
1110 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1116 if (strcmp(tokens[2], "period") != 0) {
1117 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1121 if (softnic_parser_read_uint32(&p.timer_period_ms,
1123 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1127 if (strcmp(tokens[4], "offset_port_id") != 0) {
1128 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1132 if (softnic_parser_read_uint32(&p.offset_port_id,
1134 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1138 pipeline = softnic_pipeline_create(softnic, name, &p);
1139 if (pipeline == NULL) {
1140 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1146 * pipeline <pipeline_name> port in
1148 * link <link_name> rxq <queue_id>
1150 * | tmgr <tmgr_name>
1151 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
1152 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
1153 * [action <port_in_action_profile_name>]
1157 cmd_pipeline_port_in(struct pmd_internals *softnic,
1163 struct softnic_port_in_params p;
1164 char *pipeline_name;
1166 int enabled, status;
1169 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1173 pipeline_name = tokens[1];
1175 if (strcmp(tokens[2], "port") != 0) {
1176 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1180 if (strcmp(tokens[3], "in") != 0) {
1181 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1185 if (strcmp(tokens[4], "bsz") != 0) {
1186 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1190 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1191 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1197 if (strcmp(tokens[t0], "link") == 0) {
1198 if (n_tokens < t0 + 4) {
1199 snprintf(out, out_size, MSG_ARG_MISMATCH,
1200 "pipeline port in link");
1204 p.type = PORT_IN_RXQ;
1206 p.dev_name = tokens[t0 + 1];
1208 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1209 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1213 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1214 tokens[t0 + 3]) != 0) {
1215 snprintf(out, out_size, MSG_ARG_INVALID,
1220 } else if (strcmp(tokens[t0], "swq") == 0) {
1221 if (n_tokens < t0 + 2) {
1222 snprintf(out, out_size, MSG_ARG_MISMATCH,
1223 "pipeline port in swq");
1227 p.type = PORT_IN_SWQ;
1229 p.dev_name = tokens[t0 + 1];
1232 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1233 if (n_tokens < t0 + 2) {
1234 snprintf(out, out_size, MSG_ARG_MISMATCH,
1235 "pipeline port in tmgr");
1239 p.type = PORT_IN_TMGR;
1241 p.dev_name = tokens[t0 + 1];
1244 } else if (strcmp(tokens[t0], "tap") == 0) {
1245 if (n_tokens < t0 + 6) {
1246 snprintf(out, out_size, MSG_ARG_MISMATCH,
1247 "pipeline port in tap");
1251 p.type = PORT_IN_TAP;
1253 p.dev_name = tokens[t0 + 1];
1255 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1256 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1261 p.tap.mempool_name = tokens[t0 + 3];
1263 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1264 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1269 if (softnic_parser_read_uint32(&p.tap.mtu,
1270 tokens[t0 + 5]) != 0) {
1271 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1276 } else if (strcmp(tokens[t0], "source") == 0) {
1277 if (n_tokens < t0 + 6) {
1278 snprintf(out, out_size, MSG_ARG_MISMATCH,
1279 "pipeline port in source");
1283 p.type = PORT_IN_SOURCE;
1287 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1288 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1293 p.source.mempool_name = tokens[t0 + 2];
1295 if (strcmp(tokens[t0 + 3], "file") != 0) {
1296 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1301 p.source.file_name = tokens[t0 + 4];
1303 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1304 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1309 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1310 tokens[t0 + 6]) != 0) {
1311 snprintf(out, out_size, MSG_ARG_INVALID,
1318 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1322 p.action_profile_name = NULL;
1323 if (n_tokens > t0 &&
1324 (strcmp(tokens[t0], "action") == 0)) {
1325 if (n_tokens < t0 + 2) {
1326 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1330 p.action_profile_name = tokens[t0 + 1];
1336 if (n_tokens > t0 &&
1337 (strcmp(tokens[t0], "disabled") == 0)) {
1343 if (n_tokens != t0) {
1344 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1348 status = softnic_pipeline_port_in_create(softnic,
1353 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1359 * pipeline <pipeline_name> port out
1361 * link <link_name> txq <txq_id>
1363 * | tmgr <tmgr_name>
1365 * | sink [file <file_name> pkts <max_n_pkts>]
1368 cmd_pipeline_port_out(struct pmd_internals *softnic,
1374 struct softnic_port_out_params p;
1375 char *pipeline_name;
1378 memset(&p, 0, sizeof(p));
1381 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1385 pipeline_name = tokens[1];
1387 if (strcmp(tokens[2], "port") != 0) {
1388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1392 if (strcmp(tokens[3], "out") != 0) {
1393 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1397 if (strcmp(tokens[4], "bsz") != 0) {
1398 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1402 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1403 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1407 if (strcmp(tokens[6], "link") == 0) {
1408 if (n_tokens != 10) {
1409 snprintf(out, out_size, MSG_ARG_MISMATCH,
1410 "pipeline port out link");
1414 p.type = PORT_OUT_TXQ;
1416 p.dev_name = tokens[7];
1418 if (strcmp(tokens[8], "txq") != 0) {
1419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1423 if (softnic_parser_read_uint16(&p.txq.queue_id,
1425 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1428 } else if (strcmp(tokens[6], "swq") == 0) {
1429 if (n_tokens != 8) {
1430 snprintf(out, out_size, MSG_ARG_MISMATCH,
1431 "pipeline port out swq");
1435 p.type = PORT_OUT_SWQ;
1437 p.dev_name = tokens[7];
1438 } else if (strcmp(tokens[6], "tmgr") == 0) {
1439 if (n_tokens != 8) {
1440 snprintf(out, out_size, MSG_ARG_MISMATCH,
1441 "pipeline port out tmgr");
1445 p.type = PORT_OUT_TMGR;
1447 p.dev_name = tokens[7];
1448 } else if (strcmp(tokens[6], "tap") == 0) {
1449 if (n_tokens != 8) {
1450 snprintf(out, out_size, MSG_ARG_MISMATCH,
1451 "pipeline port out tap");
1455 p.type = PORT_OUT_TAP;
1457 p.dev_name = tokens[7];
1458 } else if (strcmp(tokens[6], "sink") == 0) {
1459 if ((n_tokens != 7) && (n_tokens != 11)) {
1460 snprintf(out, out_size, MSG_ARG_MISMATCH,
1461 "pipeline port out sink");
1465 p.type = PORT_OUT_SINK;
1469 if (n_tokens == 7) {
1470 p.sink.file_name = NULL;
1471 p.sink.max_n_pkts = 0;
1473 if (strcmp(tokens[7], "file") != 0) {
1474 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1479 p.sink.file_name = tokens[8];
1481 if (strcmp(tokens[9], "pkts") != 0) {
1482 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1486 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1488 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1493 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1497 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1499 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1505 * pipeline <pipeline_name> table
1509 * offset <ip_header_offset>
1512 * offset <key_offset>
1518 * offset <key_offset>
1519 * buckets <n_buckets>
1523 * offset <ip_header_offset>
1526 * [action <table_action_profile_name>]
1529 cmd_pipeline_table(struct pmd_internals *softnic,
1535 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1536 struct softnic_table_params p;
1537 char *pipeline_name;
1542 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1546 pipeline_name = tokens[1];
1548 if (strcmp(tokens[2], "table") != 0) {
1549 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1553 if (strcmp(tokens[3], "match") != 0) {
1554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1559 if (strcmp(tokens[t0], "acl") == 0) {
1560 if (n_tokens < t0 + 6) {
1561 snprintf(out, out_size, MSG_ARG_MISMATCH,
1562 "pipeline table acl");
1566 p.match_type = TABLE_ACL;
1568 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1569 p.match.acl.ip_version = 1;
1570 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1571 p.match.acl.ip_version = 0;
1573 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1578 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1579 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1583 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1584 tokens[t0 + 3]) != 0) {
1585 snprintf(out, out_size, MSG_ARG_INVALID,
1586 "ip_header_offset");
1590 if (strcmp(tokens[t0 + 4], "size") != 0) {
1591 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1595 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1596 tokens[t0 + 5]) != 0) {
1597 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1602 } else if (strcmp(tokens[t0], "array") == 0) {
1603 if (n_tokens < t0 + 5) {
1604 snprintf(out, out_size, MSG_ARG_MISMATCH,
1605 "pipeline table array");
1609 p.match_type = TABLE_ARRAY;
1611 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1612 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1616 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1617 tokens[t0 + 2]) != 0) {
1618 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1622 if (strcmp(tokens[t0 + 3], "size") != 0) {
1623 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1627 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1628 tokens[t0 + 4]) != 0) {
1629 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1634 } else if (strcmp(tokens[t0], "hash") == 0) {
1635 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1637 if (n_tokens < t0 + 12) {
1638 snprintf(out, out_size, MSG_ARG_MISMATCH,
1639 "pipeline table hash");
1643 p.match_type = TABLE_HASH;
1645 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1646 p.match.hash.extendable_bucket = 1;
1647 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1648 p.match.hash.extendable_bucket = 0;
1650 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1655 if (strcmp(tokens[t0 + 2], "key") != 0) {
1656 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1660 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1661 tokens[t0 + 3]) != 0) ||
1662 p.match.hash.key_size == 0 ||
1663 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1664 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1668 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1669 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1673 if ((softnic_parse_hex_string(tokens[t0 + 5],
1674 key_mask, &key_mask_size) != 0) ||
1675 key_mask_size != p.match.hash.key_size) {
1676 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1679 p.match.hash.key_mask = key_mask;
1681 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1682 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1686 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1687 tokens[t0 + 7]) != 0) {
1688 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1692 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1693 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1697 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1698 tokens[t0 + 9]) != 0) {
1699 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1703 if (strcmp(tokens[t0 + 10], "size") != 0) {
1704 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1708 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1709 tokens[t0 + 11]) != 0) {
1710 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1715 } else if (strcmp(tokens[t0], "lpm") == 0) {
1716 if (n_tokens < t0 + 6) {
1717 snprintf(out, out_size, MSG_ARG_MISMATCH,
1718 "pipeline table lpm");
1722 p.match_type = TABLE_LPM;
1724 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1725 p.match.lpm.key_size = 4;
1726 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1727 p.match.lpm.key_size = 16;
1729 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1734 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1735 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1739 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1740 tokens[t0 + 3]) != 0) {
1741 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1745 if (strcmp(tokens[t0 + 4], "size") != 0) {
1746 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1750 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1751 tokens[t0 + 5]) != 0) {
1752 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1757 } else if (strcmp(tokens[t0], "stub") == 0) {
1758 p.match_type = TABLE_STUB;
1762 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1766 p.action_profile_name = NULL;
1767 if (n_tokens > t0 &&
1768 (strcmp(tokens[t0], "action") == 0)) {
1769 if (n_tokens < t0 + 2) {
1770 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1774 p.action_profile_name = tokens[t0 + 1];
1779 if (n_tokens > t0) {
1780 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1784 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1786 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1792 * pipeline <pipeline_name> port in <port_id> table <table_id>
1795 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1801 char *pipeline_name;
1802 uint32_t port_id, table_id;
1805 if (n_tokens != 7) {
1806 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1810 pipeline_name = tokens[1];
1812 if (strcmp(tokens[2], "port") != 0) {
1813 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1817 if (strcmp(tokens[3], "in") != 0) {
1818 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1822 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1823 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1827 if (strcmp(tokens[5], "table") != 0) {
1828 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1832 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1833 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1837 status = softnic_pipeline_port_in_connect_to_table(softnic,
1842 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1848 * pipeline <pipeline_name> port in <port_id> stats read [clear]
1851 #define MSG_PIPELINE_PORT_IN_STATS \
1852 "Pkts in: %" PRIu64 "\n" \
1853 "Pkts dropped by AH: %" PRIu64 "\n" \
1854 "Pkts dropped by other: %" PRIu64 "\n"
1857 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
1863 struct rte_pipeline_port_in_stats stats;
1864 char *pipeline_name;
1868 if (n_tokens != 7 &&
1870 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1874 pipeline_name = tokens[1];
1876 if (strcmp(tokens[2], "port") != 0) {
1877 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1881 if (strcmp(tokens[3], "in") != 0) {
1882 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1886 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1887 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1891 if (strcmp(tokens[5], "stats") != 0) {
1892 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1896 if (strcmp(tokens[6], "read") != 0) {
1897 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1902 if (n_tokens == 8) {
1903 if (strcmp(tokens[7], "clear") != 0) {
1904 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1911 status = softnic_pipeline_port_in_stats_read(softnic,
1917 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1921 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
1922 stats.stats.n_pkts_in,
1923 stats.n_pkts_dropped_by_ah,
1924 stats.stats.n_pkts_drop);
1928 * pipeline <pipeline_name> port in <port_id> enable
1931 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1937 char *pipeline_name;
1941 if (n_tokens != 6) {
1942 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1946 pipeline_name = tokens[1];
1948 if (strcmp(tokens[2], "port") != 0) {
1949 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1953 if (strcmp(tokens[3], "in") != 0) {
1954 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1958 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1959 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1963 if (strcmp(tokens[5], "enable") != 0) {
1964 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1968 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1970 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1976 * pipeline <pipeline_name> port in <port_id> disable
1979 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1985 char *pipeline_name;
1989 if (n_tokens != 6) {
1990 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1994 pipeline_name = tokens[1];
1996 if (strcmp(tokens[2], "port") != 0) {
1997 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2001 if (strcmp(tokens[3], "in") != 0) {
2002 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2006 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2007 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2011 if (strcmp(tokens[5], "disable") != 0) {
2012 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2016 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2018 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2024 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2026 #define MSG_PIPELINE_PORT_OUT_STATS \
2027 "Pkts in: %" PRIu64 "\n" \
2028 "Pkts dropped by AH: %" PRIu64 "\n" \
2029 "Pkts dropped by other: %" PRIu64 "\n"
2032 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2038 struct rte_pipeline_port_out_stats stats;
2039 char *pipeline_name;
2043 if (n_tokens != 7 &&
2045 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2049 pipeline_name = tokens[1];
2051 if (strcmp(tokens[2], "port") != 0) {
2052 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2056 if (strcmp(tokens[3], "out") != 0) {
2057 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2061 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2062 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2066 if (strcmp(tokens[5], "stats") != 0) {
2067 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2071 if (strcmp(tokens[6], "read") != 0) {
2072 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2077 if (n_tokens == 8) {
2078 if (strcmp(tokens[7], "clear") != 0) {
2079 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2086 status = softnic_pipeline_port_out_stats_read(softnic,
2092 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2096 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2097 stats.stats.n_pkts_in,
2098 stats.n_pkts_dropped_by_ah,
2099 stats.stats.n_pkts_drop);
2103 * pipeline <pipeline_name> table <table_id> stats read [clear]
2105 #define MSG_PIPELINE_TABLE_STATS \
2106 "Pkts in: %" PRIu64 "\n" \
2107 "Pkts in with lookup miss: %" PRIu64 "\n" \
2108 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2109 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2110 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2111 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2114 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2120 struct rte_pipeline_table_stats stats;
2121 char *pipeline_name;
2125 if (n_tokens != 6 &&
2127 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2131 pipeline_name = tokens[1];
2133 if (strcmp(tokens[2], "table") != 0) {
2134 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2138 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2139 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2143 if (strcmp(tokens[4], "stats") != 0) {
2144 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2148 if (strcmp(tokens[5], "read") != 0) {
2149 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2154 if (n_tokens == 7) {
2155 if (strcmp(tokens[6], "clear") != 0) {
2156 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2163 status = softnic_pipeline_table_stats_read(softnic,
2169 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2173 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2174 stats.stats.n_pkts_in,
2175 stats.stats.n_pkts_lookup_miss,
2176 stats.n_pkts_dropped_by_lkp_hit_ah,
2177 stats.n_pkts_dropped_lkp_hit,
2178 stats.n_pkts_dropped_by_lkp_miss_ah,
2179 stats.n_pkts_dropped_lkp_miss);
2187 * priority <priority>
2188 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2189 * <sp0> <sp1> <dp0> <dp1> <proto>
2193 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2194 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2195 * | ipv4_addr <addr>
2196 * | ipv6_addr <addr>
2197 * | qinq <svlan> <cvlan>
2199 * ipv4 | ipv6 <addr> <depth>
2201 struct pkt_key_qinq {
2202 uint16_t ethertype_svlan;
2204 uint16_t ethertype_cvlan;
2206 } __attribute__((__packed__));
2208 struct pkt_key_ipv4_5tuple {
2209 uint8_t time_to_live;
2211 uint16_t hdr_checksum;
2216 } __attribute__((__packed__));
2218 struct pkt_key_ipv6_5tuple {
2219 uint16_t payload_length;
2226 } __attribute__((__packed__));
2228 struct pkt_key_ipv4_addr {
2230 } __attribute__((__packed__));
2232 struct pkt_key_ipv6_addr {
2234 } __attribute__((__packed__));
2237 parse_match(char **tokens,
2241 struct softnic_table_rule_match *m)
2243 memset(m, 0, sizeof(*m));
2248 if (strcmp(tokens[0], "match") != 0) {
2249 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2253 if (strcmp(tokens[1], "acl") == 0) {
2254 if (n_tokens < 14) {
2255 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2259 m->match_type = TABLE_ACL;
2261 if (strcmp(tokens[2], "priority") != 0) {
2262 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2266 if (softnic_parser_read_uint32(&m->match.acl.priority,
2268 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2272 if (strcmp(tokens[4], "ipv4") == 0) {
2273 struct in_addr saddr, daddr;
2275 m->match.acl.ip_version = 1;
2277 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2278 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2281 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2283 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2284 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2287 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2288 } else if (strcmp(tokens[4], "ipv6") == 0) {
2289 struct in6_addr saddr, daddr;
2291 m->match.acl.ip_version = 0;
2293 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2294 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2297 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2299 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2300 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2303 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2305 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2310 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2312 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2316 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2318 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2322 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2323 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2327 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2328 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2332 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2333 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2337 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2338 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2342 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2343 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2347 m->match.acl.proto_mask = 0xff;
2352 if (strcmp(tokens[1], "array") == 0) {
2354 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2358 m->match_type = TABLE_ARRAY;
2360 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2361 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2368 if (strcmp(tokens[1], "hash") == 0) {
2370 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2374 m->match_type = TABLE_HASH;
2376 if (strcmp(tokens[2], "raw") == 0) {
2377 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2380 snprintf(out, out_size, MSG_ARG_MISMATCH,
2385 if (softnic_parse_hex_string(tokens[3],
2386 m->match.hash.key, &key_size) != 0) {
2387 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2394 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2395 struct pkt_key_ipv4_5tuple *ipv4 =
2396 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2397 struct in_addr saddr, daddr;
2402 snprintf(out, out_size, MSG_ARG_MISMATCH,
2407 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2408 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2412 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2413 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2417 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2418 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2422 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2423 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2427 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2428 snprintf(out, out_size, MSG_ARG_INVALID,
2433 ipv4->sa = saddr.s_addr;
2434 ipv4->da = daddr.s_addr;
2435 ipv4->sp = rte_cpu_to_be_16(sp);
2436 ipv4->dp = rte_cpu_to_be_16(dp);
2437 ipv4->proto = proto;
2440 } /* hash ipv4_5tuple */
2442 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2443 struct pkt_key_ipv6_5tuple *ipv6 =
2444 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2445 struct in6_addr saddr, daddr;
2450 snprintf(out, out_size, MSG_ARG_MISMATCH,
2455 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2456 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2460 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2461 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2465 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2466 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2470 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2471 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2475 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2476 snprintf(out, out_size, MSG_ARG_INVALID,
2481 memcpy(ipv6->sa, saddr.s6_addr, 16);
2482 memcpy(ipv6->da, daddr.s6_addr, 16);
2483 ipv6->sp = rte_cpu_to_be_16(sp);
2484 ipv6->dp = rte_cpu_to_be_16(dp);
2485 ipv6->proto = proto;
2488 } /* hash ipv6_5tuple */
2490 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2491 struct pkt_key_ipv4_addr *ipv4_addr =
2492 (struct pkt_key_ipv4_addr *)m->match.hash.key;
2493 struct in_addr addr;
2496 snprintf(out, out_size, MSG_ARG_MISMATCH,
2501 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2502 snprintf(out, out_size, MSG_ARG_INVALID,
2507 ipv4_addr->addr = addr.s_addr;
2510 } /* hash ipv4_addr */
2512 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2513 struct pkt_key_ipv6_addr *ipv6_addr =
2514 (struct pkt_key_ipv6_addr *)m->match.hash.key;
2515 struct in6_addr addr;
2518 snprintf(out, out_size, MSG_ARG_MISMATCH,
2523 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2524 snprintf(out, out_size, MSG_ARG_INVALID,
2529 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2532 } /* hash ipv6_5tuple */
2534 if (strcmp(tokens[2], "qinq") == 0) {
2535 struct pkt_key_qinq *qinq =
2536 (struct pkt_key_qinq *)m->match.hash.key;
2537 uint16_t svlan, cvlan;
2540 snprintf(out, out_size, MSG_ARG_MISMATCH,
2545 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
2547 snprintf(out, out_size, MSG_ARG_INVALID,
2552 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2554 snprintf(out, out_size, MSG_ARG_INVALID,
2559 qinq->svlan = rte_cpu_to_be_16(svlan);
2560 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2565 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2569 if (strcmp(tokens[1], "lpm") == 0) {
2571 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2575 m->match_type = TABLE_LPM;
2577 if (strcmp(tokens[2], "ipv4") == 0) {
2578 struct in_addr addr;
2580 m->match.lpm.ip_version = 1;
2582 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2583 snprintf(out, out_size, MSG_ARG_INVALID,
2588 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2589 } else if (strcmp(tokens[2], "ipv6") == 0) {
2590 struct in6_addr addr;
2592 m->match.lpm.ip_version = 0;
2594 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2595 snprintf(out, out_size, MSG_ARG_INVALID,
2600 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2602 snprintf(out, out_size, MSG_ARG_MISMATCH,
2607 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2608 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2615 snprintf(out, out_size, MSG_ARG_MISMATCH,
2616 "acl or array or hash or lpm");
2628 * | table <table_id>
2629 * [balance <out0> ... <out7>]
2631 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2632 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2633 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2634 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2635 * [tm subport <subport_id> pipe <pipe_id>]
2638 * | vlan <da> <sa> <pcp> <dei> <vid>
2639 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2640 * | mpls unicast | multicast
2642 * label0 <label> <tc> <ttl>
2643 * [label1 <label> <tc> <ttl>
2644 * [label2 <label> <tc> <ttl>
2645 * [label3 <label> <tc> <ttl>]]]
2646 * | pppoe <da> <sa> <session_id>]
2647 * [nat ipv4 | ipv6 <addr> <port>]
2653 * <pa> ::= g | y | r | drop
2656 parse_table_action_fwd(char **tokens,
2658 struct softnic_table_rule_action *a)
2660 if (n_tokens == 0 ||
2661 (strcmp(tokens[0], "fwd") != 0))
2667 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2668 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2669 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2673 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2677 softnic_parser_read_uint32(&id, tokens[1]))
2680 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2682 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2686 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2687 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2688 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2692 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2696 softnic_parser_read_uint32(&id, tokens[1]))
2699 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2701 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2709 parse_table_action_balance(char **tokens,
2711 struct softnic_table_rule_action *a)
2715 if (n_tokens == 0 ||
2716 (strcmp(tokens[0], "balance") != 0))
2722 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2725 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2726 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2729 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2730 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2734 parse_policer_action(char *token, enum rte_table_action_policer *a)
2736 if (strcmp(token, "g") == 0) {
2737 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2741 if (strcmp(token, "y") == 0) {
2742 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2746 if (strcmp(token, "r") == 0) {
2747 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2751 if (strcmp(token, "drop") == 0) {
2752 *a = RTE_TABLE_ACTION_POLICER_DROP;
2760 parse_table_action_meter_tc(char **tokens,
2762 struct rte_table_action_mtr_tc_params *mtr)
2765 strcmp(tokens[0], "meter") ||
2766 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2767 strcmp(tokens[2], "policer") ||
2768 strcmp(tokens[3], "g") ||
2769 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2770 strcmp(tokens[5], "y") ||
2771 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2772 strcmp(tokens[7], "r") ||
2773 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2780 parse_table_action_meter(char **tokens,
2782 struct softnic_table_rule_action *a)
2784 if (n_tokens == 0 ||
2785 strcmp(tokens[0], "meter"))
2791 if (n_tokens < 10 ||
2792 strcmp(tokens[0], "tc0") ||
2793 (parse_table_action_meter_tc(tokens + 1,
2795 &a->mtr.mtr[0]) == 0))
2801 if (n_tokens == 0 ||
2802 strcmp(tokens[0], "tc1")) {
2804 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2808 if (n_tokens < 30 ||
2809 (parse_table_action_meter_tc(tokens + 1,
2810 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
2811 strcmp(tokens[10], "tc2") ||
2812 (parse_table_action_meter_tc(tokens + 11,
2813 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
2814 strcmp(tokens[20], "tc3") ||
2815 (parse_table_action_meter_tc(tokens + 21,
2816 n_tokens - 21, &a->mtr.mtr[3]) == 0))
2819 a->mtr.tc_mask = 0xF;
2820 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2821 return 1 + 10 + 3 * 10;
2825 parse_table_action_tm(char **tokens,
2827 struct softnic_table_rule_action *a)
2829 uint32_t subport_id, pipe_id;
2832 strcmp(tokens[0], "tm") ||
2833 strcmp(tokens[1], "subport") ||
2834 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
2835 strcmp(tokens[3], "pipe") ||
2836 softnic_parser_read_uint32(&pipe_id, tokens[4]))
2839 a->tm.subport_id = subport_id;
2840 a->tm.pipe_id = pipe_id;
2841 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
2846 parse_table_action_encap(char **tokens,
2848 struct softnic_table_rule_action *a)
2850 if (n_tokens == 0 ||
2851 strcmp(tokens[0], "encap"))
2858 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
2860 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
2861 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
2864 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
2865 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2870 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
2871 uint32_t pcp, dei, vid;
2874 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
2875 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
2876 softnic_parser_read_uint32(&pcp, tokens[3]) ||
2878 softnic_parser_read_uint32(&dei, tokens[4]) ||
2880 softnic_parser_read_uint32(&vid, tokens[5]) ||
2884 a->encap.vlan.vlan.pcp = pcp & 0x7;
2885 a->encap.vlan.vlan.dei = dei & 0x1;
2886 a->encap.vlan.vlan.vid = vid & 0xFFF;
2887 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
2888 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2893 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
2894 uint32_t svlan_pcp, svlan_dei, svlan_vid;
2895 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
2898 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
2899 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
2900 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
2902 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
2904 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
2905 svlan_vid > 0xFFF ||
2906 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
2908 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
2910 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
2914 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
2915 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
2916 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
2917 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
2918 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
2919 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
2920 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
2921 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2926 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
2927 uint32_t label, tc, ttl;
2932 if (strcmp(tokens[1], "unicast") == 0)
2933 a->encap.mpls.unicast = 1;
2934 else if (strcmp(tokens[1], "multicast") == 0)
2935 a->encap.mpls.unicast = 0;
2939 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
2940 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
2941 strcmp(tokens[4], "label0") ||
2942 softnic_parser_read_uint32(&label, tokens[5]) ||
2944 softnic_parser_read_uint32(&tc, tokens[6]) ||
2946 softnic_parser_read_uint32(&ttl, tokens[7]) ||
2950 a->encap.mpls.mpls[0].label = label;
2951 a->encap.mpls.mpls[0].tc = tc;
2952 a->encap.mpls.mpls[0].ttl = ttl;
2957 if (n_tokens == 0 ||
2958 strcmp(tokens[0], "label1")) {
2959 a->encap.mpls.mpls_count = 1;
2960 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2961 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2966 softnic_parser_read_uint32(&label, tokens[1]) ||
2968 softnic_parser_read_uint32(&tc, tokens[2]) ||
2970 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2974 a->encap.mpls.mpls[1].label = label;
2975 a->encap.mpls.mpls[1].tc = tc;
2976 a->encap.mpls.mpls[1].ttl = ttl;
2981 if (n_tokens == 0 ||
2982 strcmp(tokens[0], "label2")) {
2983 a->encap.mpls.mpls_count = 2;
2984 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2985 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2990 softnic_parser_read_uint32(&label, tokens[1]) ||
2992 softnic_parser_read_uint32(&tc, tokens[2]) ||
2994 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2998 a->encap.mpls.mpls[2].label = label;
2999 a->encap.mpls.mpls[2].tc = tc;
3000 a->encap.mpls.mpls[2].ttl = ttl;
3005 if (n_tokens == 0 ||
3006 strcmp(tokens[0], "label3")) {
3007 a->encap.mpls.mpls_count = 3;
3008 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3009 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3010 return 1 + 8 + 4 + 4;
3014 softnic_parser_read_uint32(&label, tokens[1]) ||
3016 softnic_parser_read_uint32(&tc, tokens[2]) ||
3018 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3022 a->encap.mpls.mpls[3].label = label;
3023 a->encap.mpls.mpls[3].tc = tc;
3024 a->encap.mpls.mpls[3].ttl = ttl;
3026 a->encap.mpls.mpls_count = 4;
3027 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3028 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3029 return 1 + 8 + 4 + 4 + 4;
3033 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3035 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3036 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3037 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3041 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3042 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3050 parse_table_action_nat(char **tokens,
3052 struct softnic_table_rule_action *a)
3055 strcmp(tokens[0], "nat"))
3058 if (strcmp(tokens[1], "ipv4") == 0) {
3059 struct in_addr addr;
3062 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3063 softnic_parser_read_uint16(&port, tokens[3]))
3066 a->nat.ip_version = 1;
3067 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3069 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3073 if (strcmp(tokens[1], "ipv6") == 0) {
3074 struct in6_addr addr;
3077 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3078 softnic_parser_read_uint16(&port, tokens[3]))
3081 a->nat.ip_version = 0;
3082 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3084 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3092 parse_table_action_ttl(char **tokens,
3094 struct softnic_table_rule_action *a)
3097 strcmp(tokens[0], "ttl"))
3100 if (strcmp(tokens[1], "dec") == 0)
3101 a->ttl.decrement = 1;
3102 else if (strcmp(tokens[1], "keep") == 0)
3103 a->ttl.decrement = 0;
3107 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3112 parse_table_action_stats(char **tokens,
3114 struct softnic_table_rule_action *a)
3117 strcmp(tokens[0], "stats"))
3120 a->stats.n_packets = 0;
3121 a->stats.n_bytes = 0;
3122 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3127 parse_table_action_time(char **tokens,
3129 struct softnic_table_rule_action *a)
3132 strcmp(tokens[0], "time"))
3135 a->time.time = rte_rdtsc();
3136 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3141 parse_table_action(char **tokens,
3145 struct softnic_table_rule_action *a)
3147 uint32_t n_tokens0 = n_tokens;
3149 memset(a, 0, sizeof(*a));
3152 strcmp(tokens[0], "action"))
3158 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3161 n = parse_table_action_fwd(tokens, n_tokens, a);
3163 snprintf(out, out_size, MSG_ARG_INVALID,
3172 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3175 n = parse_table_action_balance(tokens, n_tokens, a);
3177 snprintf(out, out_size, MSG_ARG_INVALID,
3186 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3189 n = parse_table_action_meter(tokens, n_tokens, a);
3191 snprintf(out, out_size, MSG_ARG_INVALID,
3200 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3203 n = parse_table_action_tm(tokens, n_tokens, a);
3205 snprintf(out, out_size, MSG_ARG_INVALID,
3214 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3217 n = parse_table_action_encap(tokens, n_tokens, a);
3219 snprintf(out, out_size, MSG_ARG_INVALID,
3228 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3231 n = parse_table_action_nat(tokens, n_tokens, a);
3233 snprintf(out, out_size, MSG_ARG_INVALID,
3242 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3245 n = parse_table_action_ttl(tokens, n_tokens, a);
3247 snprintf(out, out_size, MSG_ARG_INVALID,
3256 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3259 n = parse_table_action_stats(tokens, n_tokens, a);
3261 snprintf(out, out_size, MSG_ARG_INVALID,
3270 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3273 n = parse_table_action_time(tokens, n_tokens, a);
3275 snprintf(out, out_size, MSG_ARG_INVALID,
3284 if (n_tokens0 - n_tokens == 1) {
3285 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3289 return n_tokens0 - n_tokens;
3293 * pipeline <pipeline_name> table <table_id> rule add
3295 * action <table_action>
3298 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3304 struct softnic_table_rule_match m;
3305 struct softnic_table_rule_action a;
3306 char *pipeline_name;
3308 uint32_t table_id, t0, n_tokens_parsed;
3312 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3316 pipeline_name = tokens[1];
3318 if (strcmp(tokens[2], "table") != 0) {
3319 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3323 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3324 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3328 if (strcmp(tokens[4], "rule") != 0) {
3329 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3333 if (strcmp(tokens[5], "add") != 0) {
3334 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3341 n_tokens_parsed = parse_match(tokens + t0,
3346 if (n_tokens_parsed == 0)
3348 t0 += n_tokens_parsed;
3351 n_tokens_parsed = parse_table_action(tokens + t0,
3356 if (n_tokens_parsed == 0)
3358 t0 += n_tokens_parsed;
3360 if (t0 != n_tokens) {
3361 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3365 status = softnic_pipeline_table_rule_add(softnic,
3372 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3378 * pipeline <pipeline_name> table <table_id> rule add
3386 * | table <table_id>
3389 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3395 struct softnic_table_rule_action action;
3397 char *pipeline_name;
3401 if (n_tokens != 11 &&
3403 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3407 pipeline_name = tokens[1];
3409 if (strcmp(tokens[2], "table") != 0) {
3410 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3414 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3415 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3419 if (strcmp(tokens[4], "rule") != 0) {
3420 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3424 if (strcmp(tokens[5], "add") != 0) {
3425 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3429 if (strcmp(tokens[6], "match") != 0) {
3430 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3434 if (strcmp(tokens[7], "default") != 0) {
3435 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3439 if (strcmp(tokens[8], "action") != 0) {
3440 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3444 if (strcmp(tokens[9], "fwd") != 0) {
3445 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3449 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3451 if (strcmp(tokens[10], "drop") == 0) {
3452 if (n_tokens != 11) {
3453 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3457 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3458 } else if (strcmp(tokens[10], "port") == 0) {
3461 if (n_tokens != 12) {
3462 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3466 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3467 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3471 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3473 } else if (strcmp(tokens[10], "meta") == 0) {
3474 if (n_tokens != 11) {
3475 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3479 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3480 } else if (strcmp(tokens[10], "table") == 0) {
3483 if (n_tokens != 12) {
3484 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3488 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3489 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3493 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3496 snprintf(out, out_size, MSG_ARG_INVALID,
3497 "drop or port or meta or table");
3501 status = softnic_pipeline_table_rule_add_default(softnic,
3507 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3513 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
3516 * - line format: match <match> action <action>
3519 cli_rule_file_process(const char *file_name,
3520 size_t line_len_max,
3521 struct softnic_table_rule_match *m,
3522 struct softnic_table_rule_action *a,
3524 uint32_t *line_number,
3529 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
3535 struct softnic_table_rule_match *match;
3536 struct softnic_table_rule_action *action;
3538 char *pipeline_name, *file_name;
3539 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3542 if (n_tokens != 9) {
3543 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3547 pipeline_name = tokens[1];
3549 if (strcmp(tokens[2], "table") != 0) {
3550 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3554 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3555 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3559 if (strcmp(tokens[4], "rule") != 0) {
3560 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3564 if (strcmp(tokens[5], "add") != 0) {
3565 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3569 if (strcmp(tokens[6], "bulk") != 0) {
3570 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3574 file_name = tokens[7];
3576 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3578 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3582 /* Memory allocation. */
3583 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
3584 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
3585 data = calloc(n_rules, sizeof(void *));
3586 if (match == NULL ||
3589 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3596 /* Load rule file */
3597 n_rules_parsed = n_rules;
3598 status = cli_rule_file_process(file_name,
3607 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3613 if (n_rules_parsed != n_rules) {
3614 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3622 status = softnic_pipeline_table_rule_add_bulk(softnic,
3630 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3644 * pipeline <pipeline_name> table <table_id> rule delete
3648 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
3654 struct softnic_table_rule_match m;
3655 char *pipeline_name;
3656 uint32_t table_id, n_tokens_parsed, t0;
3660 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3664 pipeline_name = tokens[1];
3666 if (strcmp(tokens[2], "table") != 0) {
3667 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3671 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3672 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3676 if (strcmp(tokens[4], "rule") != 0) {
3677 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3681 if (strcmp(tokens[5], "delete") != 0) {
3682 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3689 n_tokens_parsed = parse_match(tokens + t0,
3694 if (n_tokens_parsed == 0)
3696 t0 += n_tokens_parsed;
3698 if (n_tokens != t0) {
3699 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3703 status = softnic_pipeline_table_rule_delete(softnic,
3708 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3714 * pipeline <pipeline_name> table <table_id> rule delete
3719 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
3725 char *pipeline_name;
3729 if (n_tokens != 8) {
3730 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3734 pipeline_name = tokens[1];
3736 if (strcmp(tokens[2], "table") != 0) {
3737 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3741 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3742 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3746 if (strcmp(tokens[4], "rule") != 0) {
3747 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3751 if (strcmp(tokens[5], "delete") != 0) {
3752 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3756 if (strcmp(tokens[6], "match") != 0) {
3757 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3761 if (strcmp(tokens[7], "default") != 0) {
3762 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3766 status = softnic_pipeline_table_rule_delete_default(softnic,
3770 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3776 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
3779 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
3781 uint32_t n_tokens __rte_unused,
3785 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3789 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
3790 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
3791 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
3794 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
3800 struct rte_table_action_meter_profile p;
3801 char *pipeline_name;
3802 uint32_t table_id, meter_profile_id;
3806 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3810 pipeline_name = tokens[1];
3812 if (strcmp(tokens[2], "table") != 0) {
3813 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3817 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3818 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3822 if (strcmp(tokens[4], "meter") != 0) {
3823 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3827 if (strcmp(tokens[5], "profile") != 0) {
3828 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3832 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3833 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3837 if (strcmp(tokens[7], "add") != 0) {
3838 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3842 if (strcmp(tokens[8], "srtcm") == 0) {
3843 if (n_tokens != 15) {
3844 snprintf(out, out_size, MSG_ARG_MISMATCH,
3849 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
3851 if (strcmp(tokens[9], "cir") != 0) {
3852 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3856 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
3857 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3861 if (strcmp(tokens[11], "cbs") != 0) {
3862 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3866 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
3867 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3871 if (strcmp(tokens[13], "ebs") != 0) {
3872 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
3876 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
3877 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
3880 } else if (strcmp(tokens[8], "trtcm") == 0) {
3881 if (n_tokens != 17) {
3882 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3886 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
3888 if (strcmp(tokens[9], "cir") != 0) {
3889 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3893 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
3894 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3898 if (strcmp(tokens[11], "pir") != 0) {
3899 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
3903 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
3904 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
3907 if (strcmp(tokens[13], "cbs") != 0) {
3908 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3912 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
3913 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3917 if (strcmp(tokens[15], "pbs") != 0) {
3918 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
3922 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
3923 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
3927 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3931 status = softnic_pipeline_table_mtr_profile_add(softnic,
3937 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3943 * pipeline <pipeline_name> table <table_id>
3944 * meter profile <meter_profile_id> delete
3947 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
3953 char *pipeline_name;
3954 uint32_t table_id, meter_profile_id;
3957 if (n_tokens != 8) {
3958 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3962 pipeline_name = tokens[1];
3964 if (strcmp(tokens[2], "table") != 0) {
3965 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3969 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3970 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3974 if (strcmp(tokens[4], "meter") != 0) {
3975 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3979 if (strcmp(tokens[5], "profile") != 0) {
3980 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3984 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3985 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3989 if (strcmp(tokens[7], "delete") != 0) {
3990 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3994 status = softnic_pipeline_table_mtr_profile_delete(softnic,
3999 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4005 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
4008 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
4010 uint32_t n_tokens __rte_unused,
4014 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4018 * pipeline <pipeline_name> table <table_id> dscp <file_name>
4021 * - exactly 64 lines
4022 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
4025 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4026 const char *file_name,
4027 uint32_t *line_number)
4032 /* Check input arguments */
4033 if (dscp_table == NULL ||
4034 file_name == NULL ||
4035 line_number == NULL) {
4041 /* Open input file */
4042 f = fopen(file_name, "r");
4049 for (dscp = 0, l = 1; ; l++) {
4052 enum rte_meter_color color;
4053 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4055 if (fgets(line, sizeof(line), f) == NULL)
4058 if (is_comment(line))
4061 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
4070 if (dscp >= RTE_DIM(dscp_table->entry) ||
4071 n_tokens != RTE_DIM(tokens) ||
4072 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
4073 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
4074 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
4075 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
4076 (strlen(tokens[2]) != 1)) {
4082 switch (tokens[2][0]) {
4085 color = e_RTE_METER_GREEN;
4090 color = e_RTE_METER_YELLOW;
4095 color = e_RTE_METER_RED;
4104 dscp_table->entry[dscp].tc_id = tc_id;
4105 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4106 dscp_table->entry[dscp].color = color;
4116 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
4122 struct rte_table_action_dscp_table dscp_table;
4123 char *pipeline_name, *file_name;
4124 uint32_t table_id, line_number;
4127 if (n_tokens != 6) {
4128 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4132 pipeline_name = tokens[1];
4134 if (strcmp(tokens[2], "table") != 0) {
4135 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4139 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4140 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4144 if (strcmp(tokens[4], "dscp") != 0) {
4145 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4149 file_name = tokens[5];
4151 status = load_dscp_table(&dscp_table, file_name, &line_number);
4153 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4157 status = softnic_pipeline_table_dscp_table_update(softnic,
4163 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4169 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4172 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4174 uint32_t n_tokens __rte_unused,
4178 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4182 * thread <thread_id> pipeline <pipeline_name> enable
4185 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4191 char *pipeline_name;
4195 if (n_tokens != 5) {
4196 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4200 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4201 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4205 if (strcmp(tokens[2], "pipeline") != 0) {
4206 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4210 pipeline_name = tokens[3];
4212 if (strcmp(tokens[4], "enable") != 0) {
4213 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4217 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4219 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4225 * thread <thread_id> pipeline <pipeline_name> disable
4228 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4234 char *pipeline_name;
4238 if (n_tokens != 5) {
4239 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4243 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4244 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4248 if (strcmp(tokens[2], "pipeline") != 0) {
4249 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4253 pipeline_name = tokens[3];
4255 if (strcmp(tokens[4], "disable") != 0) {
4256 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4260 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4262 snprintf(out, out_size, MSG_CMD_FAIL,
4263 "thread pipeline disable");
4269 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4271 char *tokens[CMD_MAX_TOKENS];
4272 uint32_t n_tokens = RTE_DIM(tokens);
4273 struct pmd_internals *softnic = arg;
4279 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4281 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4288 if (strcmp(tokens[0], "mempool") == 0) {
4289 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4293 if (strcmp(tokens[0], "link") == 0) {
4294 cmd_link(softnic, tokens, n_tokens, out, out_size);
4298 if (strcmp(tokens[0], "swq") == 0) {
4299 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4303 if (strcmp(tokens[0], "tmgr") == 0) {
4304 if (n_tokens == 2) {
4305 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4309 if (n_tokens >= 3 &&
4310 (strcmp(tokens[1], "shaper") == 0) &&
4311 (strcmp(tokens[2], "profile") == 0)) {
4312 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4316 if (n_tokens >= 3 &&
4317 (strcmp(tokens[1], "shared") == 0) &&
4318 (strcmp(tokens[2], "shaper") == 0)) {
4319 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
4323 if (n_tokens >= 2 &&
4324 (strcmp(tokens[1], "node") == 0)) {
4325 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
4330 if (strcmp(tokens[0], "tap") == 0) {
4331 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4335 if (strcmp(tokens[0], "port") == 0) {
4336 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4340 if (strcmp(tokens[0], "table") == 0) {
4341 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4345 if (strcmp(tokens[0], "pipeline") == 0) {
4346 if (n_tokens >= 3 &&
4347 (strcmp(tokens[2], "period") == 0)) {
4348 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4352 if (n_tokens >= 5 &&
4353 (strcmp(tokens[2], "port") == 0) &&
4354 (strcmp(tokens[3], "in") == 0) &&
4355 (strcmp(tokens[4], "bsz") == 0)) {
4356 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4360 if (n_tokens >= 5 &&
4361 (strcmp(tokens[2], "port") == 0) &&
4362 (strcmp(tokens[3], "out") == 0) &&
4363 (strcmp(tokens[4], "bsz") == 0)) {
4364 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4368 if (n_tokens >= 4 &&
4369 (strcmp(tokens[2], "table") == 0) &&
4370 (strcmp(tokens[3], "match") == 0)) {
4371 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4375 if (n_tokens >= 6 &&
4376 (strcmp(tokens[2], "port") == 0) &&
4377 (strcmp(tokens[3], "in") == 0) &&
4378 (strcmp(tokens[5], "table") == 0)) {
4379 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4384 if (n_tokens >= 6 &&
4385 (strcmp(tokens[2], "port") == 0) &&
4386 (strcmp(tokens[3], "in") == 0) &&
4387 (strcmp(tokens[5], "stats") == 0)) {
4388 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4393 if (n_tokens >= 6 &&
4394 (strcmp(tokens[2], "port") == 0) &&
4395 (strcmp(tokens[3], "in") == 0) &&
4396 (strcmp(tokens[5], "enable") == 0)) {
4397 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4402 if (n_tokens >= 6 &&
4403 (strcmp(tokens[2], "port") == 0) &&
4404 (strcmp(tokens[3], "in") == 0) &&
4405 (strcmp(tokens[5], "disable") == 0)) {
4406 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4411 if (n_tokens >= 6 &&
4412 (strcmp(tokens[2], "port") == 0) &&
4413 (strcmp(tokens[3], "out") == 0) &&
4414 (strcmp(tokens[5], "stats") == 0)) {
4415 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4420 if (n_tokens >= 5 &&
4421 (strcmp(tokens[2], "table") == 0) &&
4422 (strcmp(tokens[4], "stats") == 0)) {
4423 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4428 if (n_tokens >= 7 &&
4429 (strcmp(tokens[2], "table") == 0) &&
4430 (strcmp(tokens[4], "rule") == 0) &&
4431 (strcmp(tokens[5], "add") == 0) &&
4432 (strcmp(tokens[6], "match") == 0)) {
4433 if (n_tokens >= 8 &&
4434 (strcmp(tokens[7], "default") == 0)) {
4435 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4436 n_tokens, out, out_size);
4440 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4445 if (n_tokens >= 7 &&
4446 (strcmp(tokens[2], "table") == 0) &&
4447 (strcmp(tokens[4], "rule") == 0) &&
4448 (strcmp(tokens[5], "add") == 0) &&
4449 (strcmp(tokens[6], "bulk") == 0)) {
4450 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4451 n_tokens, out, out_size);
4455 if (n_tokens >= 7 &&
4456 (strcmp(tokens[2], "table") == 0) &&
4457 (strcmp(tokens[4], "rule") == 0) &&
4458 (strcmp(tokens[5], "delete") == 0) &&
4459 (strcmp(tokens[6], "match") == 0)) {
4460 if (n_tokens >= 8 &&
4461 (strcmp(tokens[7], "default") == 0)) {
4462 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
4463 n_tokens, out, out_size);
4467 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
4472 if (n_tokens >= 7 &&
4473 (strcmp(tokens[2], "table") == 0) &&
4474 (strcmp(tokens[4], "rule") == 0) &&
4475 (strcmp(tokens[5], "read") == 0) &&
4476 (strcmp(tokens[6], "stats") == 0)) {
4477 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
4482 if (n_tokens >= 8 &&
4483 (strcmp(tokens[2], "table") == 0) &&
4484 (strcmp(tokens[4], "meter") == 0) &&
4485 (strcmp(tokens[5], "profile") == 0) &&
4486 (strcmp(tokens[7], "add") == 0)) {
4487 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
4492 if (n_tokens >= 8 &&
4493 (strcmp(tokens[2], "table") == 0) &&
4494 (strcmp(tokens[4], "meter") == 0) &&
4495 (strcmp(tokens[5], "profile") == 0) &&
4496 (strcmp(tokens[7], "delete") == 0)) {
4497 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
4498 n_tokens, out, out_size);
4502 if (n_tokens >= 7 &&
4503 (strcmp(tokens[2], "table") == 0) &&
4504 (strcmp(tokens[4], "rule") == 0) &&
4505 (strcmp(tokens[5], "read") == 0) &&
4506 (strcmp(tokens[6], "meter") == 0)) {
4507 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
4512 if (n_tokens >= 5 &&
4513 (strcmp(tokens[2], "table") == 0) &&
4514 (strcmp(tokens[4], "dscp") == 0)) {
4515 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
4520 if (n_tokens >= 7 &&
4521 (strcmp(tokens[2], "table") == 0) &&
4522 (strcmp(tokens[4], "rule") == 0) &&
4523 (strcmp(tokens[5], "read") == 0) &&
4524 (strcmp(tokens[6], "ttl") == 0)) {
4525 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
4531 if (strcmp(tokens[0], "thread") == 0) {
4532 if (n_tokens >= 5 &&
4533 (strcmp(tokens[4], "enable") == 0)) {
4534 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
4539 if (n_tokens >= 5 &&
4540 (strcmp(tokens[4], "disable") == 0)) {
4541 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
4547 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
4551 softnic_cli_script_process(struct pmd_internals *softnic,
4552 const char *file_name,
4553 size_t msg_in_len_max,
4554 size_t msg_out_len_max)
4556 char *msg_in = NULL, *msg_out = NULL;
4559 /* Check input arguments */
4560 if (file_name == NULL ||
4561 (strlen(file_name) == 0) ||
4562 msg_in_len_max == 0 ||
4563 msg_out_len_max == 0)
4566 msg_in = malloc(msg_in_len_max + 1);
4567 msg_out = malloc(msg_out_len_max + 1);
4568 if (msg_in == NULL ||
4575 /* Open input file */
4576 f = fopen(file_name, "r");
4585 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
4588 printf("%s", msg_in);
4591 softnic_cli_process(msg_in,
4596 if (strlen(msg_out))
4597 printf("%s", msg_out);
4608 cli_rule_file_process(const char *file_name,
4609 size_t line_len_max,
4610 struct softnic_table_rule_match *m,
4611 struct softnic_table_rule_action *a,
4613 uint32_t *line_number,
4619 uint32_t rule_id, line_id;
4622 /* Check input arguments */
4623 if (file_name == NULL ||
4624 (strlen(file_name) == 0) ||
4625 line_len_max == 0) {
4630 /* Memory allocation */
4631 line = malloc(line_len_max + 1);
4638 f = fopen(file_name, "r");
4646 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
4647 char *tokens[CMD_MAX_TOKENS];
4648 uint32_t n_tokens, n_tokens_parsed, t0;
4650 /* Read next line from file. */
4651 if (fgets(line, line_len_max + 1, f) == NULL)
4655 if (is_comment(line))
4659 n_tokens = RTE_DIM(tokens);
4660 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
4672 n_tokens_parsed = parse_match(tokens + t0,
4677 if (n_tokens_parsed == 0) {
4681 t0 += n_tokens_parsed;
4684 n_tokens_parsed = parse_table_action(tokens + t0,
4689 if (n_tokens_parsed == 0) {
4693 t0 += n_tokens_parsed;
4695 /* Line completed. */
4696 if (t0 < n_tokens) {
4701 /* Increment rule count */
4712 *line_number = line_id;