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]);
278 cmd_tmgr(struct pmd_internals *softnic,
285 struct softnic_tmgr_port *tmgr_port;
288 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
294 tmgr_port = softnic_tmgr_port_create(softnic, name);
295 if (tmgr_port == NULL) {
296 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
305 cmd_tap(struct pmd_internals *softnic,
312 struct softnic_tap *tap;
315 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
321 tap = softnic_tap_create(softnic, name);
323 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
329 * port in action profile <profile_name>
330 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
331 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
334 cmd_port_in_action_profile(struct pmd_internals *softnic,
340 struct softnic_port_in_action_profile_params p;
341 struct softnic_port_in_action_profile *ap;
345 memset(&p, 0, sizeof(p));
348 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
352 if (strcmp(tokens[1], "in") != 0) {
353 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
357 if (strcmp(tokens[2], "action") != 0) {
358 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
362 if (strcmp(tokens[3], "profile") != 0) {
363 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
372 (strcmp(tokens[t0], "filter") == 0)) {
375 if (n_tokens < t0 + 10) {
376 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
380 if (strcmp(tokens[t0 + 1], "match") == 0) {
381 p.fltr.filter_on_match = 1;
382 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
383 p.fltr.filter_on_match = 0;
385 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
389 if (strcmp(tokens[t0 + 2], "offset") != 0) {
390 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
394 if (softnic_parser_read_uint32(&p.fltr.key_offset,
395 tokens[t0 + 3]) != 0) {
396 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
400 if (strcmp(tokens[t0 + 4], "mask") != 0) {
401 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
405 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
406 if ((softnic_parse_hex_string(tokens[t0 + 5],
407 p.fltr.key_mask, &size) != 0) ||
408 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
409 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
413 if (strcmp(tokens[t0 + 6], "key") != 0) {
414 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
418 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
419 if ((softnic_parse_hex_string(tokens[t0 + 7],
420 p.fltr.key, &size) != 0) ||
421 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
422 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
426 if (strcmp(tokens[t0 + 8], "port") != 0) {
427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
431 if (softnic_parser_read_uint32(&p.fltr.port_id,
432 tokens[t0 + 9]) != 0) {
433 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
437 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
442 (strcmp(tokens[t0], "balance") == 0)) {
445 if (n_tokens < t0 + 22) {
446 snprintf(out, out_size, MSG_ARG_MISMATCH,
447 "port in action profile balance");
451 if (strcmp(tokens[t0 + 1], "offset") != 0) {
452 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
456 if (softnic_parser_read_uint32(&p.lb.key_offset,
457 tokens[t0 + 2]) != 0) {
458 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
462 if (strcmp(tokens[t0 + 3], "mask") != 0) {
463 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
467 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
468 if (softnic_parse_hex_string(tokens[t0 + 4],
469 p.lb.key_mask, &p.lb.key_size) != 0) {
470 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
474 if (strcmp(tokens[t0 + 5], "port") != 0) {
475 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
479 for (i = 0; i < 16; i++)
480 if (softnic_parser_read_uint32(&p.lb.port_id[i],
481 tokens[t0 + 6 + i]) != 0) {
482 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
486 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
491 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
495 ap = softnic_port_in_action_profile_create(softnic, name, &p);
497 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
503 * table action profile <profile_name>
507 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
508 * [meter srtcm | trtcm
510 * stats none | pkts | bytes | both]
511 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
512 * [encap ether | vlan | qinq | mpls | pppoe]
517 * [stats pkts | bytes | both]
521 cmd_table_action_profile(struct pmd_internals *softnic,
527 struct softnic_table_action_profile_params p;
528 struct softnic_table_action_profile *ap;
532 memset(&p, 0, sizeof(p));
535 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
539 if (strcmp(tokens[1], "action") != 0) {
540 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
544 if (strcmp(tokens[2], "profile") != 0) {
545 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
551 if (strcmp(tokens[4], "ipv4") == 0) {
552 p.common.ip_version = 1;
553 } else if (strcmp(tokens[4], "ipv6") == 0) {
554 p.common.ip_version = 0;
556 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
560 if (strcmp(tokens[5], "offset") != 0) {
561 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
565 if (softnic_parser_read_uint32(&p.common.ip_offset,
567 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
571 if (strcmp(tokens[7], "fwd") != 0) {
572 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
576 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
580 (strcmp(tokens[t0], "balance") == 0)) {
581 if (n_tokens < t0 + 7) {
582 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
586 if (strcmp(tokens[t0 + 1], "offset") != 0) {
587 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
591 if (softnic_parser_read_uint32(&p.lb.key_offset,
592 tokens[t0 + 2]) != 0) {
593 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
597 if (strcmp(tokens[t0 + 3], "mask") != 0) {
598 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
602 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
603 if (softnic_parse_hex_string(tokens[t0 + 4],
604 p.lb.key_mask, &p.lb.key_size) != 0) {
605 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
609 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
610 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
614 if (softnic_parser_read_uint32(&p.lb.out_offset,
615 tokens[t0 + 6]) != 0) {
616 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
620 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
625 (strcmp(tokens[t0], "meter") == 0)) {
626 if (n_tokens < t0 + 6) {
627 snprintf(out, out_size, MSG_ARG_MISMATCH,
628 "table action profile meter");
632 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
633 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
634 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
635 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
637 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
642 if (strcmp(tokens[t0 + 2], "tc") != 0) {
643 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
647 if (softnic_parser_read_uint32(&p.mtr.n_tc,
648 tokens[t0 + 3]) != 0) {
649 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
653 if (strcmp(tokens[t0 + 4], "stats") != 0) {
654 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
658 if (strcmp(tokens[t0 + 5], "none") == 0) {
659 p.mtr.n_packets_enabled = 0;
660 p.mtr.n_bytes_enabled = 0;
661 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
662 p.mtr.n_packets_enabled = 1;
663 p.mtr.n_bytes_enabled = 0;
664 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
665 p.mtr.n_packets_enabled = 0;
666 p.mtr.n_bytes_enabled = 1;
667 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
668 p.mtr.n_packets_enabled = 1;
669 p.mtr.n_bytes_enabled = 1;
671 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
672 "none or pkts or bytes or both");
676 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
681 (strcmp(tokens[t0], "tm") == 0)) {
682 if (n_tokens < t0 + 5) {
683 snprintf(out, out_size, MSG_ARG_MISMATCH,
684 "table action profile tm");
688 if (strcmp(tokens[t0 + 1], "spp") != 0) {
689 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
693 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
694 tokens[t0 + 2]) != 0) {
695 snprintf(out, out_size, MSG_ARG_INVALID,
696 "n_subports_per_port");
700 if (strcmp(tokens[t0 + 3], "pps") != 0) {
701 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
705 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
706 tokens[t0 + 4]) != 0) {
707 snprintf(out, out_size, MSG_ARG_INVALID,
708 "n_pipes_per_subport");
712 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
717 (strcmp(tokens[t0], "encap") == 0)) {
718 if (n_tokens < t0 + 2) {
719 snprintf(out, out_size, MSG_ARG_MISMATCH,
720 "action profile encap");
724 if (strcmp(tokens[t0 + 1], "ether") == 0) {
725 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
726 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
727 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
728 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
729 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
730 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
731 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
732 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
733 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
735 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
739 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
744 (strcmp(tokens[t0], "nat") == 0)) {
745 if (n_tokens < t0 + 4) {
746 snprintf(out, out_size, MSG_ARG_MISMATCH,
747 "table action profile nat");
751 if (strcmp(tokens[t0 + 1], "src") == 0) {
752 p.nat.source_nat = 1;
753 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
754 p.nat.source_nat = 0;
756 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
761 if (strcmp(tokens[t0 + 2], "proto") != 0) {
762 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
766 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
768 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
771 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
776 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
781 (strcmp(tokens[t0], "ttl") == 0)) {
782 if (n_tokens < t0 + 4) {
783 snprintf(out, out_size, MSG_ARG_MISMATCH,
784 "table action profile ttl");
788 if (strcmp(tokens[t0 + 1], "drop") == 0) {
790 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
793 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
798 if (strcmp(tokens[t0 + 2], "stats") != 0) {
799 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
803 if (strcmp(tokens[t0 + 3], "none") == 0) {
804 p.ttl.n_packets_enabled = 0;
805 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
806 p.ttl.n_packets_enabled = 1;
808 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
813 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
818 (strcmp(tokens[t0], "stats") == 0)) {
819 if (n_tokens < t0 + 2) {
820 snprintf(out, out_size, MSG_ARG_MISMATCH,
821 "table action profile stats");
825 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
826 p.stats.n_packets_enabled = 1;
827 p.stats.n_bytes_enabled = 0;
828 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
829 p.stats.n_packets_enabled = 0;
830 p.stats.n_bytes_enabled = 1;
831 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
832 p.stats.n_packets_enabled = 1;
833 p.stats.n_bytes_enabled = 1;
835 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
836 "pkts or bytes or both");
840 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
845 (strcmp(tokens[t0], "time") == 0)) {
846 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
851 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
855 ap = softnic_table_action_profile_create(softnic, name, &p);
857 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
863 * pipeline <pipeline_name>
864 * period <timer_period_ms>
865 * offset_port_id <offset_port_id>
868 cmd_pipeline(struct pmd_internals *softnic,
874 struct pipeline_params p;
876 struct pipeline *pipeline;
879 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
885 if (strcmp(tokens[2], "period") != 0) {
886 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
890 if (softnic_parser_read_uint32(&p.timer_period_ms,
892 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
896 if (strcmp(tokens[4], "offset_port_id") != 0) {
897 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
901 if (softnic_parser_read_uint32(&p.offset_port_id,
903 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
907 pipeline = softnic_pipeline_create(softnic, name, &p);
908 if (pipeline == NULL) {
909 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
915 * pipeline <pipeline_name> port in
917 * link <link_name> rxq <queue_id>
920 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
921 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
922 * [action <port_in_action_profile_name>]
926 cmd_pipeline_port_in(struct pmd_internals *softnic,
932 struct softnic_port_in_params p;
938 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
942 pipeline_name = tokens[1];
944 if (strcmp(tokens[2], "port") != 0) {
945 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
949 if (strcmp(tokens[3], "in") != 0) {
950 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
954 if (strcmp(tokens[4], "bsz") != 0) {
955 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
959 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
960 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
966 if (strcmp(tokens[t0], "link") == 0) {
967 if (n_tokens < t0 + 4) {
968 snprintf(out, out_size, MSG_ARG_MISMATCH,
969 "pipeline port in link");
973 p.type = PORT_IN_RXQ;
975 p.dev_name = tokens[t0 + 1];
977 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
978 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
982 if (softnic_parser_read_uint16(&p.rxq.queue_id,
983 tokens[t0 + 3]) != 0) {
984 snprintf(out, out_size, MSG_ARG_INVALID,
989 } else if (strcmp(tokens[t0], "swq") == 0) {
990 if (n_tokens < t0 + 2) {
991 snprintf(out, out_size, MSG_ARG_MISMATCH,
992 "pipeline port in swq");
996 p.type = PORT_IN_SWQ;
998 p.dev_name = tokens[t0 + 1];
1001 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1002 if (n_tokens < t0 + 2) {
1003 snprintf(out, out_size, MSG_ARG_MISMATCH,
1004 "pipeline port in tmgr");
1008 p.type = PORT_IN_TMGR;
1010 p.dev_name = tokens[t0 + 1];
1013 } else if (strcmp(tokens[t0], "tap") == 0) {
1014 if (n_tokens < t0 + 6) {
1015 snprintf(out, out_size, MSG_ARG_MISMATCH,
1016 "pipeline port in tap");
1020 p.type = PORT_IN_TAP;
1022 p.dev_name = tokens[t0 + 1];
1024 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1025 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1030 p.tap.mempool_name = tokens[t0 + 3];
1032 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1033 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1038 if (softnic_parser_read_uint32(&p.tap.mtu,
1039 tokens[t0 + 5]) != 0) {
1040 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1045 } else if (strcmp(tokens[t0], "source") == 0) {
1046 if (n_tokens < t0 + 6) {
1047 snprintf(out, out_size, MSG_ARG_MISMATCH,
1048 "pipeline port in source");
1052 p.type = PORT_IN_SOURCE;
1056 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1057 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1062 p.source.mempool_name = tokens[t0 + 2];
1064 if (strcmp(tokens[t0 + 3], "file") != 0) {
1065 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1070 p.source.file_name = tokens[t0 + 4];
1072 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1073 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1078 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1079 tokens[t0 + 6]) != 0) {
1080 snprintf(out, out_size, MSG_ARG_INVALID,
1087 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1091 p.action_profile_name = NULL;
1092 if (n_tokens > t0 &&
1093 (strcmp(tokens[t0], "action") == 0)) {
1094 if (n_tokens < t0 + 2) {
1095 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1099 p.action_profile_name = tokens[t0 + 1];
1105 if (n_tokens > t0 &&
1106 (strcmp(tokens[t0], "disabled") == 0)) {
1112 if (n_tokens != t0) {
1113 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1117 status = softnic_pipeline_port_in_create(softnic,
1122 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1128 * pipeline <pipeline_name> port out
1130 * link <link_name> txq <txq_id>
1132 * | tmgr <tmgr_name>
1134 * | sink [file <file_name> pkts <max_n_pkts>]
1137 cmd_pipeline_port_out(struct pmd_internals *softnic,
1143 struct softnic_port_out_params p;
1144 char *pipeline_name;
1147 memset(&p, 0, sizeof(p));
1150 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1154 pipeline_name = tokens[1];
1156 if (strcmp(tokens[2], "port") != 0) {
1157 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1161 if (strcmp(tokens[3], "out") != 0) {
1162 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1166 if (strcmp(tokens[4], "bsz") != 0) {
1167 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1171 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1172 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1176 if (strcmp(tokens[6], "link") == 0) {
1177 if (n_tokens != 10) {
1178 snprintf(out, out_size, MSG_ARG_MISMATCH,
1179 "pipeline port out link");
1183 p.type = PORT_OUT_TXQ;
1185 p.dev_name = tokens[7];
1187 if (strcmp(tokens[8], "txq") != 0) {
1188 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1192 if (softnic_parser_read_uint16(&p.txq.queue_id,
1194 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1197 } else if (strcmp(tokens[6], "swq") == 0) {
1198 if (n_tokens != 8) {
1199 snprintf(out, out_size, MSG_ARG_MISMATCH,
1200 "pipeline port out swq");
1204 p.type = PORT_OUT_SWQ;
1206 p.dev_name = tokens[7];
1207 } else if (strcmp(tokens[6], "tmgr") == 0) {
1208 if (n_tokens != 8) {
1209 snprintf(out, out_size, MSG_ARG_MISMATCH,
1210 "pipeline port out tmgr");
1214 p.type = PORT_OUT_TMGR;
1216 p.dev_name = tokens[7];
1217 } else if (strcmp(tokens[6], "tap") == 0) {
1218 if (n_tokens != 8) {
1219 snprintf(out, out_size, MSG_ARG_MISMATCH,
1220 "pipeline port out tap");
1224 p.type = PORT_OUT_TAP;
1226 p.dev_name = tokens[7];
1227 } else if (strcmp(tokens[6], "sink") == 0) {
1228 if ((n_tokens != 7) && (n_tokens != 11)) {
1229 snprintf(out, out_size, MSG_ARG_MISMATCH,
1230 "pipeline port out sink");
1234 p.type = PORT_OUT_SINK;
1238 if (n_tokens == 7) {
1239 p.sink.file_name = NULL;
1240 p.sink.max_n_pkts = 0;
1242 if (strcmp(tokens[7], "file") != 0) {
1243 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1248 p.sink.file_name = tokens[8];
1250 if (strcmp(tokens[9], "pkts") != 0) {
1251 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1255 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1257 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1262 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1266 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1268 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1274 * pipeline <pipeline_name> table
1278 * offset <ip_header_offset>
1281 * offset <key_offset>
1287 * offset <key_offset>
1288 * buckets <n_buckets>
1292 * offset <ip_header_offset>
1295 * [action <table_action_profile_name>]
1298 cmd_pipeline_table(struct pmd_internals *softnic,
1304 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1305 struct softnic_table_params p;
1306 char *pipeline_name;
1311 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1315 pipeline_name = tokens[1];
1317 if (strcmp(tokens[2], "table") != 0) {
1318 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1322 if (strcmp(tokens[3], "match") != 0) {
1323 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1328 if (strcmp(tokens[t0], "acl") == 0) {
1329 if (n_tokens < t0 + 6) {
1330 snprintf(out, out_size, MSG_ARG_MISMATCH,
1331 "pipeline table acl");
1335 p.match_type = TABLE_ACL;
1337 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1338 p.match.acl.ip_version = 1;
1339 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1340 p.match.acl.ip_version = 0;
1342 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1347 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1348 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1352 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1353 tokens[t0 + 3]) != 0) {
1354 snprintf(out, out_size, MSG_ARG_INVALID,
1355 "ip_header_offset");
1359 if (strcmp(tokens[t0 + 4], "size") != 0) {
1360 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1364 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1365 tokens[t0 + 5]) != 0) {
1366 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1371 } else if (strcmp(tokens[t0], "array") == 0) {
1372 if (n_tokens < t0 + 5) {
1373 snprintf(out, out_size, MSG_ARG_MISMATCH,
1374 "pipeline table array");
1378 p.match_type = TABLE_ARRAY;
1380 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1381 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1385 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1386 tokens[t0 + 2]) != 0) {
1387 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1391 if (strcmp(tokens[t0 + 3], "size") != 0) {
1392 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1396 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1397 tokens[t0 + 4]) != 0) {
1398 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1403 } else if (strcmp(tokens[t0], "hash") == 0) {
1404 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1406 if (n_tokens < t0 + 12) {
1407 snprintf(out, out_size, MSG_ARG_MISMATCH,
1408 "pipeline table hash");
1412 p.match_type = TABLE_HASH;
1414 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1415 p.match.hash.extendable_bucket = 1;
1416 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1417 p.match.hash.extendable_bucket = 0;
1419 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1424 if (strcmp(tokens[t0 + 2], "key") != 0) {
1425 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1429 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1430 tokens[t0 + 3]) != 0) ||
1431 p.match.hash.key_size == 0 ||
1432 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1433 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1437 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1438 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1442 if ((softnic_parse_hex_string(tokens[t0 + 5],
1443 key_mask, &key_mask_size) != 0) ||
1444 key_mask_size != p.match.hash.key_size) {
1445 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1448 p.match.hash.key_mask = key_mask;
1450 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1451 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1455 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1456 tokens[t0 + 7]) != 0) {
1457 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1461 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1462 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1466 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1467 tokens[t0 + 9]) != 0) {
1468 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1472 if (strcmp(tokens[t0 + 10], "size") != 0) {
1473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1477 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1478 tokens[t0 + 11]) != 0) {
1479 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1484 } else if (strcmp(tokens[t0], "lpm") == 0) {
1485 if (n_tokens < t0 + 6) {
1486 snprintf(out, out_size, MSG_ARG_MISMATCH,
1487 "pipeline table lpm");
1491 p.match_type = TABLE_LPM;
1493 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1494 p.match.lpm.key_size = 4;
1495 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1496 p.match.lpm.key_size = 16;
1498 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1503 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1504 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1508 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1509 tokens[t0 + 3]) != 0) {
1510 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1514 if (strcmp(tokens[t0 + 4], "size") != 0) {
1515 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1519 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1520 tokens[t0 + 5]) != 0) {
1521 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1526 } else if (strcmp(tokens[t0], "stub") == 0) {
1527 p.match_type = TABLE_STUB;
1531 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1535 p.action_profile_name = NULL;
1536 if (n_tokens > t0 &&
1537 (strcmp(tokens[t0], "action") == 0)) {
1538 if (n_tokens < t0 + 2) {
1539 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1543 p.action_profile_name = tokens[t0 + 1];
1548 if (n_tokens > t0) {
1549 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1553 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1555 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1561 * pipeline <pipeline_name> port in <port_id> table <table_id>
1564 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1570 char *pipeline_name;
1571 uint32_t port_id, table_id;
1574 if (n_tokens != 7) {
1575 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1579 pipeline_name = tokens[1];
1581 if (strcmp(tokens[2], "port") != 0) {
1582 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1586 if (strcmp(tokens[3], "in") != 0) {
1587 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1591 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1592 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1596 if (strcmp(tokens[5], "table") != 0) {
1597 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1601 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1602 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1606 status = softnic_pipeline_port_in_connect_to_table(softnic,
1611 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1617 * pipeline <pipeline_name> port in <port_id> stats read [clear]
1620 #define MSG_PIPELINE_PORT_IN_STATS \
1621 "Pkts in: %" PRIu64 "\n" \
1622 "Pkts dropped by AH: %" PRIu64 "\n" \
1623 "Pkts dropped by other: %" PRIu64 "\n"
1626 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
1632 struct rte_pipeline_port_in_stats stats;
1633 char *pipeline_name;
1637 if (n_tokens != 7 &&
1639 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1643 pipeline_name = tokens[1];
1645 if (strcmp(tokens[2], "port") != 0) {
1646 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1650 if (strcmp(tokens[3], "in") != 0) {
1651 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1655 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1656 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1660 if (strcmp(tokens[5], "stats") != 0) {
1661 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1665 if (strcmp(tokens[6], "read") != 0) {
1666 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1671 if (n_tokens == 8) {
1672 if (strcmp(tokens[7], "clear") != 0) {
1673 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1680 status = softnic_pipeline_port_in_stats_read(softnic,
1686 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1690 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
1691 stats.stats.n_pkts_in,
1692 stats.n_pkts_dropped_by_ah,
1693 stats.stats.n_pkts_drop);
1697 * pipeline <pipeline_name> port in <port_id> enable
1700 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1706 char *pipeline_name;
1710 if (n_tokens != 6) {
1711 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1715 pipeline_name = tokens[1];
1717 if (strcmp(tokens[2], "port") != 0) {
1718 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1722 if (strcmp(tokens[3], "in") != 0) {
1723 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1727 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1728 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1732 if (strcmp(tokens[5], "enable") != 0) {
1733 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1737 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1739 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1745 * pipeline <pipeline_name> port in <port_id> disable
1748 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1754 char *pipeline_name;
1758 if (n_tokens != 6) {
1759 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1763 pipeline_name = tokens[1];
1765 if (strcmp(tokens[2], "port") != 0) {
1766 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1770 if (strcmp(tokens[3], "in") != 0) {
1771 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1775 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1776 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1780 if (strcmp(tokens[5], "disable") != 0) {
1781 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1785 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1787 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1793 * pipeline <pipeline_name> port out <port_id> stats read [clear]
1795 #define MSG_PIPELINE_PORT_OUT_STATS \
1796 "Pkts in: %" PRIu64 "\n" \
1797 "Pkts dropped by AH: %" PRIu64 "\n" \
1798 "Pkts dropped by other: %" PRIu64 "\n"
1801 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
1807 struct rte_pipeline_port_out_stats stats;
1808 char *pipeline_name;
1812 if (n_tokens != 7 &&
1814 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1818 pipeline_name = tokens[1];
1820 if (strcmp(tokens[2], "port") != 0) {
1821 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1825 if (strcmp(tokens[3], "out") != 0) {
1826 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1830 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1831 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1835 if (strcmp(tokens[5], "stats") != 0) {
1836 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1840 if (strcmp(tokens[6], "read") != 0) {
1841 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1846 if (n_tokens == 8) {
1847 if (strcmp(tokens[7], "clear") != 0) {
1848 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1855 status = softnic_pipeline_port_out_stats_read(softnic,
1861 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1865 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
1866 stats.stats.n_pkts_in,
1867 stats.n_pkts_dropped_by_ah,
1868 stats.stats.n_pkts_drop);
1872 * pipeline <pipeline_name> table <table_id> stats read [clear]
1874 #define MSG_PIPELINE_TABLE_STATS \
1875 "Pkts in: %" PRIu64 "\n" \
1876 "Pkts in with lookup miss: %" PRIu64 "\n" \
1877 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
1878 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
1879 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
1880 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
1883 cmd_pipeline_table_stats(struct pmd_internals *softnic,
1889 struct rte_pipeline_table_stats stats;
1890 char *pipeline_name;
1894 if (n_tokens != 6 &&
1896 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1900 pipeline_name = tokens[1];
1902 if (strcmp(tokens[2], "table") != 0) {
1903 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1907 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
1908 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1912 if (strcmp(tokens[4], "stats") != 0) {
1913 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1917 if (strcmp(tokens[5], "read") != 0) {
1918 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1923 if (n_tokens == 7) {
1924 if (strcmp(tokens[6], "clear") != 0) {
1925 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1932 status = softnic_pipeline_table_stats_read(softnic,
1938 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1942 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
1943 stats.stats.n_pkts_in,
1944 stats.stats.n_pkts_lookup_miss,
1945 stats.n_pkts_dropped_by_lkp_hit_ah,
1946 stats.n_pkts_dropped_lkp_hit,
1947 stats.n_pkts_dropped_by_lkp_miss_ah,
1948 stats.n_pkts_dropped_lkp_miss);
1956 * priority <priority>
1957 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
1958 * <sp0> <sp1> <dp0> <dp1> <proto>
1962 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
1963 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
1964 * | ipv4_addr <addr>
1965 * | ipv6_addr <addr>
1966 * | qinq <svlan> <cvlan>
1968 * ipv4 | ipv6 <addr> <depth>
1970 struct pkt_key_qinq {
1971 uint16_t ethertype_svlan;
1973 uint16_t ethertype_cvlan;
1975 } __attribute__((__packed__));
1977 struct pkt_key_ipv4_5tuple {
1978 uint8_t time_to_live;
1980 uint16_t hdr_checksum;
1985 } __attribute__((__packed__));
1987 struct pkt_key_ipv6_5tuple {
1988 uint16_t payload_length;
1995 } __attribute__((__packed__));
1997 struct pkt_key_ipv4_addr {
1999 } __attribute__((__packed__));
2001 struct pkt_key_ipv6_addr {
2003 } __attribute__((__packed__));
2006 parse_match(char **tokens,
2010 struct softnic_table_rule_match *m)
2012 memset(m, 0, sizeof(*m));
2017 if (strcmp(tokens[0], "match") != 0) {
2018 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2022 if (strcmp(tokens[1], "acl") == 0) {
2023 if (n_tokens < 14) {
2024 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2028 m->match_type = TABLE_ACL;
2030 if (strcmp(tokens[2], "priority") != 0) {
2031 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2035 if (softnic_parser_read_uint32(&m->match.acl.priority,
2037 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2041 if (strcmp(tokens[4], "ipv4") == 0) {
2042 struct in_addr saddr, daddr;
2044 m->match.acl.ip_version = 1;
2046 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2047 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2050 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2052 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2053 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2056 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2057 } else if (strcmp(tokens[4], "ipv6") == 0) {
2058 struct in6_addr saddr, daddr;
2060 m->match.acl.ip_version = 0;
2062 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2063 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2066 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2068 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2069 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2072 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2074 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2079 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2081 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2085 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2087 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2091 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2092 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2096 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2097 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2101 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2102 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2106 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2107 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2111 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2112 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2116 m->match.acl.proto_mask = 0xff;
2121 if (strcmp(tokens[1], "array") == 0) {
2123 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2127 m->match_type = TABLE_ARRAY;
2129 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2130 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2137 if (strcmp(tokens[1], "hash") == 0) {
2139 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2143 m->match_type = TABLE_HASH;
2145 if (strcmp(tokens[2], "raw") == 0) {
2146 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2149 snprintf(out, out_size, MSG_ARG_MISMATCH,
2154 if (softnic_parse_hex_string(tokens[3],
2155 m->match.hash.key, &key_size) != 0) {
2156 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2163 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2164 struct pkt_key_ipv4_5tuple *ipv4 =
2165 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2166 struct in_addr saddr, daddr;
2171 snprintf(out, out_size, MSG_ARG_MISMATCH,
2176 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2177 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2181 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2182 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2186 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2187 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2191 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2192 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2196 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2197 snprintf(out, out_size, MSG_ARG_INVALID,
2202 ipv4->sa = saddr.s_addr;
2203 ipv4->da = daddr.s_addr;
2204 ipv4->sp = rte_cpu_to_be_16(sp);
2205 ipv4->dp = rte_cpu_to_be_16(dp);
2206 ipv4->proto = proto;
2209 } /* hash ipv4_5tuple */
2211 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2212 struct pkt_key_ipv6_5tuple *ipv6 =
2213 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2214 struct in6_addr saddr, daddr;
2219 snprintf(out, out_size, MSG_ARG_MISMATCH,
2224 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2225 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2229 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2230 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2234 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2235 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2239 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2240 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2244 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2245 snprintf(out, out_size, MSG_ARG_INVALID,
2250 memcpy(ipv6->sa, saddr.s6_addr, 16);
2251 memcpy(ipv6->da, daddr.s6_addr, 16);
2252 ipv6->sp = rte_cpu_to_be_16(sp);
2253 ipv6->dp = rte_cpu_to_be_16(dp);
2254 ipv6->proto = proto;
2257 } /* hash ipv6_5tuple */
2259 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2260 struct pkt_key_ipv4_addr *ipv4_addr =
2261 (struct pkt_key_ipv4_addr *)m->match.hash.key;
2262 struct in_addr addr;
2265 snprintf(out, out_size, MSG_ARG_MISMATCH,
2270 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2271 snprintf(out, out_size, MSG_ARG_INVALID,
2276 ipv4_addr->addr = addr.s_addr;
2279 } /* hash ipv4_addr */
2281 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2282 struct pkt_key_ipv6_addr *ipv6_addr =
2283 (struct pkt_key_ipv6_addr *)m->match.hash.key;
2284 struct in6_addr addr;
2287 snprintf(out, out_size, MSG_ARG_MISMATCH,
2292 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2293 snprintf(out, out_size, MSG_ARG_INVALID,
2298 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2301 } /* hash ipv6_5tuple */
2303 if (strcmp(tokens[2], "qinq") == 0) {
2304 struct pkt_key_qinq *qinq =
2305 (struct pkt_key_qinq *)m->match.hash.key;
2306 uint16_t svlan, cvlan;
2309 snprintf(out, out_size, MSG_ARG_MISMATCH,
2314 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
2316 snprintf(out, out_size, MSG_ARG_INVALID,
2321 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2323 snprintf(out, out_size, MSG_ARG_INVALID,
2328 qinq->svlan = rte_cpu_to_be_16(svlan);
2329 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2334 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2338 if (strcmp(tokens[1], "lpm") == 0) {
2340 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2344 m->match_type = TABLE_LPM;
2346 if (strcmp(tokens[2], "ipv4") == 0) {
2347 struct in_addr addr;
2349 m->match.lpm.ip_version = 1;
2351 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2352 snprintf(out, out_size, MSG_ARG_INVALID,
2357 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2358 } else if (strcmp(tokens[2], "ipv6") == 0) {
2359 struct in6_addr addr;
2361 m->match.lpm.ip_version = 0;
2363 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2364 snprintf(out, out_size, MSG_ARG_INVALID,
2369 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2371 snprintf(out, out_size, MSG_ARG_MISMATCH,
2376 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2377 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2384 snprintf(out, out_size, MSG_ARG_MISMATCH,
2385 "acl or array or hash or lpm");
2397 * | table <table_id>
2398 * [balance <out0> ... <out7>]
2400 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2401 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2402 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2403 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2404 * [tm subport <subport_id> pipe <pipe_id>]
2407 * | vlan <da> <sa> <pcp> <dei> <vid>
2408 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2409 * | mpls unicast | multicast
2411 * label0 <label> <tc> <ttl>
2412 * [label1 <label> <tc> <ttl>
2413 * [label2 <label> <tc> <ttl>
2414 * [label3 <label> <tc> <ttl>]]]
2415 * | pppoe <da> <sa> <session_id>]
2416 * [nat ipv4 | ipv6 <addr> <port>]
2422 * <pa> ::= g | y | r | drop
2425 parse_table_action_fwd(char **tokens,
2427 struct softnic_table_rule_action *a)
2429 if (n_tokens == 0 ||
2430 (strcmp(tokens[0], "fwd") != 0))
2436 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2437 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2438 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2442 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2446 softnic_parser_read_uint32(&id, tokens[1]))
2449 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2451 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2455 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2456 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2457 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2461 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2465 softnic_parser_read_uint32(&id, tokens[1]))
2468 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2470 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2478 parse_table_action_balance(char **tokens,
2480 struct softnic_table_rule_action *a)
2484 if (n_tokens == 0 ||
2485 (strcmp(tokens[0], "balance") != 0))
2491 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2494 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2495 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2498 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2499 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2503 parse_policer_action(char *token, enum rte_table_action_policer *a)
2505 if (strcmp(token, "g") == 0) {
2506 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2510 if (strcmp(token, "y") == 0) {
2511 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2515 if (strcmp(token, "r") == 0) {
2516 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2520 if (strcmp(token, "drop") == 0) {
2521 *a = RTE_TABLE_ACTION_POLICER_DROP;
2529 parse_table_action_meter_tc(char **tokens,
2531 struct rte_table_action_mtr_tc_params *mtr)
2534 strcmp(tokens[0], "meter") ||
2535 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2536 strcmp(tokens[2], "policer") ||
2537 strcmp(tokens[3], "g") ||
2538 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2539 strcmp(tokens[5], "y") ||
2540 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2541 strcmp(tokens[7], "r") ||
2542 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2549 parse_table_action_meter(char **tokens,
2551 struct softnic_table_rule_action *a)
2553 if (n_tokens == 0 ||
2554 strcmp(tokens[0], "meter"))
2560 if (n_tokens < 10 ||
2561 strcmp(tokens[0], "tc0") ||
2562 (parse_table_action_meter_tc(tokens + 1,
2564 &a->mtr.mtr[0]) == 0))
2570 if (n_tokens == 0 ||
2571 strcmp(tokens[0], "tc1")) {
2573 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2577 if (n_tokens < 30 ||
2578 (parse_table_action_meter_tc(tokens + 1,
2579 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
2580 strcmp(tokens[10], "tc2") ||
2581 (parse_table_action_meter_tc(tokens + 11,
2582 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
2583 strcmp(tokens[20], "tc3") ||
2584 (parse_table_action_meter_tc(tokens + 21,
2585 n_tokens - 21, &a->mtr.mtr[3]) == 0))
2588 a->mtr.tc_mask = 0xF;
2589 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2590 return 1 + 10 + 3 * 10;
2594 parse_table_action_tm(char **tokens,
2596 struct softnic_table_rule_action *a)
2598 uint32_t subport_id, pipe_id;
2601 strcmp(tokens[0], "tm") ||
2602 strcmp(tokens[1], "subport") ||
2603 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
2604 strcmp(tokens[3], "pipe") ||
2605 softnic_parser_read_uint32(&pipe_id, tokens[4]))
2608 a->tm.subport_id = subport_id;
2609 a->tm.pipe_id = pipe_id;
2610 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
2615 parse_table_action_encap(char **tokens,
2617 struct softnic_table_rule_action *a)
2619 if (n_tokens == 0 ||
2620 strcmp(tokens[0], "encap"))
2627 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
2629 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
2630 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
2633 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
2634 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2639 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
2640 uint32_t pcp, dei, vid;
2643 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
2644 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
2645 softnic_parser_read_uint32(&pcp, tokens[3]) ||
2647 softnic_parser_read_uint32(&dei, tokens[4]) ||
2649 softnic_parser_read_uint32(&vid, tokens[5]) ||
2653 a->encap.vlan.vlan.pcp = pcp & 0x7;
2654 a->encap.vlan.vlan.dei = dei & 0x1;
2655 a->encap.vlan.vlan.vid = vid & 0xFFF;
2656 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
2657 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2662 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
2663 uint32_t svlan_pcp, svlan_dei, svlan_vid;
2664 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
2667 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
2668 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
2669 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
2671 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
2673 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
2674 svlan_vid > 0xFFF ||
2675 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
2677 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
2679 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
2683 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
2684 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
2685 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
2686 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
2687 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
2688 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
2689 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
2690 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2695 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
2696 uint32_t label, tc, ttl;
2701 if (strcmp(tokens[1], "unicast") == 0)
2702 a->encap.mpls.unicast = 1;
2703 else if (strcmp(tokens[1], "multicast") == 0)
2704 a->encap.mpls.unicast = 0;
2708 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
2709 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
2710 strcmp(tokens[4], "label0") ||
2711 softnic_parser_read_uint32(&label, tokens[5]) ||
2713 softnic_parser_read_uint32(&tc, tokens[6]) ||
2715 softnic_parser_read_uint32(&ttl, tokens[7]) ||
2719 a->encap.mpls.mpls[0].label = label;
2720 a->encap.mpls.mpls[0].tc = tc;
2721 a->encap.mpls.mpls[0].ttl = ttl;
2726 if (n_tokens == 0 ||
2727 strcmp(tokens[0], "label1")) {
2728 a->encap.mpls.mpls_count = 1;
2729 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2730 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2735 softnic_parser_read_uint32(&label, tokens[1]) ||
2737 softnic_parser_read_uint32(&tc, tokens[2]) ||
2739 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2743 a->encap.mpls.mpls[1].label = label;
2744 a->encap.mpls.mpls[1].tc = tc;
2745 a->encap.mpls.mpls[1].ttl = ttl;
2750 if (n_tokens == 0 ||
2751 strcmp(tokens[0], "label2")) {
2752 a->encap.mpls.mpls_count = 2;
2753 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2754 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2759 softnic_parser_read_uint32(&label, tokens[1]) ||
2761 softnic_parser_read_uint32(&tc, tokens[2]) ||
2763 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2767 a->encap.mpls.mpls[2].label = label;
2768 a->encap.mpls.mpls[2].tc = tc;
2769 a->encap.mpls.mpls[2].ttl = ttl;
2774 if (n_tokens == 0 ||
2775 strcmp(tokens[0], "label3")) {
2776 a->encap.mpls.mpls_count = 3;
2777 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2778 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2779 return 1 + 8 + 4 + 4;
2783 softnic_parser_read_uint32(&label, tokens[1]) ||
2785 softnic_parser_read_uint32(&tc, tokens[2]) ||
2787 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2791 a->encap.mpls.mpls[3].label = label;
2792 a->encap.mpls.mpls[3].tc = tc;
2793 a->encap.mpls.mpls[3].ttl = ttl;
2795 a->encap.mpls.mpls_count = 4;
2796 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2797 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2798 return 1 + 8 + 4 + 4 + 4;
2802 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
2804 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
2805 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
2806 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
2810 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
2811 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2819 parse_table_action_nat(char **tokens,
2821 struct softnic_table_rule_action *a)
2824 strcmp(tokens[0], "nat"))
2827 if (strcmp(tokens[1], "ipv4") == 0) {
2828 struct in_addr addr;
2831 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
2832 softnic_parser_read_uint16(&port, tokens[3]))
2835 a->nat.ip_version = 1;
2836 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2838 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2842 if (strcmp(tokens[1], "ipv6") == 0) {
2843 struct in6_addr addr;
2846 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
2847 softnic_parser_read_uint16(&port, tokens[3]))
2850 a->nat.ip_version = 0;
2851 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
2853 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2861 parse_table_action_ttl(char **tokens,
2863 struct softnic_table_rule_action *a)
2866 strcmp(tokens[0], "ttl"))
2869 if (strcmp(tokens[1], "dec") == 0)
2870 a->ttl.decrement = 1;
2871 else if (strcmp(tokens[1], "keep") == 0)
2872 a->ttl.decrement = 0;
2876 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
2881 parse_table_action_stats(char **tokens,
2883 struct softnic_table_rule_action *a)
2886 strcmp(tokens[0], "stats"))
2889 a->stats.n_packets = 0;
2890 a->stats.n_bytes = 0;
2891 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
2896 parse_table_action_time(char **tokens,
2898 struct softnic_table_rule_action *a)
2901 strcmp(tokens[0], "time"))
2904 a->time.time = rte_rdtsc();
2905 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
2910 parse_table_action(char **tokens,
2914 struct softnic_table_rule_action *a)
2916 uint32_t n_tokens0 = n_tokens;
2918 memset(a, 0, sizeof(*a));
2921 strcmp(tokens[0], "action"))
2927 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
2930 n = parse_table_action_fwd(tokens, n_tokens, a);
2932 snprintf(out, out_size, MSG_ARG_INVALID,
2941 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
2944 n = parse_table_action_balance(tokens, n_tokens, a);
2946 snprintf(out, out_size, MSG_ARG_INVALID,
2955 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
2958 n = parse_table_action_meter(tokens, n_tokens, a);
2960 snprintf(out, out_size, MSG_ARG_INVALID,
2969 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
2972 n = parse_table_action_tm(tokens, n_tokens, a);
2974 snprintf(out, out_size, MSG_ARG_INVALID,
2983 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
2986 n = parse_table_action_encap(tokens, n_tokens, a);
2988 snprintf(out, out_size, MSG_ARG_INVALID,
2997 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3000 n = parse_table_action_nat(tokens, n_tokens, a);
3002 snprintf(out, out_size, MSG_ARG_INVALID,
3011 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3014 n = parse_table_action_ttl(tokens, n_tokens, a);
3016 snprintf(out, out_size, MSG_ARG_INVALID,
3025 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3028 n = parse_table_action_stats(tokens, n_tokens, a);
3030 snprintf(out, out_size, MSG_ARG_INVALID,
3039 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3042 n = parse_table_action_time(tokens, n_tokens, a);
3044 snprintf(out, out_size, MSG_ARG_INVALID,
3053 if (n_tokens0 - n_tokens == 1) {
3054 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3058 return n_tokens0 - n_tokens;
3062 * pipeline <pipeline_name> table <table_id> rule add
3064 * action <table_action>
3067 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3073 struct softnic_table_rule_match m;
3074 struct softnic_table_rule_action a;
3075 char *pipeline_name;
3077 uint32_t table_id, t0, n_tokens_parsed;
3081 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3085 pipeline_name = tokens[1];
3087 if (strcmp(tokens[2], "table") != 0) {
3088 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3092 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3093 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3097 if (strcmp(tokens[4], "rule") != 0) {
3098 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3102 if (strcmp(tokens[5], "add") != 0) {
3103 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3110 n_tokens_parsed = parse_match(tokens + t0,
3115 if (n_tokens_parsed == 0)
3117 t0 += n_tokens_parsed;
3120 n_tokens_parsed = parse_table_action(tokens + t0,
3125 if (n_tokens_parsed == 0)
3127 t0 += n_tokens_parsed;
3129 if (t0 != n_tokens) {
3130 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3134 status = softnic_pipeline_table_rule_add(softnic,
3141 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3147 * pipeline <pipeline_name> table <table_id> rule add
3155 * | table <table_id>
3158 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3164 struct softnic_table_rule_action action;
3166 char *pipeline_name;
3170 if (n_tokens != 11 &&
3172 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3176 pipeline_name = tokens[1];
3178 if (strcmp(tokens[2], "table") != 0) {
3179 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3183 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3184 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3188 if (strcmp(tokens[4], "rule") != 0) {
3189 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3193 if (strcmp(tokens[5], "add") != 0) {
3194 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3198 if (strcmp(tokens[6], "match") != 0) {
3199 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3203 if (strcmp(tokens[7], "default") != 0) {
3204 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3208 if (strcmp(tokens[8], "action") != 0) {
3209 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3213 if (strcmp(tokens[9], "fwd") != 0) {
3214 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3218 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3220 if (strcmp(tokens[10], "drop") == 0) {
3221 if (n_tokens != 11) {
3222 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3226 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3227 } else if (strcmp(tokens[10], "port") == 0) {
3230 if (n_tokens != 12) {
3231 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3235 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3236 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3240 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3242 } else if (strcmp(tokens[10], "meta") == 0) {
3243 if (n_tokens != 11) {
3244 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3248 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3249 } else if (strcmp(tokens[10], "table") == 0) {
3252 if (n_tokens != 12) {
3253 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3257 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3258 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3262 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3265 snprintf(out, out_size, MSG_ARG_INVALID,
3266 "drop or port or meta or table");
3270 status = softnic_pipeline_table_rule_add_default(softnic,
3276 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3282 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
3285 * - line format: match <match> action <action>
3288 cli_rule_file_process(const char *file_name,
3289 size_t line_len_max,
3290 struct softnic_table_rule_match *m,
3291 struct softnic_table_rule_action *a,
3293 uint32_t *line_number,
3298 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
3304 struct softnic_table_rule_match *match;
3305 struct softnic_table_rule_action *action;
3307 char *pipeline_name, *file_name;
3308 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3311 if (n_tokens != 9) {
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");
3338 if (strcmp(tokens[6], "bulk") != 0) {
3339 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3343 file_name = tokens[7];
3345 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3347 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3351 /* Memory allocation. */
3352 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
3353 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
3354 data = calloc(n_rules, sizeof(void *));
3355 if (match == NULL ||
3358 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3365 /* Load rule file */
3366 n_rules_parsed = n_rules;
3367 status = cli_rule_file_process(file_name,
3376 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3382 if (n_rules_parsed != n_rules) {
3383 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3391 status = softnic_pipeline_table_rule_add_bulk(softnic,
3399 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3413 * pipeline <pipeline_name> table <table_id> rule delete
3417 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
3423 struct softnic_table_rule_match m;
3424 char *pipeline_name;
3425 uint32_t table_id, n_tokens_parsed, t0;
3429 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3433 pipeline_name = tokens[1];
3435 if (strcmp(tokens[2], "table") != 0) {
3436 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3440 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3441 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3445 if (strcmp(tokens[4], "rule") != 0) {
3446 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3450 if (strcmp(tokens[5], "delete") != 0) {
3451 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3458 n_tokens_parsed = parse_match(tokens + t0,
3463 if (n_tokens_parsed == 0)
3465 t0 += n_tokens_parsed;
3467 if (n_tokens != t0) {
3468 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3472 status = softnic_pipeline_table_rule_delete(softnic,
3477 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3483 * pipeline <pipeline_name> table <table_id> rule delete
3488 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
3494 char *pipeline_name;
3498 if (n_tokens != 8) {
3499 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3503 pipeline_name = tokens[1];
3505 if (strcmp(tokens[2], "table") != 0) {
3506 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3510 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3511 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3515 if (strcmp(tokens[4], "rule") != 0) {
3516 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3520 if (strcmp(tokens[5], "delete") != 0) {
3521 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3525 if (strcmp(tokens[6], "match") != 0) {
3526 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3530 if (strcmp(tokens[7], "default") != 0) {
3531 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3535 status = softnic_pipeline_table_rule_delete_default(softnic,
3539 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3545 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
3548 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
3550 uint32_t n_tokens __rte_unused,
3554 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3558 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
3559 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
3560 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
3563 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
3569 struct rte_table_action_meter_profile p;
3570 char *pipeline_name;
3571 uint32_t table_id, meter_profile_id;
3575 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3579 pipeline_name = tokens[1];
3581 if (strcmp(tokens[2], "table") != 0) {
3582 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3586 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3587 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3591 if (strcmp(tokens[4], "meter") != 0) {
3592 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3596 if (strcmp(tokens[5], "profile") != 0) {
3597 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3601 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3602 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3606 if (strcmp(tokens[7], "add") != 0) {
3607 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3611 if (strcmp(tokens[8], "srtcm") == 0) {
3612 if (n_tokens != 15) {
3613 snprintf(out, out_size, MSG_ARG_MISMATCH,
3618 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
3620 if (strcmp(tokens[9], "cir") != 0) {
3621 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3625 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
3626 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3630 if (strcmp(tokens[11], "cbs") != 0) {
3631 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3635 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
3636 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3640 if (strcmp(tokens[13], "ebs") != 0) {
3641 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
3645 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
3646 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
3649 } else if (strcmp(tokens[8], "trtcm") == 0) {
3650 if (n_tokens != 17) {
3651 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3655 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
3657 if (strcmp(tokens[9], "cir") != 0) {
3658 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3662 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
3663 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3667 if (strcmp(tokens[11], "pir") != 0) {
3668 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
3672 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
3673 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
3676 if (strcmp(tokens[13], "cbs") != 0) {
3677 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3681 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
3682 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3686 if (strcmp(tokens[15], "pbs") != 0) {
3687 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
3691 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
3692 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
3696 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3700 status = softnic_pipeline_table_mtr_profile_add(softnic,
3706 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3712 * pipeline <pipeline_name> table <table_id>
3713 * meter profile <meter_profile_id> delete
3716 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
3722 char *pipeline_name;
3723 uint32_t table_id, meter_profile_id;
3726 if (n_tokens != 8) {
3727 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3731 pipeline_name = tokens[1];
3733 if (strcmp(tokens[2], "table") != 0) {
3734 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3738 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3739 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3743 if (strcmp(tokens[4], "meter") != 0) {
3744 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3748 if (strcmp(tokens[5], "profile") != 0) {
3749 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3753 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3754 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3758 if (strcmp(tokens[7], "delete") != 0) {
3759 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3763 status = softnic_pipeline_table_mtr_profile_delete(softnic,
3768 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3774 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
3777 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
3779 uint32_t n_tokens __rte_unused,
3783 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3787 * pipeline <pipeline_name> table <table_id> dscp <file_name>
3790 * - exactly 64 lines
3791 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
3794 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
3795 const char *file_name,
3796 uint32_t *line_number)
3801 /* Check input arguments */
3802 if (dscp_table == NULL ||
3803 file_name == NULL ||
3804 line_number == NULL) {
3810 /* Open input file */
3811 f = fopen(file_name, "r");
3818 for (dscp = 0, l = 1; ; l++) {
3821 enum rte_meter_color color;
3822 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
3824 if (fgets(line, sizeof(line), f) == NULL)
3827 if (is_comment(line))
3830 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
3839 if (dscp >= RTE_DIM(dscp_table->entry) ||
3840 n_tokens != RTE_DIM(tokens) ||
3841 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
3842 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
3843 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
3844 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
3845 (strlen(tokens[2]) != 1)) {
3851 switch (tokens[2][0]) {
3854 color = e_RTE_METER_GREEN;
3859 color = e_RTE_METER_YELLOW;
3864 color = e_RTE_METER_RED;
3873 dscp_table->entry[dscp].tc_id = tc_id;
3874 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
3875 dscp_table->entry[dscp].color = color;
3885 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
3891 struct rte_table_action_dscp_table dscp_table;
3892 char *pipeline_name, *file_name;
3893 uint32_t table_id, line_number;
3896 if (n_tokens != 6) {
3897 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3901 pipeline_name = tokens[1];
3903 if (strcmp(tokens[2], "table") != 0) {
3904 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3908 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3909 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3913 if (strcmp(tokens[4], "dscp") != 0) {
3914 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
3918 file_name = tokens[5];
3920 status = load_dscp_table(&dscp_table, file_name, &line_number);
3922 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3926 status = softnic_pipeline_table_dscp_table_update(softnic,
3932 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3938 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
3941 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
3943 uint32_t n_tokens __rte_unused,
3947 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3951 * thread <thread_id> pipeline <pipeline_name> enable
3954 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
3960 char *pipeline_name;
3964 if (n_tokens != 5) {
3965 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3969 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
3970 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
3974 if (strcmp(tokens[2], "pipeline") != 0) {
3975 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
3979 pipeline_name = tokens[3];
3981 if (strcmp(tokens[4], "enable") != 0) {
3982 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
3986 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
3988 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
3994 * thread <thread_id> pipeline <pipeline_name> disable
3997 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4003 char *pipeline_name;
4007 if (n_tokens != 5) {
4008 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4012 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4013 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4017 if (strcmp(tokens[2], "pipeline") != 0) {
4018 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4022 pipeline_name = tokens[3];
4024 if (strcmp(tokens[4], "disable") != 0) {
4025 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4029 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4031 snprintf(out, out_size, MSG_CMD_FAIL,
4032 "thread pipeline disable");
4038 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4040 char *tokens[CMD_MAX_TOKENS];
4041 uint32_t n_tokens = RTE_DIM(tokens);
4042 struct pmd_internals *softnic = arg;
4048 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4050 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4057 if (strcmp(tokens[0], "mempool") == 0) {
4058 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4062 if (strcmp(tokens[0], "link") == 0) {
4063 cmd_link(softnic, tokens, n_tokens, out, out_size);
4067 if (strcmp(tokens[0], "swq") == 0) {
4068 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4072 if (strcmp(tokens[0], "tmgr") == 0) {
4073 if (n_tokens == 2) {
4074 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4078 if (n_tokens >= 3 &&
4079 (strcmp(tokens[1], "shaper") == 0) &&
4080 (strcmp(tokens[2], "profile") == 0)) {
4081 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4086 if (strcmp(tokens[0], "tap") == 0) {
4087 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4091 if (strcmp(tokens[0], "port") == 0) {
4092 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4096 if (strcmp(tokens[0], "table") == 0) {
4097 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4101 if (strcmp(tokens[0], "pipeline") == 0) {
4102 if (n_tokens >= 3 &&
4103 (strcmp(tokens[2], "period") == 0)) {
4104 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4108 if (n_tokens >= 5 &&
4109 (strcmp(tokens[2], "port") == 0) &&
4110 (strcmp(tokens[3], "in") == 0) &&
4111 (strcmp(tokens[4], "bsz") == 0)) {
4112 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4116 if (n_tokens >= 5 &&
4117 (strcmp(tokens[2], "port") == 0) &&
4118 (strcmp(tokens[3], "out") == 0) &&
4119 (strcmp(tokens[4], "bsz") == 0)) {
4120 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4124 if (n_tokens >= 4 &&
4125 (strcmp(tokens[2], "table") == 0) &&
4126 (strcmp(tokens[3], "match") == 0)) {
4127 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4131 if (n_tokens >= 6 &&
4132 (strcmp(tokens[2], "port") == 0) &&
4133 (strcmp(tokens[3], "in") == 0) &&
4134 (strcmp(tokens[5], "table") == 0)) {
4135 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4140 if (n_tokens >= 6 &&
4141 (strcmp(tokens[2], "port") == 0) &&
4142 (strcmp(tokens[3], "in") == 0) &&
4143 (strcmp(tokens[5], "stats") == 0)) {
4144 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4149 if (n_tokens >= 6 &&
4150 (strcmp(tokens[2], "port") == 0) &&
4151 (strcmp(tokens[3], "in") == 0) &&
4152 (strcmp(tokens[5], "enable") == 0)) {
4153 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4158 if (n_tokens >= 6 &&
4159 (strcmp(tokens[2], "port") == 0) &&
4160 (strcmp(tokens[3], "in") == 0) &&
4161 (strcmp(tokens[5], "disable") == 0)) {
4162 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4167 if (n_tokens >= 6 &&
4168 (strcmp(tokens[2], "port") == 0) &&
4169 (strcmp(tokens[3], "out") == 0) &&
4170 (strcmp(tokens[5], "stats") == 0)) {
4171 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4176 if (n_tokens >= 5 &&
4177 (strcmp(tokens[2], "table") == 0) &&
4178 (strcmp(tokens[4], "stats") == 0)) {
4179 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4184 if (n_tokens >= 7 &&
4185 (strcmp(tokens[2], "table") == 0) &&
4186 (strcmp(tokens[4], "rule") == 0) &&
4187 (strcmp(tokens[5], "add") == 0) &&
4188 (strcmp(tokens[6], "match") == 0)) {
4189 if (n_tokens >= 8 &&
4190 (strcmp(tokens[7], "default") == 0)) {
4191 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4192 n_tokens, out, out_size);
4196 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4201 if (n_tokens >= 7 &&
4202 (strcmp(tokens[2], "table") == 0) &&
4203 (strcmp(tokens[4], "rule") == 0) &&
4204 (strcmp(tokens[5], "add") == 0) &&
4205 (strcmp(tokens[6], "bulk") == 0)) {
4206 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4207 n_tokens, out, out_size);
4211 if (n_tokens >= 7 &&
4212 (strcmp(tokens[2], "table") == 0) &&
4213 (strcmp(tokens[4], "rule") == 0) &&
4214 (strcmp(tokens[5], "delete") == 0) &&
4215 (strcmp(tokens[6], "match") == 0)) {
4216 if (n_tokens >= 8 &&
4217 (strcmp(tokens[7], "default") == 0)) {
4218 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
4219 n_tokens, out, out_size);
4223 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
4228 if (n_tokens >= 7 &&
4229 (strcmp(tokens[2], "table") == 0) &&
4230 (strcmp(tokens[4], "rule") == 0) &&
4231 (strcmp(tokens[5], "read") == 0) &&
4232 (strcmp(tokens[6], "stats") == 0)) {
4233 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
4238 if (n_tokens >= 8 &&
4239 (strcmp(tokens[2], "table") == 0) &&
4240 (strcmp(tokens[4], "meter") == 0) &&
4241 (strcmp(tokens[5], "profile") == 0) &&
4242 (strcmp(tokens[7], "add") == 0)) {
4243 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
4248 if (n_tokens >= 8 &&
4249 (strcmp(tokens[2], "table") == 0) &&
4250 (strcmp(tokens[4], "meter") == 0) &&
4251 (strcmp(tokens[5], "profile") == 0) &&
4252 (strcmp(tokens[7], "delete") == 0)) {
4253 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
4254 n_tokens, out, out_size);
4258 if (n_tokens >= 7 &&
4259 (strcmp(tokens[2], "table") == 0) &&
4260 (strcmp(tokens[4], "rule") == 0) &&
4261 (strcmp(tokens[5], "read") == 0) &&
4262 (strcmp(tokens[6], "meter") == 0)) {
4263 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
4268 if (n_tokens >= 5 &&
4269 (strcmp(tokens[2], "table") == 0) &&
4270 (strcmp(tokens[4], "dscp") == 0)) {
4271 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
4276 if (n_tokens >= 7 &&
4277 (strcmp(tokens[2], "table") == 0) &&
4278 (strcmp(tokens[4], "rule") == 0) &&
4279 (strcmp(tokens[5], "read") == 0) &&
4280 (strcmp(tokens[6], "ttl") == 0)) {
4281 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
4287 if (strcmp(tokens[0], "thread") == 0) {
4288 if (n_tokens >= 5 &&
4289 (strcmp(tokens[4], "enable") == 0)) {
4290 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
4295 if (n_tokens >= 5 &&
4296 (strcmp(tokens[4], "disable") == 0)) {
4297 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
4303 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
4307 softnic_cli_script_process(struct pmd_internals *softnic,
4308 const char *file_name,
4309 size_t msg_in_len_max,
4310 size_t msg_out_len_max)
4312 char *msg_in = NULL, *msg_out = NULL;
4315 /* Check input arguments */
4316 if (file_name == NULL ||
4317 (strlen(file_name) == 0) ||
4318 msg_in_len_max == 0 ||
4319 msg_out_len_max == 0)
4322 msg_in = malloc(msg_in_len_max + 1);
4323 msg_out = malloc(msg_out_len_max + 1);
4324 if (msg_in == NULL ||
4331 /* Open input file */
4332 f = fopen(file_name, "r");
4341 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
4344 printf("%s", msg_in);
4347 softnic_cli_process(msg_in,
4352 if (strlen(msg_out))
4353 printf("%s", msg_out);
4364 cli_rule_file_process(const char *file_name,
4365 size_t line_len_max,
4366 struct softnic_table_rule_match *m,
4367 struct softnic_table_rule_action *a,
4369 uint32_t *line_number,
4375 uint32_t rule_id, line_id;
4378 /* Check input arguments */
4379 if (file_name == NULL ||
4380 (strlen(file_name) == 0) ||
4381 line_len_max == 0) {
4386 /* Memory allocation */
4387 line = malloc(line_len_max + 1);
4394 f = fopen(file_name, "r");
4402 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
4403 char *tokens[CMD_MAX_TOKENS];
4404 uint32_t n_tokens, n_tokens_parsed, t0;
4406 /* Read next line from file. */
4407 if (fgets(line, line_len_max + 1, f) == NULL)
4411 if (is_comment(line))
4415 n_tokens = RTE_DIM(tokens);
4416 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
4428 n_tokens_parsed = parse_match(tokens + t0,
4433 if (n_tokens_parsed == 0) {
4437 t0 += n_tokens_parsed;
4440 n_tokens_parsed = parse_table_action(tokens + t0,
4445 if (n_tokens_parsed == 0) {
4449 t0 += n_tokens_parsed;
4451 /* Line completed. */
4452 if (t0 < n_tokens) {
4457 /* Increment rule count */
4468 *line_number = line_id;