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]);
191 cmd_tap(struct pmd_internals *softnic,
198 struct softnic_tap *tap;
201 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
207 tap = softnic_tap_create(softnic, name);
209 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
215 * port in action profile <profile_name>
216 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
217 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
220 cmd_port_in_action_profile(struct pmd_internals *softnic,
226 struct softnic_port_in_action_profile_params p;
227 struct softnic_port_in_action_profile *ap;
231 memset(&p, 0, sizeof(p));
234 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
238 if (strcmp(tokens[1], "in") != 0) {
239 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
243 if (strcmp(tokens[2], "action") != 0) {
244 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
248 if (strcmp(tokens[3], "profile") != 0) {
249 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
258 (strcmp(tokens[t0], "filter") == 0)) {
261 if (n_tokens < t0 + 10) {
262 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
266 if (strcmp(tokens[t0 + 1], "match") == 0) {
267 p.fltr.filter_on_match = 1;
268 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
269 p.fltr.filter_on_match = 0;
271 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
275 if (strcmp(tokens[t0 + 2], "offset") != 0) {
276 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
280 if (softnic_parser_read_uint32(&p.fltr.key_offset,
281 tokens[t0 + 3]) != 0) {
282 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
286 if (strcmp(tokens[t0 + 4], "mask") != 0) {
287 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
291 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
292 if ((softnic_parse_hex_string(tokens[t0 + 5],
293 p.fltr.key_mask, &size) != 0) ||
294 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
295 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
299 if (strcmp(tokens[t0 + 6], "key") != 0) {
300 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
304 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
305 if ((softnic_parse_hex_string(tokens[t0 + 7],
306 p.fltr.key, &size) != 0) ||
307 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
308 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
312 if (strcmp(tokens[t0 + 8], "port") != 0) {
313 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
317 if (softnic_parser_read_uint32(&p.fltr.port_id,
318 tokens[t0 + 9]) != 0) {
319 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
323 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
328 (strcmp(tokens[t0], "balance") == 0)) {
331 if (n_tokens < t0 + 22) {
332 snprintf(out, out_size, MSG_ARG_MISMATCH,
333 "port in action profile balance");
337 if (strcmp(tokens[t0 + 1], "offset") != 0) {
338 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
342 if (softnic_parser_read_uint32(&p.lb.key_offset,
343 tokens[t0 + 2]) != 0) {
344 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
348 if (strcmp(tokens[t0 + 3], "mask") != 0) {
349 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
353 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
354 if (softnic_parse_hex_string(tokens[t0 + 4],
355 p.lb.key_mask, &p.lb.key_size) != 0) {
356 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
360 if (strcmp(tokens[t0 + 5], "port") != 0) {
361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
365 for (i = 0; i < 16; i++)
366 if (softnic_parser_read_uint32(&p.lb.port_id[i],
367 tokens[t0 + 6 + i]) != 0) {
368 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
372 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
377 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
381 ap = softnic_port_in_action_profile_create(softnic, name, &p);
383 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
389 * table action profile <profile_name>
393 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
394 * [meter srtcm | trtcm
396 * stats none | pkts | bytes | both]
397 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
398 * [encap ether | vlan | qinq | mpls | pppoe]
403 * [stats pkts | bytes | both]
407 cmd_table_action_profile(struct pmd_internals *softnic,
413 struct softnic_table_action_profile_params p;
414 struct softnic_table_action_profile *ap;
418 memset(&p, 0, sizeof(p));
421 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
425 if (strcmp(tokens[1], "action") != 0) {
426 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
430 if (strcmp(tokens[2], "profile") != 0) {
431 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
437 if (strcmp(tokens[4], "ipv4") == 0) {
438 p.common.ip_version = 1;
439 } else if (strcmp(tokens[4], "ipv6") == 0) {
440 p.common.ip_version = 0;
442 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
446 if (strcmp(tokens[5], "offset") != 0) {
447 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
451 if (softnic_parser_read_uint32(&p.common.ip_offset,
453 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
457 if (strcmp(tokens[7], "fwd") != 0) {
458 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
462 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
466 (strcmp(tokens[t0], "balance") == 0)) {
467 if (n_tokens < t0 + 7) {
468 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
472 if (strcmp(tokens[t0 + 1], "offset") != 0) {
473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
477 if (softnic_parser_read_uint32(&p.lb.key_offset,
478 tokens[t0 + 2]) != 0) {
479 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
483 if (strcmp(tokens[t0 + 3], "mask") != 0) {
484 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
488 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
489 if (softnic_parse_hex_string(tokens[t0 + 4],
490 p.lb.key_mask, &p.lb.key_size) != 0) {
491 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
495 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
496 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
500 if (softnic_parser_read_uint32(&p.lb.out_offset,
501 tokens[t0 + 6]) != 0) {
502 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
506 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
511 (strcmp(tokens[t0], "meter") == 0)) {
512 if (n_tokens < t0 + 6) {
513 snprintf(out, out_size, MSG_ARG_MISMATCH,
514 "table action profile meter");
518 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
519 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
520 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
521 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
523 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
528 if (strcmp(tokens[t0 + 2], "tc") != 0) {
529 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
533 if (softnic_parser_read_uint32(&p.mtr.n_tc,
534 tokens[t0 + 3]) != 0) {
535 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
539 if (strcmp(tokens[t0 + 4], "stats") != 0) {
540 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
544 if (strcmp(tokens[t0 + 5], "none") == 0) {
545 p.mtr.n_packets_enabled = 0;
546 p.mtr.n_bytes_enabled = 0;
547 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
548 p.mtr.n_packets_enabled = 1;
549 p.mtr.n_bytes_enabled = 0;
550 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
551 p.mtr.n_packets_enabled = 0;
552 p.mtr.n_bytes_enabled = 1;
553 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
554 p.mtr.n_packets_enabled = 1;
555 p.mtr.n_bytes_enabled = 1;
557 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
558 "none or pkts or bytes or both");
562 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
567 (strcmp(tokens[t0], "tm") == 0)) {
568 if (n_tokens < t0 + 5) {
569 snprintf(out, out_size, MSG_ARG_MISMATCH,
570 "table action profile tm");
574 if (strcmp(tokens[t0 + 1], "spp") != 0) {
575 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
579 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
580 tokens[t0 + 2]) != 0) {
581 snprintf(out, out_size, MSG_ARG_INVALID,
582 "n_subports_per_port");
586 if (strcmp(tokens[t0 + 3], "pps") != 0) {
587 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
591 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
592 tokens[t0 + 4]) != 0) {
593 snprintf(out, out_size, MSG_ARG_INVALID,
594 "n_pipes_per_subport");
598 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
603 (strcmp(tokens[t0], "encap") == 0)) {
604 if (n_tokens < t0 + 2) {
605 snprintf(out, out_size, MSG_ARG_MISMATCH,
606 "action profile encap");
610 if (strcmp(tokens[t0 + 1], "ether") == 0) {
611 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
612 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
613 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
614 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
615 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
616 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
617 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
618 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
619 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
621 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
625 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
630 (strcmp(tokens[t0], "nat") == 0)) {
631 if (n_tokens < t0 + 4) {
632 snprintf(out, out_size, MSG_ARG_MISMATCH,
633 "table action profile nat");
637 if (strcmp(tokens[t0 + 1], "src") == 0) {
638 p.nat.source_nat = 1;
639 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
640 p.nat.source_nat = 0;
642 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
647 if (strcmp(tokens[t0 + 2], "proto") != 0) {
648 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
652 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
654 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
657 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
662 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
667 (strcmp(tokens[t0], "ttl") == 0)) {
668 if (n_tokens < t0 + 4) {
669 snprintf(out, out_size, MSG_ARG_MISMATCH,
670 "table action profile ttl");
674 if (strcmp(tokens[t0 + 1], "drop") == 0) {
676 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
679 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
684 if (strcmp(tokens[t0 + 2], "stats") != 0) {
685 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
689 if (strcmp(tokens[t0 + 3], "none") == 0) {
690 p.ttl.n_packets_enabled = 0;
691 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
692 p.ttl.n_packets_enabled = 1;
694 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
699 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
704 (strcmp(tokens[t0], "stats") == 0)) {
705 if (n_tokens < t0 + 2) {
706 snprintf(out, out_size, MSG_ARG_MISMATCH,
707 "table action profile stats");
711 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
712 p.stats.n_packets_enabled = 1;
713 p.stats.n_bytes_enabled = 0;
714 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
715 p.stats.n_packets_enabled = 0;
716 p.stats.n_bytes_enabled = 1;
717 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
718 p.stats.n_packets_enabled = 1;
719 p.stats.n_bytes_enabled = 1;
721 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
722 "pkts or bytes or both");
726 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
731 (strcmp(tokens[t0], "time") == 0)) {
732 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
737 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
741 ap = softnic_table_action_profile_create(softnic, name, &p);
743 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
749 * pipeline <pipeline_name>
750 * period <timer_period_ms>
751 * offset_port_id <offset_port_id>
754 cmd_pipeline(struct pmd_internals *softnic,
760 struct pipeline_params p;
762 struct pipeline *pipeline;
765 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
771 if (strcmp(tokens[2], "period") != 0) {
772 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
776 if (softnic_parser_read_uint32(&p.timer_period_ms,
778 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
782 if (strcmp(tokens[4], "offset_port_id") != 0) {
783 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
787 if (softnic_parser_read_uint32(&p.offset_port_id,
789 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
793 pipeline = softnic_pipeline_create(softnic, name, &p);
794 if (pipeline == NULL) {
795 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
801 * pipeline <pipeline_name> port in
803 * link <link_name> rxq <queue_id>
806 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
807 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
808 * [action <port_in_action_profile_name>]
812 cmd_pipeline_port_in(struct pmd_internals *softnic,
818 struct softnic_port_in_params p;
824 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
828 pipeline_name = tokens[1];
830 if (strcmp(tokens[2], "port") != 0) {
831 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
835 if (strcmp(tokens[3], "in") != 0) {
836 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
840 if (strcmp(tokens[4], "bsz") != 0) {
841 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
845 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
846 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
852 if (strcmp(tokens[t0], "link") == 0) {
853 if (n_tokens < t0 + 4) {
854 snprintf(out, out_size, MSG_ARG_MISMATCH,
855 "pipeline port in link");
859 p.type = PORT_IN_RXQ;
861 p.dev_name = tokens[t0 + 1];
863 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
864 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
868 if (softnic_parser_read_uint16(&p.rxq.queue_id,
869 tokens[t0 + 3]) != 0) {
870 snprintf(out, out_size, MSG_ARG_INVALID,
875 } else if (strcmp(tokens[t0], "swq") == 0) {
876 if (n_tokens < t0 + 2) {
877 snprintf(out, out_size, MSG_ARG_MISMATCH,
878 "pipeline port in swq");
882 p.type = PORT_IN_SWQ;
884 p.dev_name = tokens[t0 + 1];
887 } else if (strcmp(tokens[t0], "tmgr") == 0) {
888 if (n_tokens < t0 + 2) {
889 snprintf(out, out_size, MSG_ARG_MISMATCH,
890 "pipeline port in tmgr");
894 p.type = PORT_IN_TMGR;
896 p.dev_name = tokens[t0 + 1];
899 } else if (strcmp(tokens[t0], "tap") == 0) {
900 if (n_tokens < t0 + 6) {
901 snprintf(out, out_size, MSG_ARG_MISMATCH,
902 "pipeline port in tap");
906 p.type = PORT_IN_TAP;
908 p.dev_name = tokens[t0 + 1];
910 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
911 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
916 p.tap.mempool_name = tokens[t0 + 3];
918 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
919 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
924 if (softnic_parser_read_uint32(&p.tap.mtu,
925 tokens[t0 + 5]) != 0) {
926 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
931 } else if (strcmp(tokens[t0], "source") == 0) {
932 if (n_tokens < t0 + 6) {
933 snprintf(out, out_size, MSG_ARG_MISMATCH,
934 "pipeline port in source");
938 p.type = PORT_IN_SOURCE;
942 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
943 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
948 p.source.mempool_name = tokens[t0 + 2];
950 if (strcmp(tokens[t0 + 3], "file") != 0) {
951 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
956 p.source.file_name = tokens[t0 + 4];
958 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
959 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
964 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
965 tokens[t0 + 6]) != 0) {
966 snprintf(out, out_size, MSG_ARG_INVALID,
973 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
977 p.action_profile_name = NULL;
979 (strcmp(tokens[t0], "action") == 0)) {
980 if (n_tokens < t0 + 2) {
981 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
985 p.action_profile_name = tokens[t0 + 1];
992 (strcmp(tokens[t0], "disabled") == 0)) {
998 if (n_tokens != t0) {
999 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1003 status = softnic_pipeline_port_in_create(softnic,
1008 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1014 * pipeline <pipeline_name> port out
1016 * link <link_name> txq <txq_id>
1018 * | tmgr <tmgr_name>
1020 * | sink [file <file_name> pkts <max_n_pkts>]
1023 cmd_pipeline_port_out(struct pmd_internals *softnic,
1029 struct softnic_port_out_params p;
1030 char *pipeline_name;
1033 memset(&p, 0, sizeof(p));
1036 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1040 pipeline_name = tokens[1];
1042 if (strcmp(tokens[2], "port") != 0) {
1043 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1047 if (strcmp(tokens[3], "out") != 0) {
1048 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1052 if (strcmp(tokens[4], "bsz") != 0) {
1053 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1057 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1058 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1062 if (strcmp(tokens[6], "link") == 0) {
1063 if (n_tokens != 10) {
1064 snprintf(out, out_size, MSG_ARG_MISMATCH,
1065 "pipeline port out link");
1069 p.type = PORT_OUT_TXQ;
1071 p.dev_name = tokens[7];
1073 if (strcmp(tokens[8], "txq") != 0) {
1074 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1078 if (softnic_parser_read_uint16(&p.txq.queue_id,
1080 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1083 } else if (strcmp(tokens[6], "swq") == 0) {
1084 if (n_tokens != 8) {
1085 snprintf(out, out_size, MSG_ARG_MISMATCH,
1086 "pipeline port out swq");
1090 p.type = PORT_OUT_SWQ;
1092 p.dev_name = tokens[7];
1093 } else if (strcmp(tokens[6], "tmgr") == 0) {
1094 if (n_tokens != 8) {
1095 snprintf(out, out_size, MSG_ARG_MISMATCH,
1096 "pipeline port out tmgr");
1100 p.type = PORT_OUT_TMGR;
1102 p.dev_name = tokens[7];
1103 } else if (strcmp(tokens[6], "tap") == 0) {
1104 if (n_tokens != 8) {
1105 snprintf(out, out_size, MSG_ARG_MISMATCH,
1106 "pipeline port out tap");
1110 p.type = PORT_OUT_TAP;
1112 p.dev_name = tokens[7];
1113 } else if (strcmp(tokens[6], "sink") == 0) {
1114 if ((n_tokens != 7) && (n_tokens != 11)) {
1115 snprintf(out, out_size, MSG_ARG_MISMATCH,
1116 "pipeline port out sink");
1120 p.type = PORT_OUT_SINK;
1124 if (n_tokens == 7) {
1125 p.sink.file_name = NULL;
1126 p.sink.max_n_pkts = 0;
1128 if (strcmp(tokens[7], "file") != 0) {
1129 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1134 p.sink.file_name = tokens[8];
1136 if (strcmp(tokens[9], "pkts") != 0) {
1137 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1141 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1143 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1148 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1152 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1154 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1160 * pipeline <pipeline_name> table
1164 * offset <ip_header_offset>
1167 * offset <key_offset>
1173 * offset <key_offset>
1174 * buckets <n_buckets>
1178 * offset <ip_header_offset>
1181 * [action <table_action_profile_name>]
1184 cmd_pipeline_table(struct pmd_internals *softnic,
1190 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1191 struct softnic_table_params p;
1192 char *pipeline_name;
1197 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1201 pipeline_name = tokens[1];
1203 if (strcmp(tokens[2], "table") != 0) {
1204 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1208 if (strcmp(tokens[3], "match") != 0) {
1209 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1214 if (strcmp(tokens[t0], "acl") == 0) {
1215 if (n_tokens < t0 + 6) {
1216 snprintf(out, out_size, MSG_ARG_MISMATCH,
1217 "pipeline table acl");
1221 p.match_type = TABLE_ACL;
1223 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1224 p.match.acl.ip_version = 1;
1225 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1226 p.match.acl.ip_version = 0;
1228 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1233 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1234 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1238 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1239 tokens[t0 + 3]) != 0) {
1240 snprintf(out, out_size, MSG_ARG_INVALID,
1241 "ip_header_offset");
1245 if (strcmp(tokens[t0 + 4], "size") != 0) {
1246 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1250 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1251 tokens[t0 + 5]) != 0) {
1252 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1257 } else if (strcmp(tokens[t0], "array") == 0) {
1258 if (n_tokens < t0 + 5) {
1259 snprintf(out, out_size, MSG_ARG_MISMATCH,
1260 "pipeline table array");
1264 p.match_type = TABLE_ARRAY;
1266 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1267 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1271 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1272 tokens[t0 + 2]) != 0) {
1273 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1277 if (strcmp(tokens[t0 + 3], "size") != 0) {
1278 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1282 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1283 tokens[t0 + 4]) != 0) {
1284 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1289 } else if (strcmp(tokens[t0], "hash") == 0) {
1290 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1292 if (n_tokens < t0 + 12) {
1293 snprintf(out, out_size, MSG_ARG_MISMATCH,
1294 "pipeline table hash");
1298 p.match_type = TABLE_HASH;
1300 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1301 p.match.hash.extendable_bucket = 1;
1302 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1303 p.match.hash.extendable_bucket = 0;
1305 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1310 if (strcmp(tokens[t0 + 2], "key") != 0) {
1311 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1315 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1316 tokens[t0 + 3]) != 0) ||
1317 p.match.hash.key_size == 0 ||
1318 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1319 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1323 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1324 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1328 if ((softnic_parse_hex_string(tokens[t0 + 5],
1329 key_mask, &key_mask_size) != 0) ||
1330 key_mask_size != p.match.hash.key_size) {
1331 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1334 p.match.hash.key_mask = key_mask;
1336 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1337 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1341 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1342 tokens[t0 + 7]) != 0) {
1343 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1347 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1348 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1352 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1353 tokens[t0 + 9]) != 0) {
1354 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1358 if (strcmp(tokens[t0 + 10], "size") != 0) {
1359 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1363 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1364 tokens[t0 + 11]) != 0) {
1365 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1370 } else if (strcmp(tokens[t0], "lpm") == 0) {
1371 if (n_tokens < t0 + 6) {
1372 snprintf(out, out_size, MSG_ARG_MISMATCH,
1373 "pipeline table lpm");
1377 p.match_type = TABLE_LPM;
1379 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1380 p.match.lpm.key_size = 4;
1381 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1382 p.match.lpm.key_size = 16;
1384 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1389 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1390 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1394 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1395 tokens[t0 + 3]) != 0) {
1396 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1400 if (strcmp(tokens[t0 + 4], "size") != 0) {
1401 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1405 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1406 tokens[t0 + 5]) != 0) {
1407 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1412 } else if (strcmp(tokens[t0], "stub") == 0) {
1413 p.match_type = TABLE_STUB;
1417 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1421 p.action_profile_name = NULL;
1422 if (n_tokens > t0 &&
1423 (strcmp(tokens[t0], "action") == 0)) {
1424 if (n_tokens < t0 + 2) {
1425 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1429 p.action_profile_name = tokens[t0 + 1];
1434 if (n_tokens > t0) {
1435 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1439 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1441 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1447 * pipeline <pipeline_name> port in <port_id> table <table_id>
1450 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1456 char *pipeline_name;
1457 uint32_t port_id, table_id;
1460 if (n_tokens != 7) {
1461 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1465 pipeline_name = tokens[1];
1467 if (strcmp(tokens[2], "port") != 0) {
1468 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1472 if (strcmp(tokens[3], "in") != 0) {
1473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1477 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1478 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1482 if (strcmp(tokens[5], "table") != 0) {
1483 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1487 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1488 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1492 status = softnic_pipeline_port_in_connect_to_table(softnic,
1497 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1503 * pipeline <pipeline_name> port in <port_id> stats read [clear]
1506 #define MSG_PIPELINE_PORT_IN_STATS \
1507 "Pkts in: %" PRIu64 "\n" \
1508 "Pkts dropped by AH: %" PRIu64 "\n" \
1509 "Pkts dropped by other: %" PRIu64 "\n"
1512 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
1518 struct rte_pipeline_port_in_stats stats;
1519 char *pipeline_name;
1523 if (n_tokens != 7 &&
1525 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1529 pipeline_name = tokens[1];
1531 if (strcmp(tokens[2], "port") != 0) {
1532 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1536 if (strcmp(tokens[3], "in") != 0) {
1537 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1541 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1542 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1546 if (strcmp(tokens[5], "stats") != 0) {
1547 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1551 if (strcmp(tokens[6], "read") != 0) {
1552 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1557 if (n_tokens == 8) {
1558 if (strcmp(tokens[7], "clear") != 0) {
1559 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1566 status = softnic_pipeline_port_in_stats_read(softnic,
1572 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1576 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
1577 stats.stats.n_pkts_in,
1578 stats.n_pkts_dropped_by_ah,
1579 stats.stats.n_pkts_drop);
1583 * pipeline <pipeline_name> port in <port_id> enable
1586 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1592 char *pipeline_name;
1596 if (n_tokens != 6) {
1597 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1601 pipeline_name = tokens[1];
1603 if (strcmp(tokens[2], "port") != 0) {
1604 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1608 if (strcmp(tokens[3], "in") != 0) {
1609 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1613 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1614 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1618 if (strcmp(tokens[5], "enable") != 0) {
1619 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1623 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1625 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1631 * pipeline <pipeline_name> port in <port_id> disable
1634 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1640 char *pipeline_name;
1644 if (n_tokens != 6) {
1645 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1649 pipeline_name = tokens[1];
1651 if (strcmp(tokens[2], "port") != 0) {
1652 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1656 if (strcmp(tokens[3], "in") != 0) {
1657 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1661 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1662 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1666 if (strcmp(tokens[5], "disable") != 0) {
1667 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1671 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1673 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1679 * pipeline <pipeline_name> port out <port_id> stats read [clear]
1681 #define MSG_PIPELINE_PORT_OUT_STATS \
1682 "Pkts in: %" PRIu64 "\n" \
1683 "Pkts dropped by AH: %" PRIu64 "\n" \
1684 "Pkts dropped by other: %" PRIu64 "\n"
1687 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
1693 struct rte_pipeline_port_out_stats stats;
1694 char *pipeline_name;
1698 if (n_tokens != 7 &&
1700 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1704 pipeline_name = tokens[1];
1706 if (strcmp(tokens[2], "port") != 0) {
1707 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1711 if (strcmp(tokens[3], "out") != 0) {
1712 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1716 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1717 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1721 if (strcmp(tokens[5], "stats") != 0) {
1722 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1726 if (strcmp(tokens[6], "read") != 0) {
1727 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1732 if (n_tokens == 8) {
1733 if (strcmp(tokens[7], "clear") != 0) {
1734 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1741 status = softnic_pipeline_port_out_stats_read(softnic,
1747 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1751 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
1752 stats.stats.n_pkts_in,
1753 stats.n_pkts_dropped_by_ah,
1754 stats.stats.n_pkts_drop);
1758 * pipeline <pipeline_name> table <table_id> stats read [clear]
1760 #define MSG_PIPELINE_TABLE_STATS \
1761 "Pkts in: %" PRIu64 "\n" \
1762 "Pkts in with lookup miss: %" PRIu64 "\n" \
1763 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
1764 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
1765 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
1766 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
1769 cmd_pipeline_table_stats(struct pmd_internals *softnic,
1775 struct rte_pipeline_table_stats stats;
1776 char *pipeline_name;
1780 if (n_tokens != 6 &&
1782 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1786 pipeline_name = tokens[1];
1788 if (strcmp(tokens[2], "table") != 0) {
1789 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1793 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
1794 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1798 if (strcmp(tokens[4], "stats") != 0) {
1799 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1803 if (strcmp(tokens[5], "read") != 0) {
1804 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1809 if (n_tokens == 7) {
1810 if (strcmp(tokens[6], "clear") != 0) {
1811 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1818 status = softnic_pipeline_table_stats_read(softnic,
1824 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1828 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
1829 stats.stats.n_pkts_in,
1830 stats.stats.n_pkts_lookup_miss,
1831 stats.n_pkts_dropped_by_lkp_hit_ah,
1832 stats.n_pkts_dropped_lkp_hit,
1833 stats.n_pkts_dropped_by_lkp_miss_ah,
1834 stats.n_pkts_dropped_lkp_miss);
1842 * priority <priority>
1843 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
1844 * <sp0> <sp1> <dp0> <dp1> <proto>
1848 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
1849 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
1850 * | ipv4_addr <addr>
1851 * | ipv6_addr <addr>
1852 * | qinq <svlan> <cvlan>
1854 * ipv4 | ipv6 <addr> <depth>
1856 struct pkt_key_qinq {
1857 uint16_t ethertype_svlan;
1859 uint16_t ethertype_cvlan;
1861 } __attribute__((__packed__));
1863 struct pkt_key_ipv4_5tuple {
1864 uint8_t time_to_live;
1866 uint16_t hdr_checksum;
1871 } __attribute__((__packed__));
1873 struct pkt_key_ipv6_5tuple {
1874 uint16_t payload_length;
1881 } __attribute__((__packed__));
1883 struct pkt_key_ipv4_addr {
1885 } __attribute__((__packed__));
1887 struct pkt_key_ipv6_addr {
1889 } __attribute__((__packed__));
1892 parse_match(char **tokens,
1896 struct softnic_table_rule_match *m)
1898 memset(m, 0, sizeof(*m));
1903 if (strcmp(tokens[0], "match") != 0) {
1904 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1908 if (strcmp(tokens[1], "acl") == 0) {
1909 if (n_tokens < 14) {
1910 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1914 m->match_type = TABLE_ACL;
1916 if (strcmp(tokens[2], "priority") != 0) {
1917 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
1921 if (softnic_parser_read_uint32(&m->match.acl.priority,
1923 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
1927 if (strcmp(tokens[4], "ipv4") == 0) {
1928 struct in_addr saddr, daddr;
1930 m->match.acl.ip_version = 1;
1932 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
1933 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
1936 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
1938 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
1939 snprintf(out, out_size, MSG_ARG_INVALID, "da");
1942 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
1943 } else if (strcmp(tokens[4], "ipv6") == 0) {
1944 struct in6_addr saddr, daddr;
1946 m->match.acl.ip_version = 0;
1948 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
1949 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
1952 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
1954 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
1955 snprintf(out, out_size, MSG_ARG_INVALID, "da");
1958 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
1960 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1965 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
1967 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
1971 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
1973 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
1977 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
1978 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
1982 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
1983 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
1987 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
1988 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
1992 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
1993 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
1997 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
1998 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2002 m->match.acl.proto_mask = 0xff;
2007 if (strcmp(tokens[1], "array") == 0) {
2009 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2013 m->match_type = TABLE_ARRAY;
2015 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2016 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2023 if (strcmp(tokens[1], "hash") == 0) {
2025 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2029 m->match_type = TABLE_HASH;
2031 if (strcmp(tokens[2], "raw") == 0) {
2032 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2035 snprintf(out, out_size, MSG_ARG_MISMATCH,
2040 if (softnic_parse_hex_string(tokens[3],
2041 m->match.hash.key, &key_size) != 0) {
2042 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2049 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2050 struct pkt_key_ipv4_5tuple *ipv4 =
2051 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2052 struct in_addr saddr, daddr;
2057 snprintf(out, out_size, MSG_ARG_MISMATCH,
2062 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2063 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2067 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2068 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2072 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2073 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2077 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2078 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2082 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2083 snprintf(out, out_size, MSG_ARG_INVALID,
2088 ipv4->sa = saddr.s_addr;
2089 ipv4->da = daddr.s_addr;
2090 ipv4->sp = rte_cpu_to_be_16(sp);
2091 ipv4->dp = rte_cpu_to_be_16(dp);
2092 ipv4->proto = proto;
2095 } /* hash ipv4_5tuple */
2097 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2098 struct pkt_key_ipv6_5tuple *ipv6 =
2099 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2100 struct in6_addr saddr, daddr;
2105 snprintf(out, out_size, MSG_ARG_MISMATCH,
2110 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2111 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2115 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2116 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2120 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2121 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2125 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2126 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2130 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2131 snprintf(out, out_size, MSG_ARG_INVALID,
2136 memcpy(ipv6->sa, saddr.s6_addr, 16);
2137 memcpy(ipv6->da, daddr.s6_addr, 16);
2138 ipv6->sp = rte_cpu_to_be_16(sp);
2139 ipv6->dp = rte_cpu_to_be_16(dp);
2140 ipv6->proto = proto;
2143 } /* hash ipv6_5tuple */
2145 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2146 struct pkt_key_ipv4_addr *ipv4_addr =
2147 (struct pkt_key_ipv4_addr *)m->match.hash.key;
2148 struct in_addr addr;
2151 snprintf(out, out_size, MSG_ARG_MISMATCH,
2156 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2157 snprintf(out, out_size, MSG_ARG_INVALID,
2162 ipv4_addr->addr = addr.s_addr;
2165 } /* hash ipv4_addr */
2167 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2168 struct pkt_key_ipv6_addr *ipv6_addr =
2169 (struct pkt_key_ipv6_addr *)m->match.hash.key;
2170 struct in6_addr addr;
2173 snprintf(out, out_size, MSG_ARG_MISMATCH,
2178 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2179 snprintf(out, out_size, MSG_ARG_INVALID,
2184 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2187 } /* hash ipv6_5tuple */
2189 if (strcmp(tokens[2], "qinq") == 0) {
2190 struct pkt_key_qinq *qinq =
2191 (struct pkt_key_qinq *)m->match.hash.key;
2192 uint16_t svlan, cvlan;
2195 snprintf(out, out_size, MSG_ARG_MISMATCH,
2200 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
2202 snprintf(out, out_size, MSG_ARG_INVALID,
2207 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2209 snprintf(out, out_size, MSG_ARG_INVALID,
2214 qinq->svlan = rte_cpu_to_be_16(svlan);
2215 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2220 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2224 if (strcmp(tokens[1], "lpm") == 0) {
2226 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2230 m->match_type = TABLE_LPM;
2232 if (strcmp(tokens[2], "ipv4") == 0) {
2233 struct in_addr addr;
2235 m->match.lpm.ip_version = 1;
2237 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2238 snprintf(out, out_size, MSG_ARG_INVALID,
2243 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2244 } else if (strcmp(tokens[2], "ipv6") == 0) {
2245 struct in6_addr addr;
2247 m->match.lpm.ip_version = 0;
2249 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2250 snprintf(out, out_size, MSG_ARG_INVALID,
2255 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2257 snprintf(out, out_size, MSG_ARG_MISMATCH,
2262 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2263 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2270 snprintf(out, out_size, MSG_ARG_MISMATCH,
2271 "acl or array or hash or lpm");
2283 * | table <table_id>
2284 * [balance <out0> ... <out7>]
2286 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2287 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2288 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2289 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2290 * [tm subport <subport_id> pipe <pipe_id>]
2293 * | vlan <da> <sa> <pcp> <dei> <vid>
2294 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2295 * | mpls unicast | multicast
2297 * label0 <label> <tc> <ttl>
2298 * [label1 <label> <tc> <ttl>
2299 * [label2 <label> <tc> <ttl>
2300 * [label3 <label> <tc> <ttl>]]]
2301 * | pppoe <da> <sa> <session_id>]
2302 * [nat ipv4 | ipv6 <addr> <port>]
2308 * <pa> ::= g | y | r | drop
2311 parse_table_action_fwd(char **tokens,
2313 struct softnic_table_rule_action *a)
2315 if (n_tokens == 0 ||
2316 (strcmp(tokens[0], "fwd") != 0))
2322 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2323 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2324 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2328 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2332 softnic_parser_read_uint32(&id, tokens[1]))
2335 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2337 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2341 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2342 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2343 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2347 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2351 softnic_parser_read_uint32(&id, tokens[1]))
2354 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2356 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2364 parse_table_action_balance(char **tokens,
2366 struct softnic_table_rule_action *a)
2370 if (n_tokens == 0 ||
2371 (strcmp(tokens[0], "balance") != 0))
2377 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2380 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2381 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2384 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2385 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2389 parse_policer_action(char *token, enum rte_table_action_policer *a)
2391 if (strcmp(token, "g") == 0) {
2392 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2396 if (strcmp(token, "y") == 0) {
2397 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2401 if (strcmp(token, "r") == 0) {
2402 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2406 if (strcmp(token, "drop") == 0) {
2407 *a = RTE_TABLE_ACTION_POLICER_DROP;
2415 parse_table_action_meter_tc(char **tokens,
2417 struct rte_table_action_mtr_tc_params *mtr)
2420 strcmp(tokens[0], "meter") ||
2421 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2422 strcmp(tokens[2], "policer") ||
2423 strcmp(tokens[3], "g") ||
2424 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2425 strcmp(tokens[5], "y") ||
2426 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2427 strcmp(tokens[7], "r") ||
2428 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2435 parse_table_action_meter(char **tokens,
2437 struct softnic_table_rule_action *a)
2439 if (n_tokens == 0 ||
2440 strcmp(tokens[0], "meter"))
2446 if (n_tokens < 10 ||
2447 strcmp(tokens[0], "tc0") ||
2448 (parse_table_action_meter_tc(tokens + 1,
2450 &a->mtr.mtr[0]) == 0))
2456 if (n_tokens == 0 ||
2457 strcmp(tokens[0], "tc1")) {
2459 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2463 if (n_tokens < 30 ||
2464 (parse_table_action_meter_tc(tokens + 1,
2465 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
2466 strcmp(tokens[10], "tc2") ||
2467 (parse_table_action_meter_tc(tokens + 11,
2468 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
2469 strcmp(tokens[20], "tc3") ||
2470 (parse_table_action_meter_tc(tokens + 21,
2471 n_tokens - 21, &a->mtr.mtr[3]) == 0))
2474 a->mtr.tc_mask = 0xF;
2475 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2476 return 1 + 10 + 3 * 10;
2480 parse_table_action_tm(char **tokens,
2482 struct softnic_table_rule_action *a)
2484 uint32_t subport_id, pipe_id;
2487 strcmp(tokens[0], "tm") ||
2488 strcmp(tokens[1], "subport") ||
2489 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
2490 strcmp(tokens[3], "pipe") ||
2491 softnic_parser_read_uint32(&pipe_id, tokens[4]))
2494 a->tm.subport_id = subport_id;
2495 a->tm.pipe_id = pipe_id;
2496 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
2501 parse_table_action_encap(char **tokens,
2503 struct softnic_table_rule_action *a)
2505 if (n_tokens == 0 ||
2506 strcmp(tokens[0], "encap"))
2513 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
2515 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
2516 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
2519 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
2520 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2525 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
2526 uint32_t pcp, dei, vid;
2529 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
2530 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
2531 softnic_parser_read_uint32(&pcp, tokens[3]) ||
2533 softnic_parser_read_uint32(&dei, tokens[4]) ||
2535 softnic_parser_read_uint32(&vid, tokens[5]) ||
2539 a->encap.vlan.vlan.pcp = pcp & 0x7;
2540 a->encap.vlan.vlan.dei = dei & 0x1;
2541 a->encap.vlan.vlan.vid = vid & 0xFFF;
2542 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
2543 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2548 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
2549 uint32_t svlan_pcp, svlan_dei, svlan_vid;
2550 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
2553 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
2554 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
2555 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
2557 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
2559 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
2560 svlan_vid > 0xFFF ||
2561 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
2563 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
2565 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
2569 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
2570 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
2571 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
2572 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
2573 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
2574 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
2575 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
2576 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2581 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
2582 uint32_t label, tc, ttl;
2587 if (strcmp(tokens[1], "unicast") == 0)
2588 a->encap.mpls.unicast = 1;
2589 else if (strcmp(tokens[1], "multicast") == 0)
2590 a->encap.mpls.unicast = 0;
2594 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
2595 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
2596 strcmp(tokens[4], "label0") ||
2597 softnic_parser_read_uint32(&label, tokens[5]) ||
2599 softnic_parser_read_uint32(&tc, tokens[6]) ||
2601 softnic_parser_read_uint32(&ttl, tokens[7]) ||
2605 a->encap.mpls.mpls[0].label = label;
2606 a->encap.mpls.mpls[0].tc = tc;
2607 a->encap.mpls.mpls[0].ttl = ttl;
2612 if (n_tokens == 0 ||
2613 strcmp(tokens[0], "label1")) {
2614 a->encap.mpls.mpls_count = 1;
2615 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2616 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2621 softnic_parser_read_uint32(&label, tokens[1]) ||
2623 softnic_parser_read_uint32(&tc, tokens[2]) ||
2625 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2629 a->encap.mpls.mpls[1].label = label;
2630 a->encap.mpls.mpls[1].tc = tc;
2631 a->encap.mpls.mpls[1].ttl = ttl;
2636 if (n_tokens == 0 ||
2637 strcmp(tokens[0], "label2")) {
2638 a->encap.mpls.mpls_count = 2;
2639 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2640 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2645 softnic_parser_read_uint32(&label, tokens[1]) ||
2647 softnic_parser_read_uint32(&tc, tokens[2]) ||
2649 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2653 a->encap.mpls.mpls[2].label = label;
2654 a->encap.mpls.mpls[2].tc = tc;
2655 a->encap.mpls.mpls[2].ttl = ttl;
2660 if (n_tokens == 0 ||
2661 strcmp(tokens[0], "label3")) {
2662 a->encap.mpls.mpls_count = 3;
2663 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2664 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2665 return 1 + 8 + 4 + 4;
2669 softnic_parser_read_uint32(&label, tokens[1]) ||
2671 softnic_parser_read_uint32(&tc, tokens[2]) ||
2673 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2677 a->encap.mpls.mpls[3].label = label;
2678 a->encap.mpls.mpls[3].tc = tc;
2679 a->encap.mpls.mpls[3].ttl = ttl;
2681 a->encap.mpls.mpls_count = 4;
2682 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2683 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2684 return 1 + 8 + 4 + 4 + 4;
2688 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
2690 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
2691 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
2692 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
2696 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
2697 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2705 parse_table_action_nat(char **tokens,
2707 struct softnic_table_rule_action *a)
2710 strcmp(tokens[0], "nat"))
2713 if (strcmp(tokens[1], "ipv4") == 0) {
2714 struct in_addr addr;
2717 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
2718 softnic_parser_read_uint16(&port, tokens[3]))
2721 a->nat.ip_version = 1;
2722 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2724 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2728 if (strcmp(tokens[1], "ipv6") == 0) {
2729 struct in6_addr addr;
2732 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
2733 softnic_parser_read_uint16(&port, tokens[3]))
2736 a->nat.ip_version = 0;
2737 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
2739 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2747 parse_table_action_ttl(char **tokens,
2749 struct softnic_table_rule_action *a)
2752 strcmp(tokens[0], "ttl"))
2755 if (strcmp(tokens[1], "dec") == 0)
2756 a->ttl.decrement = 1;
2757 else if (strcmp(tokens[1], "keep") == 0)
2758 a->ttl.decrement = 0;
2762 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
2767 parse_table_action_stats(char **tokens,
2769 struct softnic_table_rule_action *a)
2772 strcmp(tokens[0], "stats"))
2775 a->stats.n_packets = 0;
2776 a->stats.n_bytes = 0;
2777 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
2782 parse_table_action_time(char **tokens,
2784 struct softnic_table_rule_action *a)
2787 strcmp(tokens[0], "time"))
2790 a->time.time = rte_rdtsc();
2791 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
2796 parse_table_action(char **tokens,
2800 struct softnic_table_rule_action *a)
2802 uint32_t n_tokens0 = n_tokens;
2804 memset(a, 0, sizeof(*a));
2807 strcmp(tokens[0], "action"))
2813 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
2816 n = parse_table_action_fwd(tokens, n_tokens, a);
2818 snprintf(out, out_size, MSG_ARG_INVALID,
2827 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
2830 n = parse_table_action_balance(tokens, n_tokens, a);
2832 snprintf(out, out_size, MSG_ARG_INVALID,
2841 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
2844 n = parse_table_action_meter(tokens, n_tokens, a);
2846 snprintf(out, out_size, MSG_ARG_INVALID,
2855 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
2858 n = parse_table_action_tm(tokens, n_tokens, a);
2860 snprintf(out, out_size, MSG_ARG_INVALID,
2869 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
2872 n = parse_table_action_encap(tokens, n_tokens, a);
2874 snprintf(out, out_size, MSG_ARG_INVALID,
2883 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
2886 n = parse_table_action_nat(tokens, n_tokens, a);
2888 snprintf(out, out_size, MSG_ARG_INVALID,
2897 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
2900 n = parse_table_action_ttl(tokens, n_tokens, a);
2902 snprintf(out, out_size, MSG_ARG_INVALID,
2911 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
2914 n = parse_table_action_stats(tokens, n_tokens, a);
2916 snprintf(out, out_size, MSG_ARG_INVALID,
2925 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
2928 n = parse_table_action_time(tokens, n_tokens, a);
2930 snprintf(out, out_size, MSG_ARG_INVALID,
2939 if (n_tokens0 - n_tokens == 1) {
2940 snprintf(out, out_size, MSG_ARG_INVALID, "action");
2944 return n_tokens0 - n_tokens;
2948 * pipeline <pipeline_name> table <table_id> rule add
2950 * action <table_action>
2953 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
2959 struct softnic_table_rule_match m;
2960 struct softnic_table_rule_action a;
2961 char *pipeline_name;
2963 uint32_t table_id, t0, n_tokens_parsed;
2967 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2971 pipeline_name = tokens[1];
2973 if (strcmp(tokens[2], "table") != 0) {
2974 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2978 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2979 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2983 if (strcmp(tokens[4], "rule") != 0) {
2984 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
2988 if (strcmp(tokens[5], "add") != 0) {
2989 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2996 n_tokens_parsed = parse_match(tokens + t0,
3001 if (n_tokens_parsed == 0)
3003 t0 += n_tokens_parsed;
3006 n_tokens_parsed = parse_table_action(tokens + t0,
3011 if (n_tokens_parsed == 0)
3013 t0 += n_tokens_parsed;
3015 if (t0 != n_tokens) {
3016 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3020 status = softnic_pipeline_table_rule_add(softnic,
3027 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3033 * pipeline <pipeline_name> table <table_id> rule add
3041 * | table <table_id>
3044 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3050 struct softnic_table_rule_action action;
3052 char *pipeline_name;
3056 if (n_tokens != 11 &&
3058 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3062 pipeline_name = tokens[1];
3064 if (strcmp(tokens[2], "table") != 0) {
3065 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3069 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3070 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3074 if (strcmp(tokens[4], "rule") != 0) {
3075 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3079 if (strcmp(tokens[5], "add") != 0) {
3080 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3084 if (strcmp(tokens[6], "match") != 0) {
3085 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3089 if (strcmp(tokens[7], "default") != 0) {
3090 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3094 if (strcmp(tokens[8], "action") != 0) {
3095 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3099 if (strcmp(tokens[9], "fwd") != 0) {
3100 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3104 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3106 if (strcmp(tokens[10], "drop") == 0) {
3107 if (n_tokens != 11) {
3108 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3112 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3113 } else if (strcmp(tokens[10], "port") == 0) {
3116 if (n_tokens != 12) {
3117 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3121 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3122 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3126 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3128 } else if (strcmp(tokens[10], "meta") == 0) {
3129 if (n_tokens != 11) {
3130 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3134 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3135 } else if (strcmp(tokens[10], "table") == 0) {
3138 if (n_tokens != 12) {
3139 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3143 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3144 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3148 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3151 snprintf(out, out_size, MSG_ARG_INVALID,
3152 "drop or port or meta or table");
3156 status = softnic_pipeline_table_rule_add_default(softnic,
3162 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3168 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
3171 * - line format: match <match> action <action>
3174 cli_rule_file_process(const char *file_name,
3175 size_t line_len_max,
3176 struct softnic_table_rule_match *m,
3177 struct softnic_table_rule_action *a,
3179 uint32_t *line_number,
3184 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
3190 struct softnic_table_rule_match *match;
3191 struct softnic_table_rule_action *action;
3193 char *pipeline_name, *file_name;
3194 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3197 if (n_tokens != 9) {
3198 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3202 pipeline_name = tokens[1];
3204 if (strcmp(tokens[2], "table") != 0) {
3205 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3209 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3210 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3214 if (strcmp(tokens[4], "rule") != 0) {
3215 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3219 if (strcmp(tokens[5], "add") != 0) {
3220 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3224 if (strcmp(tokens[6], "bulk") != 0) {
3225 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3229 file_name = tokens[7];
3231 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3233 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3237 /* Memory allocation. */
3238 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
3239 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
3240 data = calloc(n_rules, sizeof(void *));
3241 if (match == NULL ||
3244 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3251 /* Load rule file */
3252 n_rules_parsed = n_rules;
3253 status = cli_rule_file_process(file_name,
3262 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3268 if (n_rules_parsed != n_rules) {
3269 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3277 status = softnic_pipeline_table_rule_add_bulk(softnic,
3285 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3299 * pipeline <pipeline_name> table <table_id> rule delete
3303 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
3309 struct softnic_table_rule_match m;
3310 char *pipeline_name;
3311 uint32_t table_id, n_tokens_parsed, t0;
3315 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3319 pipeline_name = tokens[1];
3321 if (strcmp(tokens[2], "table") != 0) {
3322 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3326 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3327 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3331 if (strcmp(tokens[4], "rule") != 0) {
3332 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3336 if (strcmp(tokens[5], "delete") != 0) {
3337 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3344 n_tokens_parsed = parse_match(tokens + t0,
3349 if (n_tokens_parsed == 0)
3351 t0 += n_tokens_parsed;
3353 if (n_tokens != t0) {
3354 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3358 status = softnic_pipeline_table_rule_delete(softnic,
3363 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3369 * pipeline <pipeline_name> table <table_id> rule delete
3374 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
3380 char *pipeline_name;
3384 if (n_tokens != 8) {
3385 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3389 pipeline_name = tokens[1];
3391 if (strcmp(tokens[2], "table") != 0) {
3392 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3396 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3397 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3401 if (strcmp(tokens[4], "rule") != 0) {
3402 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3406 if (strcmp(tokens[5], "delete") != 0) {
3407 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3411 if (strcmp(tokens[6], "match") != 0) {
3412 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3416 if (strcmp(tokens[7], "default") != 0) {
3417 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3421 status = softnic_pipeline_table_rule_delete_default(softnic,
3425 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3431 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
3434 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
3436 uint32_t n_tokens __rte_unused,
3440 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3444 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
3445 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
3446 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
3449 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
3455 struct rte_table_action_meter_profile p;
3456 char *pipeline_name;
3457 uint32_t table_id, meter_profile_id;
3461 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3465 pipeline_name = tokens[1];
3467 if (strcmp(tokens[2], "table") != 0) {
3468 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3472 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3473 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3477 if (strcmp(tokens[4], "meter") != 0) {
3478 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3482 if (strcmp(tokens[5], "profile") != 0) {
3483 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3487 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3488 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3492 if (strcmp(tokens[7], "add") != 0) {
3493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3497 if (strcmp(tokens[8], "srtcm") == 0) {
3498 if (n_tokens != 15) {
3499 snprintf(out, out_size, MSG_ARG_MISMATCH,
3504 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
3506 if (strcmp(tokens[9], "cir") != 0) {
3507 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3511 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
3512 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3516 if (strcmp(tokens[11], "cbs") != 0) {
3517 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3521 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
3522 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3526 if (strcmp(tokens[13], "ebs") != 0) {
3527 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
3531 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
3532 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
3535 } else if (strcmp(tokens[8], "trtcm") == 0) {
3536 if (n_tokens != 17) {
3537 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3541 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
3543 if (strcmp(tokens[9], "cir") != 0) {
3544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3548 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
3549 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3553 if (strcmp(tokens[11], "pir") != 0) {
3554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
3558 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
3559 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
3562 if (strcmp(tokens[13], "cbs") != 0) {
3563 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3567 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
3568 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3572 if (strcmp(tokens[15], "pbs") != 0) {
3573 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
3577 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
3578 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
3582 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3586 status = softnic_pipeline_table_mtr_profile_add(softnic,
3592 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3598 * pipeline <pipeline_name> table <table_id>
3599 * meter profile <meter_profile_id> delete
3602 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
3608 char *pipeline_name;
3609 uint32_t table_id, meter_profile_id;
3612 if (n_tokens != 8) {
3613 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3617 pipeline_name = tokens[1];
3619 if (strcmp(tokens[2], "table") != 0) {
3620 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3624 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3625 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3629 if (strcmp(tokens[4], "meter") != 0) {
3630 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3634 if (strcmp(tokens[5], "profile") != 0) {
3635 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3639 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3640 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3644 if (strcmp(tokens[7], "delete") != 0) {
3645 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3649 status = softnic_pipeline_table_mtr_profile_delete(softnic,
3654 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3660 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
3663 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
3665 uint32_t n_tokens __rte_unused,
3669 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3673 * pipeline <pipeline_name> table <table_id> dscp <file_name>
3676 * - exactly 64 lines
3677 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
3680 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
3681 const char *file_name,
3682 uint32_t *line_number)
3687 /* Check input arguments */
3688 if (dscp_table == NULL ||
3689 file_name == NULL ||
3690 line_number == NULL) {
3696 /* Open input file */
3697 f = fopen(file_name, "r");
3704 for (dscp = 0, l = 1; ; l++) {
3707 enum rte_meter_color color;
3708 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
3710 if (fgets(line, sizeof(line), f) == NULL)
3713 if (is_comment(line))
3716 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
3725 if (dscp >= RTE_DIM(dscp_table->entry) ||
3726 n_tokens != RTE_DIM(tokens) ||
3727 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
3728 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
3729 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
3730 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
3731 (strlen(tokens[2]) != 1)) {
3737 switch (tokens[2][0]) {
3740 color = e_RTE_METER_GREEN;
3745 color = e_RTE_METER_YELLOW;
3750 color = e_RTE_METER_RED;
3759 dscp_table->entry[dscp].tc_id = tc_id;
3760 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
3761 dscp_table->entry[dscp].color = color;
3771 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
3777 struct rte_table_action_dscp_table dscp_table;
3778 char *pipeline_name, *file_name;
3779 uint32_t table_id, line_number;
3782 if (n_tokens != 6) {
3783 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3787 pipeline_name = tokens[1];
3789 if (strcmp(tokens[2], "table") != 0) {
3790 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3794 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3795 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3799 if (strcmp(tokens[4], "dscp") != 0) {
3800 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
3804 file_name = tokens[5];
3806 status = load_dscp_table(&dscp_table, file_name, &line_number);
3808 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3812 status = softnic_pipeline_table_dscp_table_update(softnic,
3818 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3824 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
3827 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
3829 uint32_t n_tokens __rte_unused,
3833 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3837 * thread <thread_id> pipeline <pipeline_name> enable
3840 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
3846 char *pipeline_name;
3850 if (n_tokens != 5) {
3851 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3855 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
3856 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
3860 if (strcmp(tokens[2], "pipeline") != 0) {
3861 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
3865 pipeline_name = tokens[3];
3867 if (strcmp(tokens[4], "enable") != 0) {
3868 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
3872 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
3874 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
3880 * thread <thread_id> pipeline <pipeline_name> disable
3883 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
3889 char *pipeline_name;
3893 if (n_tokens != 5) {
3894 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3898 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
3899 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
3903 if (strcmp(tokens[2], "pipeline") != 0) {
3904 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
3908 pipeline_name = tokens[3];
3910 if (strcmp(tokens[4], "disable") != 0) {
3911 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
3915 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
3917 snprintf(out, out_size, MSG_CMD_FAIL,
3918 "thread pipeline disable");
3924 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
3926 char *tokens[CMD_MAX_TOKENS];
3927 uint32_t n_tokens = RTE_DIM(tokens);
3928 struct pmd_internals *softnic = arg;
3934 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
3936 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
3943 if (strcmp(tokens[0], "mempool") == 0) {
3944 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
3948 if (strcmp(tokens[0], "link") == 0) {
3949 cmd_link(softnic, tokens, n_tokens, out, out_size);
3953 if (strcmp(tokens[0], "swq") == 0) {
3954 cmd_swq(softnic, tokens, n_tokens, out, out_size);
3958 if (strcmp(tokens[0], "tap") == 0) {
3959 cmd_tap(softnic, tokens, n_tokens, out, out_size);
3963 if (strcmp(tokens[0], "port") == 0) {
3964 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
3968 if (strcmp(tokens[0], "table") == 0) {
3969 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
3973 if (strcmp(tokens[0], "pipeline") == 0) {
3974 if (n_tokens >= 3 &&
3975 (strcmp(tokens[2], "period") == 0)) {
3976 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
3980 if (n_tokens >= 5 &&
3981 (strcmp(tokens[2], "port") == 0) &&
3982 (strcmp(tokens[3], "in") == 0) &&
3983 (strcmp(tokens[4], "bsz") == 0)) {
3984 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
3988 if (n_tokens >= 5 &&
3989 (strcmp(tokens[2], "port") == 0) &&
3990 (strcmp(tokens[3], "out") == 0) &&
3991 (strcmp(tokens[4], "bsz") == 0)) {
3992 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
3996 if (n_tokens >= 4 &&
3997 (strcmp(tokens[2], "table") == 0) &&
3998 (strcmp(tokens[3], "match") == 0)) {
3999 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4003 if (n_tokens >= 6 &&
4004 (strcmp(tokens[2], "port") == 0) &&
4005 (strcmp(tokens[3], "in") == 0) &&
4006 (strcmp(tokens[5], "table") == 0)) {
4007 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4012 if (n_tokens >= 6 &&
4013 (strcmp(tokens[2], "port") == 0) &&
4014 (strcmp(tokens[3], "in") == 0) &&
4015 (strcmp(tokens[5], "stats") == 0)) {
4016 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4021 if (n_tokens >= 6 &&
4022 (strcmp(tokens[2], "port") == 0) &&
4023 (strcmp(tokens[3], "in") == 0) &&
4024 (strcmp(tokens[5], "enable") == 0)) {
4025 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4030 if (n_tokens >= 6 &&
4031 (strcmp(tokens[2], "port") == 0) &&
4032 (strcmp(tokens[3], "in") == 0) &&
4033 (strcmp(tokens[5], "disable") == 0)) {
4034 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4039 if (n_tokens >= 6 &&
4040 (strcmp(tokens[2], "port") == 0) &&
4041 (strcmp(tokens[3], "out") == 0) &&
4042 (strcmp(tokens[5], "stats") == 0)) {
4043 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4048 if (n_tokens >= 5 &&
4049 (strcmp(tokens[2], "table") == 0) &&
4050 (strcmp(tokens[4], "stats") == 0)) {
4051 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4056 if (n_tokens >= 7 &&
4057 (strcmp(tokens[2], "table") == 0) &&
4058 (strcmp(tokens[4], "rule") == 0) &&
4059 (strcmp(tokens[5], "add") == 0) &&
4060 (strcmp(tokens[6], "match") == 0)) {
4061 if (n_tokens >= 8 &&
4062 (strcmp(tokens[7], "default") == 0)) {
4063 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4064 n_tokens, out, out_size);
4068 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4073 if (n_tokens >= 7 &&
4074 (strcmp(tokens[2], "table") == 0) &&
4075 (strcmp(tokens[4], "rule") == 0) &&
4076 (strcmp(tokens[5], "add") == 0) &&
4077 (strcmp(tokens[6], "bulk") == 0)) {
4078 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4079 n_tokens, out, out_size);
4083 if (n_tokens >= 7 &&
4084 (strcmp(tokens[2], "table") == 0) &&
4085 (strcmp(tokens[4], "rule") == 0) &&
4086 (strcmp(tokens[5], "delete") == 0) &&
4087 (strcmp(tokens[6], "match") == 0)) {
4088 if (n_tokens >= 8 &&
4089 (strcmp(tokens[7], "default") == 0)) {
4090 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
4091 n_tokens, out, out_size);
4095 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
4100 if (n_tokens >= 7 &&
4101 (strcmp(tokens[2], "table") == 0) &&
4102 (strcmp(tokens[4], "rule") == 0) &&
4103 (strcmp(tokens[5], "read") == 0) &&
4104 (strcmp(tokens[6], "stats") == 0)) {
4105 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
4110 if (n_tokens >= 8 &&
4111 (strcmp(tokens[2], "table") == 0) &&
4112 (strcmp(tokens[4], "meter") == 0) &&
4113 (strcmp(tokens[5], "profile") == 0) &&
4114 (strcmp(tokens[7], "add") == 0)) {
4115 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
4120 if (n_tokens >= 8 &&
4121 (strcmp(tokens[2], "table") == 0) &&
4122 (strcmp(tokens[4], "meter") == 0) &&
4123 (strcmp(tokens[5], "profile") == 0) &&
4124 (strcmp(tokens[7], "delete") == 0)) {
4125 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
4126 n_tokens, out, out_size);
4130 if (n_tokens >= 7 &&
4131 (strcmp(tokens[2], "table") == 0) &&
4132 (strcmp(tokens[4], "rule") == 0) &&
4133 (strcmp(tokens[5], "read") == 0) &&
4134 (strcmp(tokens[6], "meter") == 0)) {
4135 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
4140 if (n_tokens >= 5 &&
4141 (strcmp(tokens[2], "table") == 0) &&
4142 (strcmp(tokens[4], "dscp") == 0)) {
4143 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
4148 if (n_tokens >= 7 &&
4149 (strcmp(tokens[2], "table") == 0) &&
4150 (strcmp(tokens[4], "rule") == 0) &&
4151 (strcmp(tokens[5], "read") == 0) &&
4152 (strcmp(tokens[6], "ttl") == 0)) {
4153 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
4159 if (strcmp(tokens[0], "thread") == 0) {
4160 if (n_tokens >= 5 &&
4161 (strcmp(tokens[4], "enable") == 0)) {
4162 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
4167 if (n_tokens >= 5 &&
4168 (strcmp(tokens[4], "disable") == 0)) {
4169 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
4175 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
4179 softnic_cli_script_process(struct pmd_internals *softnic,
4180 const char *file_name,
4181 size_t msg_in_len_max,
4182 size_t msg_out_len_max)
4184 char *msg_in = NULL, *msg_out = NULL;
4187 /* Check input arguments */
4188 if (file_name == NULL ||
4189 (strlen(file_name) == 0) ||
4190 msg_in_len_max == 0 ||
4191 msg_out_len_max == 0)
4194 msg_in = malloc(msg_in_len_max + 1);
4195 msg_out = malloc(msg_out_len_max + 1);
4196 if (msg_in == NULL ||
4203 /* Open input file */
4204 f = fopen(file_name, "r");
4213 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
4216 printf("%s", msg_in);
4219 softnic_cli_process(msg_in,
4224 if (strlen(msg_out))
4225 printf("%s", msg_out);
4236 cli_rule_file_process(const char *file_name,
4237 size_t line_len_max,
4238 struct softnic_table_rule_match *m,
4239 struct softnic_table_rule_action *a,
4241 uint32_t *line_number,
4247 uint32_t rule_id, line_id;
4250 /* Check input arguments */
4251 if (file_name == NULL ||
4252 (strlen(file_name) == 0) ||
4253 line_len_max == 0) {
4258 /* Memory allocation */
4259 line = malloc(line_len_max + 1);
4266 f = fopen(file_name, "r");
4274 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
4275 char *tokens[CMD_MAX_TOKENS];
4276 uint32_t n_tokens, n_tokens_parsed, t0;
4278 /* Read next line from file. */
4279 if (fgets(line, line_len_max + 1, f) == NULL)
4283 if (is_comment(line))
4287 n_tokens = RTE_DIM(tokens);
4288 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
4300 n_tokens_parsed = parse_match(tokens + t0,
4305 if (n_tokens_parsed == 0) {
4309 t0 += n_tokens_parsed;
4312 n_tokens_parsed = parse_table_action(tokens + t0,
4317 if (n_tokens_parsed == 0) {
4321 t0 += n_tokens_parsed;
4323 /* Line completed. */
4324 if (t0 < n_tokens) {
4329 /* Increment rule count */
4340 *line_number = line_id;