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]);
344 cmd_tmgr(struct pmd_internals *softnic,
351 struct softnic_tmgr_port *tmgr_port;
354 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
360 tmgr_port = softnic_tmgr_port_create(softnic, name);
361 if (tmgr_port == NULL) {
362 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
371 cmd_tap(struct pmd_internals *softnic,
378 struct softnic_tap *tap;
381 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
387 tap = softnic_tap_create(softnic, name);
389 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
395 * port in action profile <profile_name>
396 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
397 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
400 cmd_port_in_action_profile(struct pmd_internals *softnic,
406 struct softnic_port_in_action_profile_params p;
407 struct softnic_port_in_action_profile *ap;
411 memset(&p, 0, sizeof(p));
414 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
418 if (strcmp(tokens[1], "in") != 0) {
419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
423 if (strcmp(tokens[2], "action") != 0) {
424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
428 if (strcmp(tokens[3], "profile") != 0) {
429 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
438 (strcmp(tokens[t0], "filter") == 0)) {
441 if (n_tokens < t0 + 10) {
442 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
446 if (strcmp(tokens[t0 + 1], "match") == 0) {
447 p.fltr.filter_on_match = 1;
448 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
449 p.fltr.filter_on_match = 0;
451 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
455 if (strcmp(tokens[t0 + 2], "offset") != 0) {
456 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
460 if (softnic_parser_read_uint32(&p.fltr.key_offset,
461 tokens[t0 + 3]) != 0) {
462 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
466 if (strcmp(tokens[t0 + 4], "mask") != 0) {
467 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
471 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
472 if ((softnic_parse_hex_string(tokens[t0 + 5],
473 p.fltr.key_mask, &size) != 0) ||
474 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
475 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
479 if (strcmp(tokens[t0 + 6], "key") != 0) {
480 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
484 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
485 if ((softnic_parse_hex_string(tokens[t0 + 7],
486 p.fltr.key, &size) != 0) ||
487 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
488 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
492 if (strcmp(tokens[t0 + 8], "port") != 0) {
493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
497 if (softnic_parser_read_uint32(&p.fltr.port_id,
498 tokens[t0 + 9]) != 0) {
499 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
503 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
508 (strcmp(tokens[t0], "balance") == 0)) {
511 if (n_tokens < t0 + 22) {
512 snprintf(out, out_size, MSG_ARG_MISMATCH,
513 "port in action profile balance");
517 if (strcmp(tokens[t0 + 1], "offset") != 0) {
518 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
522 if (softnic_parser_read_uint32(&p.lb.key_offset,
523 tokens[t0 + 2]) != 0) {
524 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
528 if (strcmp(tokens[t0 + 3], "mask") != 0) {
529 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
533 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
534 if (softnic_parse_hex_string(tokens[t0 + 4],
535 p.lb.key_mask, &p.lb.key_size) != 0) {
536 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
540 if (strcmp(tokens[t0 + 5], "port") != 0) {
541 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
545 for (i = 0; i < 16; i++)
546 if (softnic_parser_read_uint32(&p.lb.port_id[i],
547 tokens[t0 + 6 + i]) != 0) {
548 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
552 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
557 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
561 ap = softnic_port_in_action_profile_create(softnic, name, &p);
563 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
569 * table action profile <profile_name>
573 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
574 * [meter srtcm | trtcm
576 * stats none | pkts | bytes | both]
577 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
578 * [encap ether | vlan | qinq | mpls | pppoe]
583 * [stats pkts | bytes | both]
587 cmd_table_action_profile(struct pmd_internals *softnic,
593 struct softnic_table_action_profile_params p;
594 struct softnic_table_action_profile *ap;
598 memset(&p, 0, sizeof(p));
601 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
605 if (strcmp(tokens[1], "action") != 0) {
606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
610 if (strcmp(tokens[2], "profile") != 0) {
611 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
617 if (strcmp(tokens[4], "ipv4") == 0) {
618 p.common.ip_version = 1;
619 } else if (strcmp(tokens[4], "ipv6") == 0) {
620 p.common.ip_version = 0;
622 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
626 if (strcmp(tokens[5], "offset") != 0) {
627 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
631 if (softnic_parser_read_uint32(&p.common.ip_offset,
633 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
637 if (strcmp(tokens[7], "fwd") != 0) {
638 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
642 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
646 (strcmp(tokens[t0], "balance") == 0)) {
647 if (n_tokens < t0 + 7) {
648 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
652 if (strcmp(tokens[t0 + 1], "offset") != 0) {
653 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
657 if (softnic_parser_read_uint32(&p.lb.key_offset,
658 tokens[t0 + 2]) != 0) {
659 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
663 if (strcmp(tokens[t0 + 3], "mask") != 0) {
664 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
668 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
669 if (softnic_parse_hex_string(tokens[t0 + 4],
670 p.lb.key_mask, &p.lb.key_size) != 0) {
671 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
675 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
676 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
680 if (softnic_parser_read_uint32(&p.lb.out_offset,
681 tokens[t0 + 6]) != 0) {
682 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
686 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
691 (strcmp(tokens[t0], "meter") == 0)) {
692 if (n_tokens < t0 + 6) {
693 snprintf(out, out_size, MSG_ARG_MISMATCH,
694 "table action profile meter");
698 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
699 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
700 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
701 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
703 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
708 if (strcmp(tokens[t0 + 2], "tc") != 0) {
709 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
713 if (softnic_parser_read_uint32(&p.mtr.n_tc,
714 tokens[t0 + 3]) != 0) {
715 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
719 if (strcmp(tokens[t0 + 4], "stats") != 0) {
720 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
724 if (strcmp(tokens[t0 + 5], "none") == 0) {
725 p.mtr.n_packets_enabled = 0;
726 p.mtr.n_bytes_enabled = 0;
727 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
728 p.mtr.n_packets_enabled = 1;
729 p.mtr.n_bytes_enabled = 0;
730 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
731 p.mtr.n_packets_enabled = 0;
732 p.mtr.n_bytes_enabled = 1;
733 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
734 p.mtr.n_packets_enabled = 1;
735 p.mtr.n_bytes_enabled = 1;
737 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
738 "none or pkts or bytes or both");
742 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
747 (strcmp(tokens[t0], "tm") == 0)) {
748 if (n_tokens < t0 + 5) {
749 snprintf(out, out_size, MSG_ARG_MISMATCH,
750 "table action profile tm");
754 if (strcmp(tokens[t0 + 1], "spp") != 0) {
755 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
759 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
760 tokens[t0 + 2]) != 0) {
761 snprintf(out, out_size, MSG_ARG_INVALID,
762 "n_subports_per_port");
766 if (strcmp(tokens[t0 + 3], "pps") != 0) {
767 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
771 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
772 tokens[t0 + 4]) != 0) {
773 snprintf(out, out_size, MSG_ARG_INVALID,
774 "n_pipes_per_subport");
778 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
783 (strcmp(tokens[t0], "encap") == 0)) {
784 if (n_tokens < t0 + 2) {
785 snprintf(out, out_size, MSG_ARG_MISMATCH,
786 "action profile encap");
790 if (strcmp(tokens[t0 + 1], "ether") == 0) {
791 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
792 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
793 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
794 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
795 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
796 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
797 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
798 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
799 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
801 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
805 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
810 (strcmp(tokens[t0], "nat") == 0)) {
811 if (n_tokens < t0 + 4) {
812 snprintf(out, out_size, MSG_ARG_MISMATCH,
813 "table action profile nat");
817 if (strcmp(tokens[t0 + 1], "src") == 0) {
818 p.nat.source_nat = 1;
819 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
820 p.nat.source_nat = 0;
822 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
827 if (strcmp(tokens[t0 + 2], "proto") != 0) {
828 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
832 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
834 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
837 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
842 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
847 (strcmp(tokens[t0], "ttl") == 0)) {
848 if (n_tokens < t0 + 4) {
849 snprintf(out, out_size, MSG_ARG_MISMATCH,
850 "table action profile ttl");
854 if (strcmp(tokens[t0 + 1], "drop") == 0) {
856 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
859 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
864 if (strcmp(tokens[t0 + 2], "stats") != 0) {
865 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
869 if (strcmp(tokens[t0 + 3], "none") == 0) {
870 p.ttl.n_packets_enabled = 0;
871 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
872 p.ttl.n_packets_enabled = 1;
874 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
879 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
884 (strcmp(tokens[t0], "stats") == 0)) {
885 if (n_tokens < t0 + 2) {
886 snprintf(out, out_size, MSG_ARG_MISMATCH,
887 "table action profile stats");
891 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
892 p.stats.n_packets_enabled = 1;
893 p.stats.n_bytes_enabled = 0;
894 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
895 p.stats.n_packets_enabled = 0;
896 p.stats.n_bytes_enabled = 1;
897 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
898 p.stats.n_packets_enabled = 1;
899 p.stats.n_bytes_enabled = 1;
901 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
902 "pkts or bytes or both");
906 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
911 (strcmp(tokens[t0], "time") == 0)) {
912 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
917 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
921 ap = softnic_table_action_profile_create(softnic, name, &p);
923 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
929 * pipeline <pipeline_name>
930 * period <timer_period_ms>
931 * offset_port_id <offset_port_id>
934 cmd_pipeline(struct pmd_internals *softnic,
940 struct pipeline_params p;
942 struct pipeline *pipeline;
945 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
951 if (strcmp(tokens[2], "period") != 0) {
952 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
956 if (softnic_parser_read_uint32(&p.timer_period_ms,
958 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
962 if (strcmp(tokens[4], "offset_port_id") != 0) {
963 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
967 if (softnic_parser_read_uint32(&p.offset_port_id,
969 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
973 pipeline = softnic_pipeline_create(softnic, name, &p);
974 if (pipeline == NULL) {
975 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
981 * pipeline <pipeline_name> port in
983 * link <link_name> rxq <queue_id>
986 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
987 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
988 * [action <port_in_action_profile_name>]
992 cmd_pipeline_port_in(struct pmd_internals *softnic,
998 struct softnic_port_in_params p;
1001 int enabled, status;
1004 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1008 pipeline_name = tokens[1];
1010 if (strcmp(tokens[2], "port") != 0) {
1011 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1015 if (strcmp(tokens[3], "in") != 0) {
1016 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1020 if (strcmp(tokens[4], "bsz") != 0) {
1021 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1025 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1026 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1032 if (strcmp(tokens[t0], "link") == 0) {
1033 if (n_tokens < t0 + 4) {
1034 snprintf(out, out_size, MSG_ARG_MISMATCH,
1035 "pipeline port in link");
1039 p.type = PORT_IN_RXQ;
1041 p.dev_name = tokens[t0 + 1];
1043 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1044 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1048 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1049 tokens[t0 + 3]) != 0) {
1050 snprintf(out, out_size, MSG_ARG_INVALID,
1055 } else if (strcmp(tokens[t0], "swq") == 0) {
1056 if (n_tokens < t0 + 2) {
1057 snprintf(out, out_size, MSG_ARG_MISMATCH,
1058 "pipeline port in swq");
1062 p.type = PORT_IN_SWQ;
1064 p.dev_name = tokens[t0 + 1];
1067 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1068 if (n_tokens < t0 + 2) {
1069 snprintf(out, out_size, MSG_ARG_MISMATCH,
1070 "pipeline port in tmgr");
1074 p.type = PORT_IN_TMGR;
1076 p.dev_name = tokens[t0 + 1];
1079 } else if (strcmp(tokens[t0], "tap") == 0) {
1080 if (n_tokens < t0 + 6) {
1081 snprintf(out, out_size, MSG_ARG_MISMATCH,
1082 "pipeline port in tap");
1086 p.type = PORT_IN_TAP;
1088 p.dev_name = tokens[t0 + 1];
1090 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1091 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1096 p.tap.mempool_name = tokens[t0 + 3];
1098 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1099 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1104 if (softnic_parser_read_uint32(&p.tap.mtu,
1105 tokens[t0 + 5]) != 0) {
1106 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1111 } else if (strcmp(tokens[t0], "source") == 0) {
1112 if (n_tokens < t0 + 6) {
1113 snprintf(out, out_size, MSG_ARG_MISMATCH,
1114 "pipeline port in source");
1118 p.type = PORT_IN_SOURCE;
1122 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1123 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1128 p.source.mempool_name = tokens[t0 + 2];
1130 if (strcmp(tokens[t0 + 3], "file") != 0) {
1131 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1136 p.source.file_name = tokens[t0 + 4];
1138 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1139 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1144 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1145 tokens[t0 + 6]) != 0) {
1146 snprintf(out, out_size, MSG_ARG_INVALID,
1153 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1157 p.action_profile_name = NULL;
1158 if (n_tokens > t0 &&
1159 (strcmp(tokens[t0], "action") == 0)) {
1160 if (n_tokens < t0 + 2) {
1161 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1165 p.action_profile_name = tokens[t0 + 1];
1171 if (n_tokens > t0 &&
1172 (strcmp(tokens[t0], "disabled") == 0)) {
1178 if (n_tokens != t0) {
1179 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1183 status = softnic_pipeline_port_in_create(softnic,
1188 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1194 * pipeline <pipeline_name> port out
1196 * link <link_name> txq <txq_id>
1198 * | tmgr <tmgr_name>
1200 * | sink [file <file_name> pkts <max_n_pkts>]
1203 cmd_pipeline_port_out(struct pmd_internals *softnic,
1209 struct softnic_port_out_params p;
1210 char *pipeline_name;
1213 memset(&p, 0, sizeof(p));
1216 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1220 pipeline_name = tokens[1];
1222 if (strcmp(tokens[2], "port") != 0) {
1223 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1227 if (strcmp(tokens[3], "out") != 0) {
1228 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1232 if (strcmp(tokens[4], "bsz") != 0) {
1233 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1237 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1238 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1242 if (strcmp(tokens[6], "link") == 0) {
1243 if (n_tokens != 10) {
1244 snprintf(out, out_size, MSG_ARG_MISMATCH,
1245 "pipeline port out link");
1249 p.type = PORT_OUT_TXQ;
1251 p.dev_name = tokens[7];
1253 if (strcmp(tokens[8], "txq") != 0) {
1254 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1258 if (softnic_parser_read_uint16(&p.txq.queue_id,
1260 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1263 } else if (strcmp(tokens[6], "swq") == 0) {
1264 if (n_tokens != 8) {
1265 snprintf(out, out_size, MSG_ARG_MISMATCH,
1266 "pipeline port out swq");
1270 p.type = PORT_OUT_SWQ;
1272 p.dev_name = tokens[7];
1273 } else if (strcmp(tokens[6], "tmgr") == 0) {
1274 if (n_tokens != 8) {
1275 snprintf(out, out_size, MSG_ARG_MISMATCH,
1276 "pipeline port out tmgr");
1280 p.type = PORT_OUT_TMGR;
1282 p.dev_name = tokens[7];
1283 } else if (strcmp(tokens[6], "tap") == 0) {
1284 if (n_tokens != 8) {
1285 snprintf(out, out_size, MSG_ARG_MISMATCH,
1286 "pipeline port out tap");
1290 p.type = PORT_OUT_TAP;
1292 p.dev_name = tokens[7];
1293 } else if (strcmp(tokens[6], "sink") == 0) {
1294 if ((n_tokens != 7) && (n_tokens != 11)) {
1295 snprintf(out, out_size, MSG_ARG_MISMATCH,
1296 "pipeline port out sink");
1300 p.type = PORT_OUT_SINK;
1304 if (n_tokens == 7) {
1305 p.sink.file_name = NULL;
1306 p.sink.max_n_pkts = 0;
1308 if (strcmp(tokens[7], "file") != 0) {
1309 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1314 p.sink.file_name = tokens[8];
1316 if (strcmp(tokens[9], "pkts") != 0) {
1317 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1321 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1323 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1328 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1332 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1334 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1340 * pipeline <pipeline_name> table
1344 * offset <ip_header_offset>
1347 * offset <key_offset>
1353 * offset <key_offset>
1354 * buckets <n_buckets>
1358 * offset <ip_header_offset>
1361 * [action <table_action_profile_name>]
1364 cmd_pipeline_table(struct pmd_internals *softnic,
1370 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1371 struct softnic_table_params p;
1372 char *pipeline_name;
1377 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1381 pipeline_name = tokens[1];
1383 if (strcmp(tokens[2], "table") != 0) {
1384 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1388 if (strcmp(tokens[3], "match") != 0) {
1389 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1394 if (strcmp(tokens[t0], "acl") == 0) {
1395 if (n_tokens < t0 + 6) {
1396 snprintf(out, out_size, MSG_ARG_MISMATCH,
1397 "pipeline table acl");
1401 p.match_type = TABLE_ACL;
1403 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1404 p.match.acl.ip_version = 1;
1405 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1406 p.match.acl.ip_version = 0;
1408 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1413 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1414 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1418 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1419 tokens[t0 + 3]) != 0) {
1420 snprintf(out, out_size, MSG_ARG_INVALID,
1421 "ip_header_offset");
1425 if (strcmp(tokens[t0 + 4], "size") != 0) {
1426 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1430 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1431 tokens[t0 + 5]) != 0) {
1432 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1437 } else if (strcmp(tokens[t0], "array") == 0) {
1438 if (n_tokens < t0 + 5) {
1439 snprintf(out, out_size, MSG_ARG_MISMATCH,
1440 "pipeline table array");
1444 p.match_type = TABLE_ARRAY;
1446 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1447 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1451 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1452 tokens[t0 + 2]) != 0) {
1453 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1457 if (strcmp(tokens[t0 + 3], "size") != 0) {
1458 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1462 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1463 tokens[t0 + 4]) != 0) {
1464 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1469 } else if (strcmp(tokens[t0], "hash") == 0) {
1470 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1472 if (n_tokens < t0 + 12) {
1473 snprintf(out, out_size, MSG_ARG_MISMATCH,
1474 "pipeline table hash");
1478 p.match_type = TABLE_HASH;
1480 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1481 p.match.hash.extendable_bucket = 1;
1482 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1483 p.match.hash.extendable_bucket = 0;
1485 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1490 if (strcmp(tokens[t0 + 2], "key") != 0) {
1491 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1495 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1496 tokens[t0 + 3]) != 0) ||
1497 p.match.hash.key_size == 0 ||
1498 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1499 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1503 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1504 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1508 if ((softnic_parse_hex_string(tokens[t0 + 5],
1509 key_mask, &key_mask_size) != 0) ||
1510 key_mask_size != p.match.hash.key_size) {
1511 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1514 p.match.hash.key_mask = key_mask;
1516 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1521 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1522 tokens[t0 + 7]) != 0) {
1523 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1527 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1528 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1532 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1533 tokens[t0 + 9]) != 0) {
1534 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1538 if (strcmp(tokens[t0 + 10], "size") != 0) {
1539 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1543 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1544 tokens[t0 + 11]) != 0) {
1545 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1550 } else if (strcmp(tokens[t0], "lpm") == 0) {
1551 if (n_tokens < t0 + 6) {
1552 snprintf(out, out_size, MSG_ARG_MISMATCH,
1553 "pipeline table lpm");
1557 p.match_type = TABLE_LPM;
1559 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1560 p.match.lpm.key_size = 4;
1561 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1562 p.match.lpm.key_size = 16;
1564 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1569 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1570 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1574 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1575 tokens[t0 + 3]) != 0) {
1576 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1580 if (strcmp(tokens[t0 + 4], "size") != 0) {
1581 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1585 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1586 tokens[t0 + 5]) != 0) {
1587 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1592 } else if (strcmp(tokens[t0], "stub") == 0) {
1593 p.match_type = TABLE_STUB;
1597 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1601 p.action_profile_name = NULL;
1602 if (n_tokens > t0 &&
1603 (strcmp(tokens[t0], "action") == 0)) {
1604 if (n_tokens < t0 + 2) {
1605 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1609 p.action_profile_name = tokens[t0 + 1];
1614 if (n_tokens > t0) {
1615 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1619 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1621 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1627 * pipeline <pipeline_name> port in <port_id> table <table_id>
1630 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1636 char *pipeline_name;
1637 uint32_t port_id, table_id;
1640 if (n_tokens != 7) {
1641 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1645 pipeline_name = tokens[1];
1647 if (strcmp(tokens[2], "port") != 0) {
1648 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1652 if (strcmp(tokens[3], "in") != 0) {
1653 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1657 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1658 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1662 if (strcmp(tokens[5], "table") != 0) {
1663 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1667 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1668 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1672 status = softnic_pipeline_port_in_connect_to_table(softnic,
1677 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1683 * pipeline <pipeline_name> port in <port_id> stats read [clear]
1686 #define MSG_PIPELINE_PORT_IN_STATS \
1687 "Pkts in: %" PRIu64 "\n" \
1688 "Pkts dropped by AH: %" PRIu64 "\n" \
1689 "Pkts dropped by other: %" PRIu64 "\n"
1692 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
1698 struct rte_pipeline_port_in_stats stats;
1699 char *pipeline_name;
1703 if (n_tokens != 7 &&
1705 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1709 pipeline_name = tokens[1];
1711 if (strcmp(tokens[2], "port") != 0) {
1712 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1716 if (strcmp(tokens[3], "in") != 0) {
1717 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1721 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1722 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1726 if (strcmp(tokens[5], "stats") != 0) {
1727 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1731 if (strcmp(tokens[6], "read") != 0) {
1732 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1737 if (n_tokens == 8) {
1738 if (strcmp(tokens[7], "clear") != 0) {
1739 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1746 status = softnic_pipeline_port_in_stats_read(softnic,
1752 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1756 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
1757 stats.stats.n_pkts_in,
1758 stats.n_pkts_dropped_by_ah,
1759 stats.stats.n_pkts_drop);
1763 * pipeline <pipeline_name> port in <port_id> enable
1766 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1772 char *pipeline_name;
1776 if (n_tokens != 6) {
1777 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1781 pipeline_name = tokens[1];
1783 if (strcmp(tokens[2], "port") != 0) {
1784 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1788 if (strcmp(tokens[3], "in") != 0) {
1789 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1793 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1794 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1798 if (strcmp(tokens[5], "enable") != 0) {
1799 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1803 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1805 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1811 * pipeline <pipeline_name> port in <port_id> disable
1814 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1820 char *pipeline_name;
1824 if (n_tokens != 6) {
1825 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1829 pipeline_name = tokens[1];
1831 if (strcmp(tokens[2], "port") != 0) {
1832 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1836 if (strcmp(tokens[3], "in") != 0) {
1837 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1841 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1842 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1846 if (strcmp(tokens[5], "disable") != 0) {
1847 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1851 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1853 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1859 * pipeline <pipeline_name> port out <port_id> stats read [clear]
1861 #define MSG_PIPELINE_PORT_OUT_STATS \
1862 "Pkts in: %" PRIu64 "\n" \
1863 "Pkts dropped by AH: %" PRIu64 "\n" \
1864 "Pkts dropped by other: %" PRIu64 "\n"
1867 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
1873 struct rte_pipeline_port_out_stats stats;
1874 char *pipeline_name;
1878 if (n_tokens != 7 &&
1880 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1884 pipeline_name = tokens[1];
1886 if (strcmp(tokens[2], "port") != 0) {
1887 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1891 if (strcmp(tokens[3], "out") != 0) {
1892 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1896 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1897 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1901 if (strcmp(tokens[5], "stats") != 0) {
1902 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1906 if (strcmp(tokens[6], "read") != 0) {
1907 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1912 if (n_tokens == 8) {
1913 if (strcmp(tokens[7], "clear") != 0) {
1914 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1921 status = softnic_pipeline_port_out_stats_read(softnic,
1927 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1931 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
1932 stats.stats.n_pkts_in,
1933 stats.n_pkts_dropped_by_ah,
1934 stats.stats.n_pkts_drop);
1938 * pipeline <pipeline_name> table <table_id> stats read [clear]
1940 #define MSG_PIPELINE_TABLE_STATS \
1941 "Pkts in: %" PRIu64 "\n" \
1942 "Pkts in with lookup miss: %" PRIu64 "\n" \
1943 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
1944 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
1945 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
1946 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
1949 cmd_pipeline_table_stats(struct pmd_internals *softnic,
1955 struct rte_pipeline_table_stats stats;
1956 char *pipeline_name;
1960 if (n_tokens != 6 &&
1962 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1966 pipeline_name = tokens[1];
1968 if (strcmp(tokens[2], "table") != 0) {
1969 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1973 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
1974 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1978 if (strcmp(tokens[4], "stats") != 0) {
1979 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1983 if (strcmp(tokens[5], "read") != 0) {
1984 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1989 if (n_tokens == 7) {
1990 if (strcmp(tokens[6], "clear") != 0) {
1991 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1998 status = softnic_pipeline_table_stats_read(softnic,
2004 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2008 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2009 stats.stats.n_pkts_in,
2010 stats.stats.n_pkts_lookup_miss,
2011 stats.n_pkts_dropped_by_lkp_hit_ah,
2012 stats.n_pkts_dropped_lkp_hit,
2013 stats.n_pkts_dropped_by_lkp_miss_ah,
2014 stats.n_pkts_dropped_lkp_miss);
2022 * priority <priority>
2023 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2024 * <sp0> <sp1> <dp0> <dp1> <proto>
2028 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2029 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2030 * | ipv4_addr <addr>
2031 * | ipv6_addr <addr>
2032 * | qinq <svlan> <cvlan>
2034 * ipv4 | ipv6 <addr> <depth>
2036 struct pkt_key_qinq {
2037 uint16_t ethertype_svlan;
2039 uint16_t ethertype_cvlan;
2041 } __attribute__((__packed__));
2043 struct pkt_key_ipv4_5tuple {
2044 uint8_t time_to_live;
2046 uint16_t hdr_checksum;
2051 } __attribute__((__packed__));
2053 struct pkt_key_ipv6_5tuple {
2054 uint16_t payload_length;
2061 } __attribute__((__packed__));
2063 struct pkt_key_ipv4_addr {
2065 } __attribute__((__packed__));
2067 struct pkt_key_ipv6_addr {
2069 } __attribute__((__packed__));
2072 parse_match(char **tokens,
2076 struct softnic_table_rule_match *m)
2078 memset(m, 0, sizeof(*m));
2083 if (strcmp(tokens[0], "match") != 0) {
2084 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2088 if (strcmp(tokens[1], "acl") == 0) {
2089 if (n_tokens < 14) {
2090 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2094 m->match_type = TABLE_ACL;
2096 if (strcmp(tokens[2], "priority") != 0) {
2097 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2101 if (softnic_parser_read_uint32(&m->match.acl.priority,
2103 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2107 if (strcmp(tokens[4], "ipv4") == 0) {
2108 struct in_addr saddr, daddr;
2110 m->match.acl.ip_version = 1;
2112 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2113 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2116 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2118 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2119 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2122 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2123 } else if (strcmp(tokens[4], "ipv6") == 0) {
2124 struct in6_addr saddr, daddr;
2126 m->match.acl.ip_version = 0;
2128 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2129 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2132 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2134 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2135 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2138 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2140 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2145 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2147 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2151 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2153 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2157 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2158 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2162 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2163 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2167 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2168 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2172 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2173 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2177 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2178 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2182 m->match.acl.proto_mask = 0xff;
2187 if (strcmp(tokens[1], "array") == 0) {
2189 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2193 m->match_type = TABLE_ARRAY;
2195 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2196 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2203 if (strcmp(tokens[1], "hash") == 0) {
2205 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2209 m->match_type = TABLE_HASH;
2211 if (strcmp(tokens[2], "raw") == 0) {
2212 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2215 snprintf(out, out_size, MSG_ARG_MISMATCH,
2220 if (softnic_parse_hex_string(tokens[3],
2221 m->match.hash.key, &key_size) != 0) {
2222 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2229 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2230 struct pkt_key_ipv4_5tuple *ipv4 =
2231 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2232 struct in_addr saddr, daddr;
2237 snprintf(out, out_size, MSG_ARG_MISMATCH,
2242 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2243 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2247 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2248 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2252 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2253 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2257 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2258 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2262 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2263 snprintf(out, out_size, MSG_ARG_INVALID,
2268 ipv4->sa = saddr.s_addr;
2269 ipv4->da = daddr.s_addr;
2270 ipv4->sp = rte_cpu_to_be_16(sp);
2271 ipv4->dp = rte_cpu_to_be_16(dp);
2272 ipv4->proto = proto;
2275 } /* hash ipv4_5tuple */
2277 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2278 struct pkt_key_ipv6_5tuple *ipv6 =
2279 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2280 struct in6_addr saddr, daddr;
2285 snprintf(out, out_size, MSG_ARG_MISMATCH,
2290 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2291 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2295 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2296 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2300 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2301 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2305 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2306 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2310 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2311 snprintf(out, out_size, MSG_ARG_INVALID,
2316 memcpy(ipv6->sa, saddr.s6_addr, 16);
2317 memcpy(ipv6->da, daddr.s6_addr, 16);
2318 ipv6->sp = rte_cpu_to_be_16(sp);
2319 ipv6->dp = rte_cpu_to_be_16(dp);
2320 ipv6->proto = proto;
2323 } /* hash ipv6_5tuple */
2325 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2326 struct pkt_key_ipv4_addr *ipv4_addr =
2327 (struct pkt_key_ipv4_addr *)m->match.hash.key;
2328 struct in_addr addr;
2331 snprintf(out, out_size, MSG_ARG_MISMATCH,
2336 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2337 snprintf(out, out_size, MSG_ARG_INVALID,
2342 ipv4_addr->addr = addr.s_addr;
2345 } /* hash ipv4_addr */
2347 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2348 struct pkt_key_ipv6_addr *ipv6_addr =
2349 (struct pkt_key_ipv6_addr *)m->match.hash.key;
2350 struct in6_addr addr;
2353 snprintf(out, out_size, MSG_ARG_MISMATCH,
2358 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2359 snprintf(out, out_size, MSG_ARG_INVALID,
2364 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2367 } /* hash ipv6_5tuple */
2369 if (strcmp(tokens[2], "qinq") == 0) {
2370 struct pkt_key_qinq *qinq =
2371 (struct pkt_key_qinq *)m->match.hash.key;
2372 uint16_t svlan, cvlan;
2375 snprintf(out, out_size, MSG_ARG_MISMATCH,
2380 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
2382 snprintf(out, out_size, MSG_ARG_INVALID,
2387 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2389 snprintf(out, out_size, MSG_ARG_INVALID,
2394 qinq->svlan = rte_cpu_to_be_16(svlan);
2395 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2400 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2404 if (strcmp(tokens[1], "lpm") == 0) {
2406 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2410 m->match_type = TABLE_LPM;
2412 if (strcmp(tokens[2], "ipv4") == 0) {
2413 struct in_addr addr;
2415 m->match.lpm.ip_version = 1;
2417 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2418 snprintf(out, out_size, MSG_ARG_INVALID,
2423 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2424 } else if (strcmp(tokens[2], "ipv6") == 0) {
2425 struct in6_addr addr;
2427 m->match.lpm.ip_version = 0;
2429 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2430 snprintf(out, out_size, MSG_ARG_INVALID,
2435 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2437 snprintf(out, out_size, MSG_ARG_MISMATCH,
2442 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2443 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2450 snprintf(out, out_size, MSG_ARG_MISMATCH,
2451 "acl or array or hash or lpm");
2463 * | table <table_id>
2464 * [balance <out0> ... <out7>]
2466 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2467 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2468 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2469 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2470 * [tm subport <subport_id> pipe <pipe_id>]
2473 * | vlan <da> <sa> <pcp> <dei> <vid>
2474 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2475 * | mpls unicast | multicast
2477 * label0 <label> <tc> <ttl>
2478 * [label1 <label> <tc> <ttl>
2479 * [label2 <label> <tc> <ttl>
2480 * [label3 <label> <tc> <ttl>]]]
2481 * | pppoe <da> <sa> <session_id>]
2482 * [nat ipv4 | ipv6 <addr> <port>]
2488 * <pa> ::= g | y | r | drop
2491 parse_table_action_fwd(char **tokens,
2493 struct softnic_table_rule_action *a)
2495 if (n_tokens == 0 ||
2496 (strcmp(tokens[0], "fwd") != 0))
2502 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2503 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2504 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2508 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2512 softnic_parser_read_uint32(&id, tokens[1]))
2515 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2517 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2521 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2522 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2523 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2527 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2531 softnic_parser_read_uint32(&id, tokens[1]))
2534 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2536 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2544 parse_table_action_balance(char **tokens,
2546 struct softnic_table_rule_action *a)
2550 if (n_tokens == 0 ||
2551 (strcmp(tokens[0], "balance") != 0))
2557 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2560 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2561 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2564 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2565 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2569 parse_policer_action(char *token, enum rte_table_action_policer *a)
2571 if (strcmp(token, "g") == 0) {
2572 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2576 if (strcmp(token, "y") == 0) {
2577 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2581 if (strcmp(token, "r") == 0) {
2582 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2586 if (strcmp(token, "drop") == 0) {
2587 *a = RTE_TABLE_ACTION_POLICER_DROP;
2595 parse_table_action_meter_tc(char **tokens,
2597 struct rte_table_action_mtr_tc_params *mtr)
2600 strcmp(tokens[0], "meter") ||
2601 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2602 strcmp(tokens[2], "policer") ||
2603 strcmp(tokens[3], "g") ||
2604 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2605 strcmp(tokens[5], "y") ||
2606 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2607 strcmp(tokens[7], "r") ||
2608 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2615 parse_table_action_meter(char **tokens,
2617 struct softnic_table_rule_action *a)
2619 if (n_tokens == 0 ||
2620 strcmp(tokens[0], "meter"))
2626 if (n_tokens < 10 ||
2627 strcmp(tokens[0], "tc0") ||
2628 (parse_table_action_meter_tc(tokens + 1,
2630 &a->mtr.mtr[0]) == 0))
2636 if (n_tokens == 0 ||
2637 strcmp(tokens[0], "tc1")) {
2639 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2643 if (n_tokens < 30 ||
2644 (parse_table_action_meter_tc(tokens + 1,
2645 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
2646 strcmp(tokens[10], "tc2") ||
2647 (parse_table_action_meter_tc(tokens + 11,
2648 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
2649 strcmp(tokens[20], "tc3") ||
2650 (parse_table_action_meter_tc(tokens + 21,
2651 n_tokens - 21, &a->mtr.mtr[3]) == 0))
2654 a->mtr.tc_mask = 0xF;
2655 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2656 return 1 + 10 + 3 * 10;
2660 parse_table_action_tm(char **tokens,
2662 struct softnic_table_rule_action *a)
2664 uint32_t subport_id, pipe_id;
2667 strcmp(tokens[0], "tm") ||
2668 strcmp(tokens[1], "subport") ||
2669 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
2670 strcmp(tokens[3], "pipe") ||
2671 softnic_parser_read_uint32(&pipe_id, tokens[4]))
2674 a->tm.subport_id = subport_id;
2675 a->tm.pipe_id = pipe_id;
2676 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
2681 parse_table_action_encap(char **tokens,
2683 struct softnic_table_rule_action *a)
2685 if (n_tokens == 0 ||
2686 strcmp(tokens[0], "encap"))
2693 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
2695 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
2696 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
2699 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
2700 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2705 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
2706 uint32_t pcp, dei, vid;
2709 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
2710 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
2711 softnic_parser_read_uint32(&pcp, tokens[3]) ||
2713 softnic_parser_read_uint32(&dei, tokens[4]) ||
2715 softnic_parser_read_uint32(&vid, tokens[5]) ||
2719 a->encap.vlan.vlan.pcp = pcp & 0x7;
2720 a->encap.vlan.vlan.dei = dei & 0x1;
2721 a->encap.vlan.vlan.vid = vid & 0xFFF;
2722 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
2723 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2728 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
2729 uint32_t svlan_pcp, svlan_dei, svlan_vid;
2730 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
2733 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
2734 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
2735 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
2737 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
2739 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
2740 svlan_vid > 0xFFF ||
2741 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
2743 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
2745 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
2749 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
2750 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
2751 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
2752 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
2753 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
2754 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
2755 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
2756 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2761 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
2762 uint32_t label, tc, ttl;
2767 if (strcmp(tokens[1], "unicast") == 0)
2768 a->encap.mpls.unicast = 1;
2769 else if (strcmp(tokens[1], "multicast") == 0)
2770 a->encap.mpls.unicast = 0;
2774 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
2775 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
2776 strcmp(tokens[4], "label0") ||
2777 softnic_parser_read_uint32(&label, tokens[5]) ||
2779 softnic_parser_read_uint32(&tc, tokens[6]) ||
2781 softnic_parser_read_uint32(&ttl, tokens[7]) ||
2785 a->encap.mpls.mpls[0].label = label;
2786 a->encap.mpls.mpls[0].tc = tc;
2787 a->encap.mpls.mpls[0].ttl = ttl;
2792 if (n_tokens == 0 ||
2793 strcmp(tokens[0], "label1")) {
2794 a->encap.mpls.mpls_count = 1;
2795 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2796 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2801 softnic_parser_read_uint32(&label, tokens[1]) ||
2803 softnic_parser_read_uint32(&tc, tokens[2]) ||
2805 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2809 a->encap.mpls.mpls[1].label = label;
2810 a->encap.mpls.mpls[1].tc = tc;
2811 a->encap.mpls.mpls[1].ttl = ttl;
2816 if (n_tokens == 0 ||
2817 strcmp(tokens[0], "label2")) {
2818 a->encap.mpls.mpls_count = 2;
2819 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2820 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2825 softnic_parser_read_uint32(&label, tokens[1]) ||
2827 softnic_parser_read_uint32(&tc, tokens[2]) ||
2829 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2833 a->encap.mpls.mpls[2].label = label;
2834 a->encap.mpls.mpls[2].tc = tc;
2835 a->encap.mpls.mpls[2].ttl = ttl;
2840 if (n_tokens == 0 ||
2841 strcmp(tokens[0], "label3")) {
2842 a->encap.mpls.mpls_count = 3;
2843 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2844 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2845 return 1 + 8 + 4 + 4;
2849 softnic_parser_read_uint32(&label, tokens[1]) ||
2851 softnic_parser_read_uint32(&tc, tokens[2]) ||
2853 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2857 a->encap.mpls.mpls[3].label = label;
2858 a->encap.mpls.mpls[3].tc = tc;
2859 a->encap.mpls.mpls[3].ttl = ttl;
2861 a->encap.mpls.mpls_count = 4;
2862 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2863 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2864 return 1 + 8 + 4 + 4 + 4;
2868 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
2870 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
2871 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
2872 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
2876 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
2877 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2885 parse_table_action_nat(char **tokens,
2887 struct softnic_table_rule_action *a)
2890 strcmp(tokens[0], "nat"))
2893 if (strcmp(tokens[1], "ipv4") == 0) {
2894 struct in_addr addr;
2897 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
2898 softnic_parser_read_uint16(&port, tokens[3]))
2901 a->nat.ip_version = 1;
2902 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2904 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2908 if (strcmp(tokens[1], "ipv6") == 0) {
2909 struct in6_addr addr;
2912 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
2913 softnic_parser_read_uint16(&port, tokens[3]))
2916 a->nat.ip_version = 0;
2917 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
2919 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2927 parse_table_action_ttl(char **tokens,
2929 struct softnic_table_rule_action *a)
2932 strcmp(tokens[0], "ttl"))
2935 if (strcmp(tokens[1], "dec") == 0)
2936 a->ttl.decrement = 1;
2937 else if (strcmp(tokens[1], "keep") == 0)
2938 a->ttl.decrement = 0;
2942 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
2947 parse_table_action_stats(char **tokens,
2949 struct softnic_table_rule_action *a)
2952 strcmp(tokens[0], "stats"))
2955 a->stats.n_packets = 0;
2956 a->stats.n_bytes = 0;
2957 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
2962 parse_table_action_time(char **tokens,
2964 struct softnic_table_rule_action *a)
2967 strcmp(tokens[0], "time"))
2970 a->time.time = rte_rdtsc();
2971 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
2976 parse_table_action(char **tokens,
2980 struct softnic_table_rule_action *a)
2982 uint32_t n_tokens0 = n_tokens;
2984 memset(a, 0, sizeof(*a));
2987 strcmp(tokens[0], "action"))
2993 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
2996 n = parse_table_action_fwd(tokens, n_tokens, a);
2998 snprintf(out, out_size, MSG_ARG_INVALID,
3007 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3010 n = parse_table_action_balance(tokens, n_tokens, a);
3012 snprintf(out, out_size, MSG_ARG_INVALID,
3021 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3024 n = parse_table_action_meter(tokens, n_tokens, a);
3026 snprintf(out, out_size, MSG_ARG_INVALID,
3035 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3038 n = parse_table_action_tm(tokens, n_tokens, a);
3040 snprintf(out, out_size, MSG_ARG_INVALID,
3049 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3052 n = parse_table_action_encap(tokens, n_tokens, a);
3054 snprintf(out, out_size, MSG_ARG_INVALID,
3063 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3066 n = parse_table_action_nat(tokens, n_tokens, a);
3068 snprintf(out, out_size, MSG_ARG_INVALID,
3077 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3080 n = parse_table_action_ttl(tokens, n_tokens, a);
3082 snprintf(out, out_size, MSG_ARG_INVALID,
3091 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3094 n = parse_table_action_stats(tokens, n_tokens, a);
3096 snprintf(out, out_size, MSG_ARG_INVALID,
3105 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3108 n = parse_table_action_time(tokens, n_tokens, a);
3110 snprintf(out, out_size, MSG_ARG_INVALID,
3119 if (n_tokens0 - n_tokens == 1) {
3120 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3124 return n_tokens0 - n_tokens;
3128 * pipeline <pipeline_name> table <table_id> rule add
3130 * action <table_action>
3133 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3139 struct softnic_table_rule_match m;
3140 struct softnic_table_rule_action a;
3141 char *pipeline_name;
3143 uint32_t table_id, t0, n_tokens_parsed;
3147 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3151 pipeline_name = tokens[1];
3153 if (strcmp(tokens[2], "table") != 0) {
3154 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3158 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3159 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3163 if (strcmp(tokens[4], "rule") != 0) {
3164 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3168 if (strcmp(tokens[5], "add") != 0) {
3169 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3176 n_tokens_parsed = parse_match(tokens + t0,
3181 if (n_tokens_parsed == 0)
3183 t0 += n_tokens_parsed;
3186 n_tokens_parsed = parse_table_action(tokens + t0,
3191 if (n_tokens_parsed == 0)
3193 t0 += n_tokens_parsed;
3195 if (t0 != n_tokens) {
3196 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3200 status = softnic_pipeline_table_rule_add(softnic,
3207 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3213 * pipeline <pipeline_name> table <table_id> rule add
3221 * | table <table_id>
3224 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3230 struct softnic_table_rule_action action;
3232 char *pipeline_name;
3236 if (n_tokens != 11 &&
3238 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3242 pipeline_name = tokens[1];
3244 if (strcmp(tokens[2], "table") != 0) {
3245 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3249 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3250 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3254 if (strcmp(tokens[4], "rule") != 0) {
3255 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3259 if (strcmp(tokens[5], "add") != 0) {
3260 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3264 if (strcmp(tokens[6], "match") != 0) {
3265 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3269 if (strcmp(tokens[7], "default") != 0) {
3270 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3274 if (strcmp(tokens[8], "action") != 0) {
3275 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3279 if (strcmp(tokens[9], "fwd") != 0) {
3280 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3284 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3286 if (strcmp(tokens[10], "drop") == 0) {
3287 if (n_tokens != 11) {
3288 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3292 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3293 } else if (strcmp(tokens[10], "port") == 0) {
3296 if (n_tokens != 12) {
3297 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3301 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3302 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3306 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3308 } else if (strcmp(tokens[10], "meta") == 0) {
3309 if (n_tokens != 11) {
3310 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3314 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3315 } else if (strcmp(tokens[10], "table") == 0) {
3318 if (n_tokens != 12) {
3319 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3323 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3324 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3328 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3331 snprintf(out, out_size, MSG_ARG_INVALID,
3332 "drop or port or meta or table");
3336 status = softnic_pipeline_table_rule_add_default(softnic,
3342 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3348 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
3351 * - line format: match <match> action <action>
3354 cli_rule_file_process(const char *file_name,
3355 size_t line_len_max,
3356 struct softnic_table_rule_match *m,
3357 struct softnic_table_rule_action *a,
3359 uint32_t *line_number,
3364 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
3370 struct softnic_table_rule_match *match;
3371 struct softnic_table_rule_action *action;
3373 char *pipeline_name, *file_name;
3374 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3377 if (n_tokens != 9) {
3378 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3382 pipeline_name = tokens[1];
3384 if (strcmp(tokens[2], "table") != 0) {
3385 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3389 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3390 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3394 if (strcmp(tokens[4], "rule") != 0) {
3395 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3399 if (strcmp(tokens[5], "add") != 0) {
3400 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3404 if (strcmp(tokens[6], "bulk") != 0) {
3405 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3409 file_name = tokens[7];
3411 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3413 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3417 /* Memory allocation. */
3418 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
3419 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
3420 data = calloc(n_rules, sizeof(void *));
3421 if (match == NULL ||
3424 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3431 /* Load rule file */
3432 n_rules_parsed = n_rules;
3433 status = cli_rule_file_process(file_name,
3442 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3448 if (n_rules_parsed != n_rules) {
3449 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3457 status = softnic_pipeline_table_rule_add_bulk(softnic,
3465 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3479 * pipeline <pipeline_name> table <table_id> rule delete
3483 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
3489 struct softnic_table_rule_match m;
3490 char *pipeline_name;
3491 uint32_t table_id, n_tokens_parsed, t0;
3495 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3499 pipeline_name = tokens[1];
3501 if (strcmp(tokens[2], "table") != 0) {
3502 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3506 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3507 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3511 if (strcmp(tokens[4], "rule") != 0) {
3512 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3516 if (strcmp(tokens[5], "delete") != 0) {
3517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3524 n_tokens_parsed = parse_match(tokens + t0,
3529 if (n_tokens_parsed == 0)
3531 t0 += n_tokens_parsed;
3533 if (n_tokens != t0) {
3534 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3538 status = softnic_pipeline_table_rule_delete(softnic,
3543 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3549 * pipeline <pipeline_name> table <table_id> rule delete
3554 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
3560 char *pipeline_name;
3564 if (n_tokens != 8) {
3565 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3569 pipeline_name = tokens[1];
3571 if (strcmp(tokens[2], "table") != 0) {
3572 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3576 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3577 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3581 if (strcmp(tokens[4], "rule") != 0) {
3582 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3586 if (strcmp(tokens[5], "delete") != 0) {
3587 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3591 if (strcmp(tokens[6], "match") != 0) {
3592 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3596 if (strcmp(tokens[7], "default") != 0) {
3597 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3601 status = softnic_pipeline_table_rule_delete_default(softnic,
3605 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3611 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
3614 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
3616 uint32_t n_tokens __rte_unused,
3620 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3624 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
3625 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
3626 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
3629 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
3635 struct rte_table_action_meter_profile p;
3636 char *pipeline_name;
3637 uint32_t table_id, meter_profile_id;
3641 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3645 pipeline_name = tokens[1];
3647 if (strcmp(tokens[2], "table") != 0) {
3648 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3652 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3653 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3657 if (strcmp(tokens[4], "meter") != 0) {
3658 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3662 if (strcmp(tokens[5], "profile") != 0) {
3663 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3667 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3668 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3672 if (strcmp(tokens[7], "add") != 0) {
3673 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3677 if (strcmp(tokens[8], "srtcm") == 0) {
3678 if (n_tokens != 15) {
3679 snprintf(out, out_size, MSG_ARG_MISMATCH,
3684 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
3686 if (strcmp(tokens[9], "cir") != 0) {
3687 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3691 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
3692 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3696 if (strcmp(tokens[11], "cbs") != 0) {
3697 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3701 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
3702 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3706 if (strcmp(tokens[13], "ebs") != 0) {
3707 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
3711 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
3712 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
3715 } else if (strcmp(tokens[8], "trtcm") == 0) {
3716 if (n_tokens != 17) {
3717 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3721 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
3723 if (strcmp(tokens[9], "cir") != 0) {
3724 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3728 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
3729 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3733 if (strcmp(tokens[11], "pir") != 0) {
3734 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
3738 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
3739 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
3742 if (strcmp(tokens[13], "cbs") != 0) {
3743 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3747 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
3748 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3752 if (strcmp(tokens[15], "pbs") != 0) {
3753 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
3757 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
3758 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
3762 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3766 status = softnic_pipeline_table_mtr_profile_add(softnic,
3772 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3778 * pipeline <pipeline_name> table <table_id>
3779 * meter profile <meter_profile_id> delete
3782 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
3788 char *pipeline_name;
3789 uint32_t table_id, meter_profile_id;
3792 if (n_tokens != 8) {
3793 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3797 pipeline_name = tokens[1];
3799 if (strcmp(tokens[2], "table") != 0) {
3800 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3804 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3805 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3809 if (strcmp(tokens[4], "meter") != 0) {
3810 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3814 if (strcmp(tokens[5], "profile") != 0) {
3815 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3819 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3820 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3824 if (strcmp(tokens[7], "delete") != 0) {
3825 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3829 status = softnic_pipeline_table_mtr_profile_delete(softnic,
3834 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3840 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
3843 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
3845 uint32_t n_tokens __rte_unused,
3849 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3853 * pipeline <pipeline_name> table <table_id> dscp <file_name>
3856 * - exactly 64 lines
3857 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
3860 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
3861 const char *file_name,
3862 uint32_t *line_number)
3867 /* Check input arguments */
3868 if (dscp_table == NULL ||
3869 file_name == NULL ||
3870 line_number == NULL) {
3876 /* Open input file */
3877 f = fopen(file_name, "r");
3884 for (dscp = 0, l = 1; ; l++) {
3887 enum rte_meter_color color;
3888 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
3890 if (fgets(line, sizeof(line), f) == NULL)
3893 if (is_comment(line))
3896 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
3905 if (dscp >= RTE_DIM(dscp_table->entry) ||
3906 n_tokens != RTE_DIM(tokens) ||
3907 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
3908 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
3909 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
3910 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
3911 (strlen(tokens[2]) != 1)) {
3917 switch (tokens[2][0]) {
3920 color = e_RTE_METER_GREEN;
3925 color = e_RTE_METER_YELLOW;
3930 color = e_RTE_METER_RED;
3939 dscp_table->entry[dscp].tc_id = tc_id;
3940 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
3941 dscp_table->entry[dscp].color = color;
3951 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
3957 struct rte_table_action_dscp_table dscp_table;
3958 char *pipeline_name, *file_name;
3959 uint32_t table_id, line_number;
3962 if (n_tokens != 6) {
3963 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3967 pipeline_name = tokens[1];
3969 if (strcmp(tokens[2], "table") != 0) {
3970 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3974 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3975 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3979 if (strcmp(tokens[4], "dscp") != 0) {
3980 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
3984 file_name = tokens[5];
3986 status = load_dscp_table(&dscp_table, file_name, &line_number);
3988 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3992 status = softnic_pipeline_table_dscp_table_update(softnic,
3998 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4004 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4007 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4009 uint32_t n_tokens __rte_unused,
4013 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4017 * thread <thread_id> pipeline <pipeline_name> enable
4020 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4026 char *pipeline_name;
4030 if (n_tokens != 5) {
4031 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4035 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4036 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4040 if (strcmp(tokens[2], "pipeline") != 0) {
4041 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4045 pipeline_name = tokens[3];
4047 if (strcmp(tokens[4], "enable") != 0) {
4048 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4052 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4054 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4060 * thread <thread_id> pipeline <pipeline_name> disable
4063 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4069 char *pipeline_name;
4073 if (n_tokens != 5) {
4074 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4078 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4079 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4083 if (strcmp(tokens[2], "pipeline") != 0) {
4084 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4088 pipeline_name = tokens[3];
4090 if (strcmp(tokens[4], "disable") != 0) {
4091 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4095 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4097 snprintf(out, out_size, MSG_CMD_FAIL,
4098 "thread pipeline disable");
4104 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4106 char *tokens[CMD_MAX_TOKENS];
4107 uint32_t n_tokens = RTE_DIM(tokens);
4108 struct pmd_internals *softnic = arg;
4114 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4116 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4123 if (strcmp(tokens[0], "mempool") == 0) {
4124 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4128 if (strcmp(tokens[0], "link") == 0) {
4129 cmd_link(softnic, tokens, n_tokens, out, out_size);
4133 if (strcmp(tokens[0], "swq") == 0) {
4134 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4138 if (strcmp(tokens[0], "tmgr") == 0) {
4139 if (n_tokens == 2) {
4140 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4144 if (n_tokens >= 3 &&
4145 (strcmp(tokens[1], "shaper") == 0) &&
4146 (strcmp(tokens[2], "profile") == 0)) {
4147 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4151 if (n_tokens >= 3 &&
4152 (strcmp(tokens[1], "shared") == 0) &&
4153 (strcmp(tokens[2], "shaper") == 0)) {
4154 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
4159 if (strcmp(tokens[0], "tap") == 0) {
4160 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4164 if (strcmp(tokens[0], "port") == 0) {
4165 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4169 if (strcmp(tokens[0], "table") == 0) {
4170 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4174 if (strcmp(tokens[0], "pipeline") == 0) {
4175 if (n_tokens >= 3 &&
4176 (strcmp(tokens[2], "period") == 0)) {
4177 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4181 if (n_tokens >= 5 &&
4182 (strcmp(tokens[2], "port") == 0) &&
4183 (strcmp(tokens[3], "in") == 0) &&
4184 (strcmp(tokens[4], "bsz") == 0)) {
4185 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4189 if (n_tokens >= 5 &&
4190 (strcmp(tokens[2], "port") == 0) &&
4191 (strcmp(tokens[3], "out") == 0) &&
4192 (strcmp(tokens[4], "bsz") == 0)) {
4193 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4197 if (n_tokens >= 4 &&
4198 (strcmp(tokens[2], "table") == 0) &&
4199 (strcmp(tokens[3], "match") == 0)) {
4200 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4204 if (n_tokens >= 6 &&
4205 (strcmp(tokens[2], "port") == 0) &&
4206 (strcmp(tokens[3], "in") == 0) &&
4207 (strcmp(tokens[5], "table") == 0)) {
4208 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4213 if (n_tokens >= 6 &&
4214 (strcmp(tokens[2], "port") == 0) &&
4215 (strcmp(tokens[3], "in") == 0) &&
4216 (strcmp(tokens[5], "stats") == 0)) {
4217 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4222 if (n_tokens >= 6 &&
4223 (strcmp(tokens[2], "port") == 0) &&
4224 (strcmp(tokens[3], "in") == 0) &&
4225 (strcmp(tokens[5], "enable") == 0)) {
4226 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4231 if (n_tokens >= 6 &&
4232 (strcmp(tokens[2], "port") == 0) &&
4233 (strcmp(tokens[3], "in") == 0) &&
4234 (strcmp(tokens[5], "disable") == 0)) {
4235 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4240 if (n_tokens >= 6 &&
4241 (strcmp(tokens[2], "port") == 0) &&
4242 (strcmp(tokens[3], "out") == 0) &&
4243 (strcmp(tokens[5], "stats") == 0)) {
4244 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4249 if (n_tokens >= 5 &&
4250 (strcmp(tokens[2], "table") == 0) &&
4251 (strcmp(tokens[4], "stats") == 0)) {
4252 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4257 if (n_tokens >= 7 &&
4258 (strcmp(tokens[2], "table") == 0) &&
4259 (strcmp(tokens[4], "rule") == 0) &&
4260 (strcmp(tokens[5], "add") == 0) &&
4261 (strcmp(tokens[6], "match") == 0)) {
4262 if (n_tokens >= 8 &&
4263 (strcmp(tokens[7], "default") == 0)) {
4264 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4265 n_tokens, out, out_size);
4269 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4274 if (n_tokens >= 7 &&
4275 (strcmp(tokens[2], "table") == 0) &&
4276 (strcmp(tokens[4], "rule") == 0) &&
4277 (strcmp(tokens[5], "add") == 0) &&
4278 (strcmp(tokens[6], "bulk") == 0)) {
4279 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4280 n_tokens, out, out_size);
4284 if (n_tokens >= 7 &&
4285 (strcmp(tokens[2], "table") == 0) &&
4286 (strcmp(tokens[4], "rule") == 0) &&
4287 (strcmp(tokens[5], "delete") == 0) &&
4288 (strcmp(tokens[6], "match") == 0)) {
4289 if (n_tokens >= 8 &&
4290 (strcmp(tokens[7], "default") == 0)) {
4291 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
4292 n_tokens, out, out_size);
4296 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
4301 if (n_tokens >= 7 &&
4302 (strcmp(tokens[2], "table") == 0) &&
4303 (strcmp(tokens[4], "rule") == 0) &&
4304 (strcmp(tokens[5], "read") == 0) &&
4305 (strcmp(tokens[6], "stats") == 0)) {
4306 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
4311 if (n_tokens >= 8 &&
4312 (strcmp(tokens[2], "table") == 0) &&
4313 (strcmp(tokens[4], "meter") == 0) &&
4314 (strcmp(tokens[5], "profile") == 0) &&
4315 (strcmp(tokens[7], "add") == 0)) {
4316 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
4321 if (n_tokens >= 8 &&
4322 (strcmp(tokens[2], "table") == 0) &&
4323 (strcmp(tokens[4], "meter") == 0) &&
4324 (strcmp(tokens[5], "profile") == 0) &&
4325 (strcmp(tokens[7], "delete") == 0)) {
4326 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
4327 n_tokens, out, out_size);
4331 if (n_tokens >= 7 &&
4332 (strcmp(tokens[2], "table") == 0) &&
4333 (strcmp(tokens[4], "rule") == 0) &&
4334 (strcmp(tokens[5], "read") == 0) &&
4335 (strcmp(tokens[6], "meter") == 0)) {
4336 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
4341 if (n_tokens >= 5 &&
4342 (strcmp(tokens[2], "table") == 0) &&
4343 (strcmp(tokens[4], "dscp") == 0)) {
4344 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
4349 if (n_tokens >= 7 &&
4350 (strcmp(tokens[2], "table") == 0) &&
4351 (strcmp(tokens[4], "rule") == 0) &&
4352 (strcmp(tokens[5], "read") == 0) &&
4353 (strcmp(tokens[6], "ttl") == 0)) {
4354 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
4360 if (strcmp(tokens[0], "thread") == 0) {
4361 if (n_tokens >= 5 &&
4362 (strcmp(tokens[4], "enable") == 0)) {
4363 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
4368 if (n_tokens >= 5 &&
4369 (strcmp(tokens[4], "disable") == 0)) {
4370 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
4376 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
4380 softnic_cli_script_process(struct pmd_internals *softnic,
4381 const char *file_name,
4382 size_t msg_in_len_max,
4383 size_t msg_out_len_max)
4385 char *msg_in = NULL, *msg_out = NULL;
4388 /* Check input arguments */
4389 if (file_name == NULL ||
4390 (strlen(file_name) == 0) ||
4391 msg_in_len_max == 0 ||
4392 msg_out_len_max == 0)
4395 msg_in = malloc(msg_in_len_max + 1);
4396 msg_out = malloc(msg_out_len_max + 1);
4397 if (msg_in == NULL ||
4404 /* Open input file */
4405 f = fopen(file_name, "r");
4414 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
4417 printf("%s", msg_in);
4420 softnic_cli_process(msg_in,
4425 if (strlen(msg_out))
4426 printf("%s", msg_out);
4437 cli_rule_file_process(const char *file_name,
4438 size_t line_len_max,
4439 struct softnic_table_rule_match *m,
4440 struct softnic_table_rule_action *a,
4442 uint32_t *line_number,
4448 uint32_t rule_id, line_id;
4451 /* Check input arguments */
4452 if (file_name == NULL ||
4453 (strlen(file_name) == 0) ||
4454 line_len_max == 0) {
4459 /* Memory allocation */
4460 line = malloc(line_len_max + 1);
4467 f = fopen(file_name, "r");
4475 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
4476 char *tokens[CMD_MAX_TOKENS];
4477 uint32_t n_tokens, n_tokens_parsed, t0;
4479 /* Read next line from file. */
4480 if (fgets(line, line_len_max + 1, f) == NULL)
4484 if (is_comment(line))
4488 n_tokens = RTE_DIM(tokens);
4489 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
4501 n_tokens_parsed = parse_match(tokens + t0,
4506 if (n_tokens_parsed == 0) {
4510 t0 += n_tokens_parsed;
4513 n_tokens_parsed = parse_table_action(tokens + t0,
4518 if (n_tokens_parsed == 0) {
4522 t0 += n_tokens_parsed;
4524 /* Line completed. */
4525 if (t0 < n_tokens) {
4530 /* Increment rule count */
4541 *line_number = line_id;