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_tmgr(struct pmd_internals *softnic,
198 struct softnic_tmgr_port *tmgr_port;
201 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
207 tmgr_port = softnic_tmgr_port_create(softnic, name);
208 if (tmgr_port == NULL) {
209 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
218 cmd_tap(struct pmd_internals *softnic,
225 struct softnic_tap *tap;
228 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
234 tap = softnic_tap_create(softnic, name);
236 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
242 * port in action profile <profile_name>
243 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
244 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
247 cmd_port_in_action_profile(struct pmd_internals *softnic,
253 struct softnic_port_in_action_profile_params p;
254 struct softnic_port_in_action_profile *ap;
258 memset(&p, 0, sizeof(p));
261 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
265 if (strcmp(tokens[1], "in") != 0) {
266 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
270 if (strcmp(tokens[2], "action") != 0) {
271 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
275 if (strcmp(tokens[3], "profile") != 0) {
276 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
285 (strcmp(tokens[t0], "filter") == 0)) {
288 if (n_tokens < t0 + 10) {
289 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
293 if (strcmp(tokens[t0 + 1], "match") == 0) {
294 p.fltr.filter_on_match = 1;
295 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
296 p.fltr.filter_on_match = 0;
298 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
302 if (strcmp(tokens[t0 + 2], "offset") != 0) {
303 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
307 if (softnic_parser_read_uint32(&p.fltr.key_offset,
308 tokens[t0 + 3]) != 0) {
309 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
313 if (strcmp(tokens[t0 + 4], "mask") != 0) {
314 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
318 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
319 if ((softnic_parse_hex_string(tokens[t0 + 5],
320 p.fltr.key_mask, &size) != 0) ||
321 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
322 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
326 if (strcmp(tokens[t0 + 6], "key") != 0) {
327 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
331 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
332 if ((softnic_parse_hex_string(tokens[t0 + 7],
333 p.fltr.key, &size) != 0) ||
334 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
335 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
339 if (strcmp(tokens[t0 + 8], "port") != 0) {
340 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
344 if (softnic_parser_read_uint32(&p.fltr.port_id,
345 tokens[t0 + 9]) != 0) {
346 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
350 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
355 (strcmp(tokens[t0], "balance") == 0)) {
358 if (n_tokens < t0 + 22) {
359 snprintf(out, out_size, MSG_ARG_MISMATCH,
360 "port in action profile balance");
364 if (strcmp(tokens[t0 + 1], "offset") != 0) {
365 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
369 if (softnic_parser_read_uint32(&p.lb.key_offset,
370 tokens[t0 + 2]) != 0) {
371 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
375 if (strcmp(tokens[t0 + 3], "mask") != 0) {
376 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
380 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
381 if (softnic_parse_hex_string(tokens[t0 + 4],
382 p.lb.key_mask, &p.lb.key_size) != 0) {
383 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
387 if (strcmp(tokens[t0 + 5], "port") != 0) {
388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
392 for (i = 0; i < 16; i++)
393 if (softnic_parser_read_uint32(&p.lb.port_id[i],
394 tokens[t0 + 6 + i]) != 0) {
395 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
399 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
404 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
408 ap = softnic_port_in_action_profile_create(softnic, name, &p);
410 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
416 * table action profile <profile_name>
420 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
421 * [meter srtcm | trtcm
423 * stats none | pkts | bytes | both]
424 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
425 * [encap ether | vlan | qinq | mpls | pppoe]
430 * [stats pkts | bytes | both]
434 cmd_table_action_profile(struct pmd_internals *softnic,
440 struct softnic_table_action_profile_params p;
441 struct softnic_table_action_profile *ap;
445 memset(&p, 0, sizeof(p));
448 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
452 if (strcmp(tokens[1], "action") != 0) {
453 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
457 if (strcmp(tokens[2], "profile") != 0) {
458 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
464 if (strcmp(tokens[4], "ipv4") == 0) {
465 p.common.ip_version = 1;
466 } else if (strcmp(tokens[4], "ipv6") == 0) {
467 p.common.ip_version = 0;
469 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
473 if (strcmp(tokens[5], "offset") != 0) {
474 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
478 if (softnic_parser_read_uint32(&p.common.ip_offset,
480 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
484 if (strcmp(tokens[7], "fwd") != 0) {
485 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
489 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
493 (strcmp(tokens[t0], "balance") == 0)) {
494 if (n_tokens < t0 + 7) {
495 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
499 if (strcmp(tokens[t0 + 1], "offset") != 0) {
500 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
504 if (softnic_parser_read_uint32(&p.lb.key_offset,
505 tokens[t0 + 2]) != 0) {
506 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
510 if (strcmp(tokens[t0 + 3], "mask") != 0) {
511 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
515 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
516 if (softnic_parse_hex_string(tokens[t0 + 4],
517 p.lb.key_mask, &p.lb.key_size) != 0) {
518 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
522 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
523 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
527 if (softnic_parser_read_uint32(&p.lb.out_offset,
528 tokens[t0 + 6]) != 0) {
529 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
533 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
538 (strcmp(tokens[t0], "meter") == 0)) {
539 if (n_tokens < t0 + 6) {
540 snprintf(out, out_size, MSG_ARG_MISMATCH,
541 "table action profile meter");
545 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
546 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
547 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
548 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
550 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
555 if (strcmp(tokens[t0 + 2], "tc") != 0) {
556 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
560 if (softnic_parser_read_uint32(&p.mtr.n_tc,
561 tokens[t0 + 3]) != 0) {
562 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
566 if (strcmp(tokens[t0 + 4], "stats") != 0) {
567 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
571 if (strcmp(tokens[t0 + 5], "none") == 0) {
572 p.mtr.n_packets_enabled = 0;
573 p.mtr.n_bytes_enabled = 0;
574 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
575 p.mtr.n_packets_enabled = 1;
576 p.mtr.n_bytes_enabled = 0;
577 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
578 p.mtr.n_packets_enabled = 0;
579 p.mtr.n_bytes_enabled = 1;
580 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
581 p.mtr.n_packets_enabled = 1;
582 p.mtr.n_bytes_enabled = 1;
584 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
585 "none or pkts or bytes or both");
589 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
594 (strcmp(tokens[t0], "tm") == 0)) {
595 if (n_tokens < t0 + 5) {
596 snprintf(out, out_size, MSG_ARG_MISMATCH,
597 "table action profile tm");
601 if (strcmp(tokens[t0 + 1], "spp") != 0) {
602 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
606 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
607 tokens[t0 + 2]) != 0) {
608 snprintf(out, out_size, MSG_ARG_INVALID,
609 "n_subports_per_port");
613 if (strcmp(tokens[t0 + 3], "pps") != 0) {
614 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
618 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
619 tokens[t0 + 4]) != 0) {
620 snprintf(out, out_size, MSG_ARG_INVALID,
621 "n_pipes_per_subport");
625 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
630 (strcmp(tokens[t0], "encap") == 0)) {
631 if (n_tokens < t0 + 2) {
632 snprintf(out, out_size, MSG_ARG_MISMATCH,
633 "action profile encap");
637 if (strcmp(tokens[t0 + 1], "ether") == 0) {
638 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
639 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
640 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
641 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
642 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
643 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
644 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
645 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
646 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
648 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
652 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
657 (strcmp(tokens[t0], "nat") == 0)) {
658 if (n_tokens < t0 + 4) {
659 snprintf(out, out_size, MSG_ARG_MISMATCH,
660 "table action profile nat");
664 if (strcmp(tokens[t0 + 1], "src") == 0) {
665 p.nat.source_nat = 1;
666 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
667 p.nat.source_nat = 0;
669 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
674 if (strcmp(tokens[t0 + 2], "proto") != 0) {
675 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
679 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
681 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
684 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
689 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
694 (strcmp(tokens[t0], "ttl") == 0)) {
695 if (n_tokens < t0 + 4) {
696 snprintf(out, out_size, MSG_ARG_MISMATCH,
697 "table action profile ttl");
701 if (strcmp(tokens[t0 + 1], "drop") == 0) {
703 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
706 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
711 if (strcmp(tokens[t0 + 2], "stats") != 0) {
712 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
716 if (strcmp(tokens[t0 + 3], "none") == 0) {
717 p.ttl.n_packets_enabled = 0;
718 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
719 p.ttl.n_packets_enabled = 1;
721 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
726 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
731 (strcmp(tokens[t0], "stats") == 0)) {
732 if (n_tokens < t0 + 2) {
733 snprintf(out, out_size, MSG_ARG_MISMATCH,
734 "table action profile stats");
738 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
739 p.stats.n_packets_enabled = 1;
740 p.stats.n_bytes_enabled = 0;
741 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
742 p.stats.n_packets_enabled = 0;
743 p.stats.n_bytes_enabled = 1;
744 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
745 p.stats.n_packets_enabled = 1;
746 p.stats.n_bytes_enabled = 1;
748 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
749 "pkts or bytes or both");
753 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
758 (strcmp(tokens[t0], "time") == 0)) {
759 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
764 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
768 ap = softnic_table_action_profile_create(softnic, name, &p);
770 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
776 * pipeline <pipeline_name>
777 * period <timer_period_ms>
778 * offset_port_id <offset_port_id>
781 cmd_pipeline(struct pmd_internals *softnic,
787 struct pipeline_params p;
789 struct pipeline *pipeline;
792 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
798 if (strcmp(tokens[2], "period") != 0) {
799 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
803 if (softnic_parser_read_uint32(&p.timer_period_ms,
805 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
809 if (strcmp(tokens[4], "offset_port_id") != 0) {
810 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
814 if (softnic_parser_read_uint32(&p.offset_port_id,
816 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
820 pipeline = softnic_pipeline_create(softnic, name, &p);
821 if (pipeline == NULL) {
822 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
828 * pipeline <pipeline_name> port in
830 * link <link_name> rxq <queue_id>
833 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
834 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
835 * [action <port_in_action_profile_name>]
839 cmd_pipeline_port_in(struct pmd_internals *softnic,
845 struct softnic_port_in_params p;
851 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
855 pipeline_name = tokens[1];
857 if (strcmp(tokens[2], "port") != 0) {
858 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
862 if (strcmp(tokens[3], "in") != 0) {
863 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
867 if (strcmp(tokens[4], "bsz") != 0) {
868 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
872 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
873 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
879 if (strcmp(tokens[t0], "link") == 0) {
880 if (n_tokens < t0 + 4) {
881 snprintf(out, out_size, MSG_ARG_MISMATCH,
882 "pipeline port in link");
886 p.type = PORT_IN_RXQ;
888 p.dev_name = tokens[t0 + 1];
890 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
891 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
895 if (softnic_parser_read_uint16(&p.rxq.queue_id,
896 tokens[t0 + 3]) != 0) {
897 snprintf(out, out_size, MSG_ARG_INVALID,
902 } else if (strcmp(tokens[t0], "swq") == 0) {
903 if (n_tokens < t0 + 2) {
904 snprintf(out, out_size, MSG_ARG_MISMATCH,
905 "pipeline port in swq");
909 p.type = PORT_IN_SWQ;
911 p.dev_name = tokens[t0 + 1];
914 } else if (strcmp(tokens[t0], "tmgr") == 0) {
915 if (n_tokens < t0 + 2) {
916 snprintf(out, out_size, MSG_ARG_MISMATCH,
917 "pipeline port in tmgr");
921 p.type = PORT_IN_TMGR;
923 p.dev_name = tokens[t0 + 1];
926 } else if (strcmp(tokens[t0], "tap") == 0) {
927 if (n_tokens < t0 + 6) {
928 snprintf(out, out_size, MSG_ARG_MISMATCH,
929 "pipeline port in tap");
933 p.type = PORT_IN_TAP;
935 p.dev_name = tokens[t0 + 1];
937 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
938 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
943 p.tap.mempool_name = tokens[t0 + 3];
945 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
946 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
951 if (softnic_parser_read_uint32(&p.tap.mtu,
952 tokens[t0 + 5]) != 0) {
953 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
958 } else if (strcmp(tokens[t0], "source") == 0) {
959 if (n_tokens < t0 + 6) {
960 snprintf(out, out_size, MSG_ARG_MISMATCH,
961 "pipeline port in source");
965 p.type = PORT_IN_SOURCE;
969 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
970 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
975 p.source.mempool_name = tokens[t0 + 2];
977 if (strcmp(tokens[t0 + 3], "file") != 0) {
978 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
983 p.source.file_name = tokens[t0 + 4];
985 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
986 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
991 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
992 tokens[t0 + 6]) != 0) {
993 snprintf(out, out_size, MSG_ARG_INVALID,
1000 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1004 p.action_profile_name = NULL;
1005 if (n_tokens > t0 &&
1006 (strcmp(tokens[t0], "action") == 0)) {
1007 if (n_tokens < t0 + 2) {
1008 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1012 p.action_profile_name = tokens[t0 + 1];
1018 if (n_tokens > t0 &&
1019 (strcmp(tokens[t0], "disabled") == 0)) {
1025 if (n_tokens != t0) {
1026 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1030 status = softnic_pipeline_port_in_create(softnic,
1035 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1041 * pipeline <pipeline_name> port out
1043 * link <link_name> txq <txq_id>
1045 * | tmgr <tmgr_name>
1047 * | sink [file <file_name> pkts <max_n_pkts>]
1050 cmd_pipeline_port_out(struct pmd_internals *softnic,
1056 struct softnic_port_out_params p;
1057 char *pipeline_name;
1060 memset(&p, 0, sizeof(p));
1063 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1067 pipeline_name = tokens[1];
1069 if (strcmp(tokens[2], "port") != 0) {
1070 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1074 if (strcmp(tokens[3], "out") != 0) {
1075 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1079 if (strcmp(tokens[4], "bsz") != 0) {
1080 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1084 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1085 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1089 if (strcmp(tokens[6], "link") == 0) {
1090 if (n_tokens != 10) {
1091 snprintf(out, out_size, MSG_ARG_MISMATCH,
1092 "pipeline port out link");
1096 p.type = PORT_OUT_TXQ;
1098 p.dev_name = tokens[7];
1100 if (strcmp(tokens[8], "txq") != 0) {
1101 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1105 if (softnic_parser_read_uint16(&p.txq.queue_id,
1107 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1110 } else if (strcmp(tokens[6], "swq") == 0) {
1111 if (n_tokens != 8) {
1112 snprintf(out, out_size, MSG_ARG_MISMATCH,
1113 "pipeline port out swq");
1117 p.type = PORT_OUT_SWQ;
1119 p.dev_name = tokens[7];
1120 } else if (strcmp(tokens[6], "tmgr") == 0) {
1121 if (n_tokens != 8) {
1122 snprintf(out, out_size, MSG_ARG_MISMATCH,
1123 "pipeline port out tmgr");
1127 p.type = PORT_OUT_TMGR;
1129 p.dev_name = tokens[7];
1130 } else if (strcmp(tokens[6], "tap") == 0) {
1131 if (n_tokens != 8) {
1132 snprintf(out, out_size, MSG_ARG_MISMATCH,
1133 "pipeline port out tap");
1137 p.type = PORT_OUT_TAP;
1139 p.dev_name = tokens[7];
1140 } else if (strcmp(tokens[6], "sink") == 0) {
1141 if ((n_tokens != 7) && (n_tokens != 11)) {
1142 snprintf(out, out_size, MSG_ARG_MISMATCH,
1143 "pipeline port out sink");
1147 p.type = PORT_OUT_SINK;
1151 if (n_tokens == 7) {
1152 p.sink.file_name = NULL;
1153 p.sink.max_n_pkts = 0;
1155 if (strcmp(tokens[7], "file") != 0) {
1156 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1161 p.sink.file_name = tokens[8];
1163 if (strcmp(tokens[9], "pkts") != 0) {
1164 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1168 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1170 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1175 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1179 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1181 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1187 * pipeline <pipeline_name> table
1191 * offset <ip_header_offset>
1194 * offset <key_offset>
1200 * offset <key_offset>
1201 * buckets <n_buckets>
1205 * offset <ip_header_offset>
1208 * [action <table_action_profile_name>]
1211 cmd_pipeline_table(struct pmd_internals *softnic,
1217 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1218 struct softnic_table_params p;
1219 char *pipeline_name;
1224 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1228 pipeline_name = tokens[1];
1230 if (strcmp(tokens[2], "table") != 0) {
1231 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1235 if (strcmp(tokens[3], "match") != 0) {
1236 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1241 if (strcmp(tokens[t0], "acl") == 0) {
1242 if (n_tokens < t0 + 6) {
1243 snprintf(out, out_size, MSG_ARG_MISMATCH,
1244 "pipeline table acl");
1248 p.match_type = TABLE_ACL;
1250 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1251 p.match.acl.ip_version = 1;
1252 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1253 p.match.acl.ip_version = 0;
1255 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1260 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1261 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1265 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1266 tokens[t0 + 3]) != 0) {
1267 snprintf(out, out_size, MSG_ARG_INVALID,
1268 "ip_header_offset");
1272 if (strcmp(tokens[t0 + 4], "size") != 0) {
1273 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1277 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1278 tokens[t0 + 5]) != 0) {
1279 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1284 } else if (strcmp(tokens[t0], "array") == 0) {
1285 if (n_tokens < t0 + 5) {
1286 snprintf(out, out_size, MSG_ARG_MISMATCH,
1287 "pipeline table array");
1291 p.match_type = TABLE_ARRAY;
1293 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1294 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1298 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1299 tokens[t0 + 2]) != 0) {
1300 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1304 if (strcmp(tokens[t0 + 3], "size") != 0) {
1305 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1309 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1310 tokens[t0 + 4]) != 0) {
1311 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1316 } else if (strcmp(tokens[t0], "hash") == 0) {
1317 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1319 if (n_tokens < t0 + 12) {
1320 snprintf(out, out_size, MSG_ARG_MISMATCH,
1321 "pipeline table hash");
1325 p.match_type = TABLE_HASH;
1327 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1328 p.match.hash.extendable_bucket = 1;
1329 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1330 p.match.hash.extendable_bucket = 0;
1332 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1337 if (strcmp(tokens[t0 + 2], "key") != 0) {
1338 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1342 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1343 tokens[t0 + 3]) != 0) ||
1344 p.match.hash.key_size == 0 ||
1345 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1346 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1350 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1355 if ((softnic_parse_hex_string(tokens[t0 + 5],
1356 key_mask, &key_mask_size) != 0) ||
1357 key_mask_size != p.match.hash.key_size) {
1358 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1361 p.match.hash.key_mask = key_mask;
1363 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1364 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1368 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1369 tokens[t0 + 7]) != 0) {
1370 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1374 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1375 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1379 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1380 tokens[t0 + 9]) != 0) {
1381 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1385 if (strcmp(tokens[t0 + 10], "size") != 0) {
1386 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1390 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1391 tokens[t0 + 11]) != 0) {
1392 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1397 } else if (strcmp(tokens[t0], "lpm") == 0) {
1398 if (n_tokens < t0 + 6) {
1399 snprintf(out, out_size, MSG_ARG_MISMATCH,
1400 "pipeline table lpm");
1404 p.match_type = TABLE_LPM;
1406 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1407 p.match.lpm.key_size = 4;
1408 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1409 p.match.lpm.key_size = 16;
1411 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1416 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1421 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1422 tokens[t0 + 3]) != 0) {
1423 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1427 if (strcmp(tokens[t0 + 4], "size") != 0) {
1428 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1432 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1433 tokens[t0 + 5]) != 0) {
1434 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1439 } else if (strcmp(tokens[t0], "stub") == 0) {
1440 p.match_type = TABLE_STUB;
1444 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1448 p.action_profile_name = NULL;
1449 if (n_tokens > t0 &&
1450 (strcmp(tokens[t0], "action") == 0)) {
1451 if (n_tokens < t0 + 2) {
1452 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1456 p.action_profile_name = tokens[t0 + 1];
1461 if (n_tokens > t0) {
1462 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1466 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1468 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1474 * pipeline <pipeline_name> port in <port_id> table <table_id>
1477 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1483 char *pipeline_name;
1484 uint32_t port_id, table_id;
1487 if (n_tokens != 7) {
1488 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1492 pipeline_name = tokens[1];
1494 if (strcmp(tokens[2], "port") != 0) {
1495 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1499 if (strcmp(tokens[3], "in") != 0) {
1500 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1504 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1505 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1509 if (strcmp(tokens[5], "table") != 0) {
1510 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1514 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1515 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1519 status = softnic_pipeline_port_in_connect_to_table(softnic,
1524 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1530 * pipeline <pipeline_name> port in <port_id> stats read [clear]
1533 #define MSG_PIPELINE_PORT_IN_STATS \
1534 "Pkts in: %" PRIu64 "\n" \
1535 "Pkts dropped by AH: %" PRIu64 "\n" \
1536 "Pkts dropped by other: %" PRIu64 "\n"
1539 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
1545 struct rte_pipeline_port_in_stats stats;
1546 char *pipeline_name;
1550 if (n_tokens != 7 &&
1552 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1556 pipeline_name = tokens[1];
1558 if (strcmp(tokens[2], "port") != 0) {
1559 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1563 if (strcmp(tokens[3], "in") != 0) {
1564 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1568 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1569 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1573 if (strcmp(tokens[5], "stats") != 0) {
1574 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1578 if (strcmp(tokens[6], "read") != 0) {
1579 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1584 if (n_tokens == 8) {
1585 if (strcmp(tokens[7], "clear") != 0) {
1586 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1593 status = softnic_pipeline_port_in_stats_read(softnic,
1599 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1603 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
1604 stats.stats.n_pkts_in,
1605 stats.n_pkts_dropped_by_ah,
1606 stats.stats.n_pkts_drop);
1610 * pipeline <pipeline_name> port in <port_id> enable
1613 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1619 char *pipeline_name;
1623 if (n_tokens != 6) {
1624 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1628 pipeline_name = tokens[1];
1630 if (strcmp(tokens[2], "port") != 0) {
1631 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1635 if (strcmp(tokens[3], "in") != 0) {
1636 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1640 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1641 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1645 if (strcmp(tokens[5], "enable") != 0) {
1646 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1650 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1652 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1658 * pipeline <pipeline_name> port in <port_id> disable
1661 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1667 char *pipeline_name;
1671 if (n_tokens != 6) {
1672 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1676 pipeline_name = tokens[1];
1678 if (strcmp(tokens[2], "port") != 0) {
1679 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1683 if (strcmp(tokens[3], "in") != 0) {
1684 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1688 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1689 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1693 if (strcmp(tokens[5], "disable") != 0) {
1694 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1698 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1700 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1706 * pipeline <pipeline_name> port out <port_id> stats read [clear]
1708 #define MSG_PIPELINE_PORT_OUT_STATS \
1709 "Pkts in: %" PRIu64 "\n" \
1710 "Pkts dropped by AH: %" PRIu64 "\n" \
1711 "Pkts dropped by other: %" PRIu64 "\n"
1714 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
1720 struct rte_pipeline_port_out_stats stats;
1721 char *pipeline_name;
1725 if (n_tokens != 7 &&
1727 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1731 pipeline_name = tokens[1];
1733 if (strcmp(tokens[2], "port") != 0) {
1734 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1738 if (strcmp(tokens[3], "out") != 0) {
1739 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1743 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1744 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1748 if (strcmp(tokens[5], "stats") != 0) {
1749 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1753 if (strcmp(tokens[6], "read") != 0) {
1754 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1759 if (n_tokens == 8) {
1760 if (strcmp(tokens[7], "clear") != 0) {
1761 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1768 status = softnic_pipeline_port_out_stats_read(softnic,
1774 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1778 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
1779 stats.stats.n_pkts_in,
1780 stats.n_pkts_dropped_by_ah,
1781 stats.stats.n_pkts_drop);
1785 * pipeline <pipeline_name> table <table_id> stats read [clear]
1787 #define MSG_PIPELINE_TABLE_STATS \
1788 "Pkts in: %" PRIu64 "\n" \
1789 "Pkts in with lookup miss: %" PRIu64 "\n" \
1790 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
1791 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
1792 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
1793 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
1796 cmd_pipeline_table_stats(struct pmd_internals *softnic,
1802 struct rte_pipeline_table_stats stats;
1803 char *pipeline_name;
1807 if (n_tokens != 6 &&
1809 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1813 pipeline_name = tokens[1];
1815 if (strcmp(tokens[2], "table") != 0) {
1816 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1820 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
1821 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1825 if (strcmp(tokens[4], "stats") != 0) {
1826 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1830 if (strcmp(tokens[5], "read") != 0) {
1831 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
1836 if (n_tokens == 7) {
1837 if (strcmp(tokens[6], "clear") != 0) {
1838 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
1845 status = softnic_pipeline_table_stats_read(softnic,
1851 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1855 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
1856 stats.stats.n_pkts_in,
1857 stats.stats.n_pkts_lookup_miss,
1858 stats.n_pkts_dropped_by_lkp_hit_ah,
1859 stats.n_pkts_dropped_lkp_hit,
1860 stats.n_pkts_dropped_by_lkp_miss_ah,
1861 stats.n_pkts_dropped_lkp_miss);
1869 * priority <priority>
1870 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
1871 * <sp0> <sp1> <dp0> <dp1> <proto>
1875 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
1876 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
1877 * | ipv4_addr <addr>
1878 * | ipv6_addr <addr>
1879 * | qinq <svlan> <cvlan>
1881 * ipv4 | ipv6 <addr> <depth>
1883 struct pkt_key_qinq {
1884 uint16_t ethertype_svlan;
1886 uint16_t ethertype_cvlan;
1888 } __attribute__((__packed__));
1890 struct pkt_key_ipv4_5tuple {
1891 uint8_t time_to_live;
1893 uint16_t hdr_checksum;
1898 } __attribute__((__packed__));
1900 struct pkt_key_ipv6_5tuple {
1901 uint16_t payload_length;
1908 } __attribute__((__packed__));
1910 struct pkt_key_ipv4_addr {
1912 } __attribute__((__packed__));
1914 struct pkt_key_ipv6_addr {
1916 } __attribute__((__packed__));
1919 parse_match(char **tokens,
1923 struct softnic_table_rule_match *m)
1925 memset(m, 0, sizeof(*m));
1930 if (strcmp(tokens[0], "match") != 0) {
1931 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1935 if (strcmp(tokens[1], "acl") == 0) {
1936 if (n_tokens < 14) {
1937 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1941 m->match_type = TABLE_ACL;
1943 if (strcmp(tokens[2], "priority") != 0) {
1944 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
1948 if (softnic_parser_read_uint32(&m->match.acl.priority,
1950 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
1954 if (strcmp(tokens[4], "ipv4") == 0) {
1955 struct in_addr saddr, daddr;
1957 m->match.acl.ip_version = 1;
1959 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
1960 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
1963 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
1965 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
1966 snprintf(out, out_size, MSG_ARG_INVALID, "da");
1969 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
1970 } else if (strcmp(tokens[4], "ipv6") == 0) {
1971 struct in6_addr saddr, daddr;
1973 m->match.acl.ip_version = 0;
1975 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
1976 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
1979 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
1981 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
1982 snprintf(out, out_size, MSG_ARG_INVALID, "da");
1985 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
1987 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1992 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
1994 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
1998 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2000 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2004 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2005 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2009 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2010 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2014 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2015 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2019 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2020 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2024 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2025 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2029 m->match.acl.proto_mask = 0xff;
2034 if (strcmp(tokens[1], "array") == 0) {
2036 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2040 m->match_type = TABLE_ARRAY;
2042 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2043 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2050 if (strcmp(tokens[1], "hash") == 0) {
2052 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2056 m->match_type = TABLE_HASH;
2058 if (strcmp(tokens[2], "raw") == 0) {
2059 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2062 snprintf(out, out_size, MSG_ARG_MISMATCH,
2067 if (softnic_parse_hex_string(tokens[3],
2068 m->match.hash.key, &key_size) != 0) {
2069 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2076 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2077 struct pkt_key_ipv4_5tuple *ipv4 =
2078 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2079 struct in_addr saddr, daddr;
2084 snprintf(out, out_size, MSG_ARG_MISMATCH,
2089 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2090 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2094 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2095 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2099 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2100 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2104 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2105 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2109 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2110 snprintf(out, out_size, MSG_ARG_INVALID,
2115 ipv4->sa = saddr.s_addr;
2116 ipv4->da = daddr.s_addr;
2117 ipv4->sp = rte_cpu_to_be_16(sp);
2118 ipv4->dp = rte_cpu_to_be_16(dp);
2119 ipv4->proto = proto;
2122 } /* hash ipv4_5tuple */
2124 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2125 struct pkt_key_ipv6_5tuple *ipv6 =
2126 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2127 struct in6_addr saddr, daddr;
2132 snprintf(out, out_size, MSG_ARG_MISMATCH,
2137 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2138 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2142 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2143 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2147 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2148 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2152 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2153 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2157 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2158 snprintf(out, out_size, MSG_ARG_INVALID,
2163 memcpy(ipv6->sa, saddr.s6_addr, 16);
2164 memcpy(ipv6->da, daddr.s6_addr, 16);
2165 ipv6->sp = rte_cpu_to_be_16(sp);
2166 ipv6->dp = rte_cpu_to_be_16(dp);
2167 ipv6->proto = proto;
2170 } /* hash ipv6_5tuple */
2172 if (strcmp(tokens[2], "ipv4_addr") == 0) {
2173 struct pkt_key_ipv4_addr *ipv4_addr =
2174 (struct pkt_key_ipv4_addr *)m->match.hash.key;
2175 struct in_addr addr;
2178 snprintf(out, out_size, MSG_ARG_MISMATCH,
2183 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2184 snprintf(out, out_size, MSG_ARG_INVALID,
2189 ipv4_addr->addr = addr.s_addr;
2192 } /* hash ipv4_addr */
2194 if (strcmp(tokens[2], "ipv6_addr") == 0) {
2195 struct pkt_key_ipv6_addr *ipv6_addr =
2196 (struct pkt_key_ipv6_addr *)m->match.hash.key;
2197 struct in6_addr addr;
2200 snprintf(out, out_size, MSG_ARG_MISMATCH,
2205 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2206 snprintf(out, out_size, MSG_ARG_INVALID,
2211 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
2214 } /* hash ipv6_5tuple */
2216 if (strcmp(tokens[2], "qinq") == 0) {
2217 struct pkt_key_qinq *qinq =
2218 (struct pkt_key_qinq *)m->match.hash.key;
2219 uint16_t svlan, cvlan;
2222 snprintf(out, out_size, MSG_ARG_MISMATCH,
2227 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
2229 snprintf(out, out_size, MSG_ARG_INVALID,
2234 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
2236 snprintf(out, out_size, MSG_ARG_INVALID,
2241 qinq->svlan = rte_cpu_to_be_16(svlan);
2242 qinq->cvlan = rte_cpu_to_be_16(cvlan);
2247 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2251 if (strcmp(tokens[1], "lpm") == 0) {
2253 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2257 m->match_type = TABLE_LPM;
2259 if (strcmp(tokens[2], "ipv4") == 0) {
2260 struct in_addr addr;
2262 m->match.lpm.ip_version = 1;
2264 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
2265 snprintf(out, out_size, MSG_ARG_INVALID,
2270 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2271 } else if (strcmp(tokens[2], "ipv6") == 0) {
2272 struct in6_addr addr;
2274 m->match.lpm.ip_version = 0;
2276 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
2277 snprintf(out, out_size, MSG_ARG_INVALID,
2282 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
2284 snprintf(out, out_size, MSG_ARG_MISMATCH,
2289 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
2290 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
2297 snprintf(out, out_size, MSG_ARG_MISMATCH,
2298 "acl or array or hash or lpm");
2310 * | table <table_id>
2311 * [balance <out0> ... <out7>]
2313 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2314 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2315 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
2316 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
2317 * [tm subport <subport_id> pipe <pipe_id>]
2320 * | vlan <da> <sa> <pcp> <dei> <vid>
2321 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
2322 * | mpls unicast | multicast
2324 * label0 <label> <tc> <ttl>
2325 * [label1 <label> <tc> <ttl>
2326 * [label2 <label> <tc> <ttl>
2327 * [label3 <label> <tc> <ttl>]]]
2328 * | pppoe <da> <sa> <session_id>]
2329 * [nat ipv4 | ipv6 <addr> <port>]
2335 * <pa> ::= g | y | r | drop
2338 parse_table_action_fwd(char **tokens,
2340 struct softnic_table_rule_action *a)
2342 if (n_tokens == 0 ||
2343 (strcmp(tokens[0], "fwd") != 0))
2349 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
2350 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
2351 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2355 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
2359 softnic_parser_read_uint32(&id, tokens[1]))
2362 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
2364 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2368 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
2369 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
2370 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2374 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
2378 softnic_parser_read_uint32(&id, tokens[1]))
2381 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
2383 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
2391 parse_table_action_balance(char **tokens,
2393 struct softnic_table_rule_action *a)
2397 if (n_tokens == 0 ||
2398 (strcmp(tokens[0], "balance") != 0))
2404 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
2407 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
2408 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
2411 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
2412 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
2416 parse_policer_action(char *token, enum rte_table_action_policer *a)
2418 if (strcmp(token, "g") == 0) {
2419 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
2423 if (strcmp(token, "y") == 0) {
2424 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
2428 if (strcmp(token, "r") == 0) {
2429 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
2433 if (strcmp(token, "drop") == 0) {
2434 *a = RTE_TABLE_ACTION_POLICER_DROP;
2442 parse_table_action_meter_tc(char **tokens,
2444 struct rte_table_action_mtr_tc_params *mtr)
2447 strcmp(tokens[0], "meter") ||
2448 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
2449 strcmp(tokens[2], "policer") ||
2450 strcmp(tokens[3], "g") ||
2451 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
2452 strcmp(tokens[5], "y") ||
2453 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
2454 strcmp(tokens[7], "r") ||
2455 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
2462 parse_table_action_meter(char **tokens,
2464 struct softnic_table_rule_action *a)
2466 if (n_tokens == 0 ||
2467 strcmp(tokens[0], "meter"))
2473 if (n_tokens < 10 ||
2474 strcmp(tokens[0], "tc0") ||
2475 (parse_table_action_meter_tc(tokens + 1,
2477 &a->mtr.mtr[0]) == 0))
2483 if (n_tokens == 0 ||
2484 strcmp(tokens[0], "tc1")) {
2486 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2490 if (n_tokens < 30 ||
2491 (parse_table_action_meter_tc(tokens + 1,
2492 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
2493 strcmp(tokens[10], "tc2") ||
2494 (parse_table_action_meter_tc(tokens + 11,
2495 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
2496 strcmp(tokens[20], "tc3") ||
2497 (parse_table_action_meter_tc(tokens + 21,
2498 n_tokens - 21, &a->mtr.mtr[3]) == 0))
2501 a->mtr.tc_mask = 0xF;
2502 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
2503 return 1 + 10 + 3 * 10;
2507 parse_table_action_tm(char **tokens,
2509 struct softnic_table_rule_action *a)
2511 uint32_t subport_id, pipe_id;
2514 strcmp(tokens[0], "tm") ||
2515 strcmp(tokens[1], "subport") ||
2516 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
2517 strcmp(tokens[3], "pipe") ||
2518 softnic_parser_read_uint32(&pipe_id, tokens[4]))
2521 a->tm.subport_id = subport_id;
2522 a->tm.pipe_id = pipe_id;
2523 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
2528 parse_table_action_encap(char **tokens,
2530 struct softnic_table_rule_action *a)
2532 if (n_tokens == 0 ||
2533 strcmp(tokens[0], "encap"))
2540 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
2542 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
2543 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
2546 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
2547 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2552 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
2553 uint32_t pcp, dei, vid;
2556 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
2557 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
2558 softnic_parser_read_uint32(&pcp, tokens[3]) ||
2560 softnic_parser_read_uint32(&dei, tokens[4]) ||
2562 softnic_parser_read_uint32(&vid, tokens[5]) ||
2566 a->encap.vlan.vlan.pcp = pcp & 0x7;
2567 a->encap.vlan.vlan.dei = dei & 0x1;
2568 a->encap.vlan.vlan.vid = vid & 0xFFF;
2569 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
2570 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2575 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
2576 uint32_t svlan_pcp, svlan_dei, svlan_vid;
2577 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
2580 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
2581 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
2582 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
2584 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
2586 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
2587 svlan_vid > 0xFFF ||
2588 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
2590 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
2592 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
2596 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
2597 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
2598 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
2599 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
2600 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
2601 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
2602 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
2603 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2608 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
2609 uint32_t label, tc, ttl;
2614 if (strcmp(tokens[1], "unicast") == 0)
2615 a->encap.mpls.unicast = 1;
2616 else if (strcmp(tokens[1], "multicast") == 0)
2617 a->encap.mpls.unicast = 0;
2621 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
2622 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
2623 strcmp(tokens[4], "label0") ||
2624 softnic_parser_read_uint32(&label, tokens[5]) ||
2626 softnic_parser_read_uint32(&tc, tokens[6]) ||
2628 softnic_parser_read_uint32(&ttl, tokens[7]) ||
2632 a->encap.mpls.mpls[0].label = label;
2633 a->encap.mpls.mpls[0].tc = tc;
2634 a->encap.mpls.mpls[0].ttl = ttl;
2639 if (n_tokens == 0 ||
2640 strcmp(tokens[0], "label1")) {
2641 a->encap.mpls.mpls_count = 1;
2642 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2643 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2648 softnic_parser_read_uint32(&label, tokens[1]) ||
2650 softnic_parser_read_uint32(&tc, tokens[2]) ||
2652 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2656 a->encap.mpls.mpls[1].label = label;
2657 a->encap.mpls.mpls[1].tc = tc;
2658 a->encap.mpls.mpls[1].ttl = ttl;
2663 if (n_tokens == 0 ||
2664 strcmp(tokens[0], "label2")) {
2665 a->encap.mpls.mpls_count = 2;
2666 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2667 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2672 softnic_parser_read_uint32(&label, tokens[1]) ||
2674 softnic_parser_read_uint32(&tc, tokens[2]) ||
2676 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2680 a->encap.mpls.mpls[2].label = label;
2681 a->encap.mpls.mpls[2].tc = tc;
2682 a->encap.mpls.mpls[2].ttl = ttl;
2687 if (n_tokens == 0 ||
2688 strcmp(tokens[0], "label3")) {
2689 a->encap.mpls.mpls_count = 3;
2690 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2691 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2692 return 1 + 8 + 4 + 4;
2696 softnic_parser_read_uint32(&label, tokens[1]) ||
2698 softnic_parser_read_uint32(&tc, tokens[2]) ||
2700 softnic_parser_read_uint32(&ttl, tokens[3]) ||
2704 a->encap.mpls.mpls[3].label = label;
2705 a->encap.mpls.mpls[3].tc = tc;
2706 a->encap.mpls.mpls[3].ttl = ttl;
2708 a->encap.mpls.mpls_count = 4;
2709 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
2710 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2711 return 1 + 8 + 4 + 4 + 4;
2715 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
2717 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
2718 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
2719 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
2723 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
2724 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
2732 parse_table_action_nat(char **tokens,
2734 struct softnic_table_rule_action *a)
2737 strcmp(tokens[0], "nat"))
2740 if (strcmp(tokens[1], "ipv4") == 0) {
2741 struct in_addr addr;
2744 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
2745 softnic_parser_read_uint16(&port, tokens[3]))
2748 a->nat.ip_version = 1;
2749 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
2751 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2755 if (strcmp(tokens[1], "ipv6") == 0) {
2756 struct in6_addr addr;
2759 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
2760 softnic_parser_read_uint16(&port, tokens[3]))
2763 a->nat.ip_version = 0;
2764 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
2766 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
2774 parse_table_action_ttl(char **tokens,
2776 struct softnic_table_rule_action *a)
2779 strcmp(tokens[0], "ttl"))
2782 if (strcmp(tokens[1], "dec") == 0)
2783 a->ttl.decrement = 1;
2784 else if (strcmp(tokens[1], "keep") == 0)
2785 a->ttl.decrement = 0;
2789 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
2794 parse_table_action_stats(char **tokens,
2796 struct softnic_table_rule_action *a)
2799 strcmp(tokens[0], "stats"))
2802 a->stats.n_packets = 0;
2803 a->stats.n_bytes = 0;
2804 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
2809 parse_table_action_time(char **tokens,
2811 struct softnic_table_rule_action *a)
2814 strcmp(tokens[0], "time"))
2817 a->time.time = rte_rdtsc();
2818 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
2823 parse_table_action(char **tokens,
2827 struct softnic_table_rule_action *a)
2829 uint32_t n_tokens0 = n_tokens;
2831 memset(a, 0, sizeof(*a));
2834 strcmp(tokens[0], "action"))
2840 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
2843 n = parse_table_action_fwd(tokens, n_tokens, a);
2845 snprintf(out, out_size, MSG_ARG_INVALID,
2854 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
2857 n = parse_table_action_balance(tokens, n_tokens, a);
2859 snprintf(out, out_size, MSG_ARG_INVALID,
2868 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
2871 n = parse_table_action_meter(tokens, n_tokens, a);
2873 snprintf(out, out_size, MSG_ARG_INVALID,
2882 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
2885 n = parse_table_action_tm(tokens, n_tokens, a);
2887 snprintf(out, out_size, MSG_ARG_INVALID,
2896 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
2899 n = parse_table_action_encap(tokens, n_tokens, a);
2901 snprintf(out, out_size, MSG_ARG_INVALID,
2910 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
2913 n = parse_table_action_nat(tokens, n_tokens, a);
2915 snprintf(out, out_size, MSG_ARG_INVALID,
2924 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
2927 n = parse_table_action_ttl(tokens, n_tokens, a);
2929 snprintf(out, out_size, MSG_ARG_INVALID,
2938 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
2941 n = parse_table_action_stats(tokens, n_tokens, a);
2943 snprintf(out, out_size, MSG_ARG_INVALID,
2952 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
2955 n = parse_table_action_time(tokens, n_tokens, a);
2957 snprintf(out, out_size, MSG_ARG_INVALID,
2966 if (n_tokens0 - n_tokens == 1) {
2967 snprintf(out, out_size, MSG_ARG_INVALID, "action");
2971 return n_tokens0 - n_tokens;
2975 * pipeline <pipeline_name> table <table_id> rule add
2977 * action <table_action>
2980 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
2986 struct softnic_table_rule_match m;
2987 struct softnic_table_rule_action a;
2988 char *pipeline_name;
2990 uint32_t table_id, t0, n_tokens_parsed;
2994 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2998 pipeline_name = tokens[1];
3000 if (strcmp(tokens[2], "table") != 0) {
3001 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3005 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3006 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3010 if (strcmp(tokens[4], "rule") != 0) {
3011 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3015 if (strcmp(tokens[5], "add") != 0) {
3016 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3023 n_tokens_parsed = parse_match(tokens + t0,
3028 if (n_tokens_parsed == 0)
3030 t0 += n_tokens_parsed;
3033 n_tokens_parsed = parse_table_action(tokens + t0,
3038 if (n_tokens_parsed == 0)
3040 t0 += n_tokens_parsed;
3042 if (t0 != n_tokens) {
3043 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3047 status = softnic_pipeline_table_rule_add(softnic,
3054 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3060 * pipeline <pipeline_name> table <table_id> rule add
3068 * | table <table_id>
3071 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3077 struct softnic_table_rule_action action;
3079 char *pipeline_name;
3083 if (n_tokens != 11 &&
3085 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3089 pipeline_name = tokens[1];
3091 if (strcmp(tokens[2], "table") != 0) {
3092 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3096 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3097 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3101 if (strcmp(tokens[4], "rule") != 0) {
3102 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3106 if (strcmp(tokens[5], "add") != 0) {
3107 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3111 if (strcmp(tokens[6], "match") != 0) {
3112 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3116 if (strcmp(tokens[7], "default") != 0) {
3117 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3121 if (strcmp(tokens[8], "action") != 0) {
3122 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3126 if (strcmp(tokens[9], "fwd") != 0) {
3127 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3131 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3133 if (strcmp(tokens[10], "drop") == 0) {
3134 if (n_tokens != 11) {
3135 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3139 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3140 } else if (strcmp(tokens[10], "port") == 0) {
3143 if (n_tokens != 12) {
3144 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3148 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3149 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3153 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
3155 } else if (strcmp(tokens[10], "meta") == 0) {
3156 if (n_tokens != 11) {
3157 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3161 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3162 } else if (strcmp(tokens[10], "table") == 0) {
3165 if (n_tokens != 12) {
3166 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3170 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3171 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3175 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
3178 snprintf(out, out_size, MSG_ARG_INVALID,
3179 "drop or port or meta or table");
3183 status = softnic_pipeline_table_rule_add_default(softnic,
3189 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3195 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
3198 * - line format: match <match> action <action>
3201 cli_rule_file_process(const char *file_name,
3202 size_t line_len_max,
3203 struct softnic_table_rule_match *m,
3204 struct softnic_table_rule_action *a,
3206 uint32_t *line_number,
3211 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
3217 struct softnic_table_rule_match *match;
3218 struct softnic_table_rule_action *action;
3220 char *pipeline_name, *file_name;
3221 uint32_t table_id, n_rules, n_rules_parsed, line_number;
3224 if (n_tokens != 9) {
3225 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3229 pipeline_name = tokens[1];
3231 if (strcmp(tokens[2], "table") != 0) {
3232 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3236 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3237 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3241 if (strcmp(tokens[4], "rule") != 0) {
3242 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3246 if (strcmp(tokens[5], "add") != 0) {
3247 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3251 if (strcmp(tokens[6], "bulk") != 0) {
3252 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
3256 file_name = tokens[7];
3258 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
3260 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
3264 /* Memory allocation. */
3265 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
3266 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
3267 data = calloc(n_rules, sizeof(void *));
3268 if (match == NULL ||
3271 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
3278 /* Load rule file */
3279 n_rules_parsed = n_rules;
3280 status = cli_rule_file_process(file_name,
3289 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3295 if (n_rules_parsed != n_rules) {
3296 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
3304 status = softnic_pipeline_table_rule_add_bulk(softnic,
3312 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3326 * pipeline <pipeline_name> table <table_id> rule delete
3330 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
3336 struct softnic_table_rule_match m;
3337 char *pipeline_name;
3338 uint32_t table_id, n_tokens_parsed, t0;
3342 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3346 pipeline_name = tokens[1];
3348 if (strcmp(tokens[2], "table") != 0) {
3349 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3353 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3354 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3358 if (strcmp(tokens[4], "rule") != 0) {
3359 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3363 if (strcmp(tokens[5], "delete") != 0) {
3364 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3371 n_tokens_parsed = parse_match(tokens + t0,
3376 if (n_tokens_parsed == 0)
3378 t0 += n_tokens_parsed;
3380 if (n_tokens != t0) {
3381 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3385 status = softnic_pipeline_table_rule_delete(softnic,
3390 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3396 * pipeline <pipeline_name> table <table_id> rule delete
3401 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
3407 char *pipeline_name;
3411 if (n_tokens != 8) {
3412 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3416 pipeline_name = tokens[1];
3418 if (strcmp(tokens[2], "table") != 0) {
3419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3423 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3424 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3428 if (strcmp(tokens[4], "rule") != 0) {
3429 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3433 if (strcmp(tokens[5], "delete") != 0) {
3434 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3438 if (strcmp(tokens[6], "match") != 0) {
3439 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3443 if (strcmp(tokens[7], "default") != 0) {
3444 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3448 status = softnic_pipeline_table_rule_delete_default(softnic,
3452 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3458 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
3461 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
3463 uint32_t n_tokens __rte_unused,
3467 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3471 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
3472 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
3473 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
3476 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
3482 struct rte_table_action_meter_profile p;
3483 char *pipeline_name;
3484 uint32_t table_id, meter_profile_id;
3488 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3492 pipeline_name = tokens[1];
3494 if (strcmp(tokens[2], "table") != 0) {
3495 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3499 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3500 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3504 if (strcmp(tokens[4], "meter") != 0) {
3505 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3509 if (strcmp(tokens[5], "profile") != 0) {
3510 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3514 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3515 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3519 if (strcmp(tokens[7], "add") != 0) {
3520 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3524 if (strcmp(tokens[8], "srtcm") == 0) {
3525 if (n_tokens != 15) {
3526 snprintf(out, out_size, MSG_ARG_MISMATCH,
3531 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
3533 if (strcmp(tokens[9], "cir") != 0) {
3534 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3538 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
3539 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3543 if (strcmp(tokens[11], "cbs") != 0) {
3544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3548 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
3549 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3553 if (strcmp(tokens[13], "ebs") != 0) {
3554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
3558 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
3559 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
3562 } else if (strcmp(tokens[8], "trtcm") == 0) {
3563 if (n_tokens != 17) {
3564 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3568 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
3570 if (strcmp(tokens[9], "cir") != 0) {
3571 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
3575 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
3576 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
3580 if (strcmp(tokens[11], "pir") != 0) {
3581 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
3585 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
3586 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
3589 if (strcmp(tokens[13], "cbs") != 0) {
3590 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
3594 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
3595 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
3599 if (strcmp(tokens[15], "pbs") != 0) {
3600 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
3604 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
3605 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
3609 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3613 status = softnic_pipeline_table_mtr_profile_add(softnic,
3619 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3625 * pipeline <pipeline_name> table <table_id>
3626 * meter profile <meter_profile_id> delete
3629 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
3635 char *pipeline_name;
3636 uint32_t table_id, meter_profile_id;
3639 if (n_tokens != 8) {
3640 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3644 pipeline_name = tokens[1];
3646 if (strcmp(tokens[2], "table") != 0) {
3647 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3651 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3652 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3656 if (strcmp(tokens[4], "meter") != 0) {
3657 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
3661 if (strcmp(tokens[5], "profile") != 0) {
3662 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
3666 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
3667 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
3671 if (strcmp(tokens[7], "delete") != 0) {
3672 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
3676 status = softnic_pipeline_table_mtr_profile_delete(softnic,
3681 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3687 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
3690 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
3692 uint32_t n_tokens __rte_unused,
3696 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3700 * pipeline <pipeline_name> table <table_id> dscp <file_name>
3703 * - exactly 64 lines
3704 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
3707 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
3708 const char *file_name,
3709 uint32_t *line_number)
3714 /* Check input arguments */
3715 if (dscp_table == NULL ||
3716 file_name == NULL ||
3717 line_number == NULL) {
3723 /* Open input file */
3724 f = fopen(file_name, "r");
3731 for (dscp = 0, l = 1; ; l++) {
3734 enum rte_meter_color color;
3735 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
3737 if (fgets(line, sizeof(line), f) == NULL)
3740 if (is_comment(line))
3743 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
3752 if (dscp >= RTE_DIM(dscp_table->entry) ||
3753 n_tokens != RTE_DIM(tokens) ||
3754 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
3755 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
3756 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
3757 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
3758 (strlen(tokens[2]) != 1)) {
3764 switch (tokens[2][0]) {
3767 color = e_RTE_METER_GREEN;
3772 color = e_RTE_METER_YELLOW;
3777 color = e_RTE_METER_RED;
3786 dscp_table->entry[dscp].tc_id = tc_id;
3787 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
3788 dscp_table->entry[dscp].color = color;
3798 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
3804 struct rte_table_action_dscp_table dscp_table;
3805 char *pipeline_name, *file_name;
3806 uint32_t table_id, line_number;
3809 if (n_tokens != 6) {
3810 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3814 pipeline_name = tokens[1];
3816 if (strcmp(tokens[2], "table") != 0) {
3817 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
3821 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3822 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3826 if (strcmp(tokens[4], "dscp") != 0) {
3827 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
3831 file_name = tokens[5];
3833 status = load_dscp_table(&dscp_table, file_name, &line_number);
3835 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
3839 status = softnic_pipeline_table_dscp_table_update(softnic,
3845 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3851 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
3854 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
3856 uint32_t n_tokens __rte_unused,
3860 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
3864 * thread <thread_id> pipeline <pipeline_name> enable
3867 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
3873 char *pipeline_name;
3877 if (n_tokens != 5) {
3878 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3882 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
3883 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
3887 if (strcmp(tokens[2], "pipeline") != 0) {
3888 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
3892 pipeline_name = tokens[3];
3894 if (strcmp(tokens[4], "enable") != 0) {
3895 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
3899 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
3901 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
3907 * thread <thread_id> pipeline <pipeline_name> disable
3910 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
3916 char *pipeline_name;
3920 if (n_tokens != 5) {
3921 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3925 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
3926 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
3930 if (strcmp(tokens[2], "pipeline") != 0) {
3931 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
3935 pipeline_name = tokens[3];
3937 if (strcmp(tokens[4], "disable") != 0) {
3938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
3942 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
3944 snprintf(out, out_size, MSG_CMD_FAIL,
3945 "thread pipeline disable");
3951 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
3953 char *tokens[CMD_MAX_TOKENS];
3954 uint32_t n_tokens = RTE_DIM(tokens);
3955 struct pmd_internals *softnic = arg;
3961 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
3963 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
3970 if (strcmp(tokens[0], "mempool") == 0) {
3971 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
3975 if (strcmp(tokens[0], "link") == 0) {
3976 cmd_link(softnic, tokens, n_tokens, out, out_size);
3980 if (strcmp(tokens[0], "swq") == 0) {
3981 cmd_swq(softnic, tokens, n_tokens, out, out_size);
3985 if (strcmp(tokens[0], "tmgr") == 0) {
3986 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
3990 if (strcmp(tokens[0], "tap") == 0) {
3991 cmd_tap(softnic, tokens, n_tokens, out, out_size);
3995 if (strcmp(tokens[0], "port") == 0) {
3996 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4000 if (strcmp(tokens[0], "table") == 0) {
4001 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4005 if (strcmp(tokens[0], "pipeline") == 0) {
4006 if (n_tokens >= 3 &&
4007 (strcmp(tokens[2], "period") == 0)) {
4008 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4012 if (n_tokens >= 5 &&
4013 (strcmp(tokens[2], "port") == 0) &&
4014 (strcmp(tokens[3], "in") == 0) &&
4015 (strcmp(tokens[4], "bsz") == 0)) {
4016 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4020 if (n_tokens >= 5 &&
4021 (strcmp(tokens[2], "port") == 0) &&
4022 (strcmp(tokens[3], "out") == 0) &&
4023 (strcmp(tokens[4], "bsz") == 0)) {
4024 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4028 if (n_tokens >= 4 &&
4029 (strcmp(tokens[2], "table") == 0) &&
4030 (strcmp(tokens[3], "match") == 0)) {
4031 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4035 if (n_tokens >= 6 &&
4036 (strcmp(tokens[2], "port") == 0) &&
4037 (strcmp(tokens[3], "in") == 0) &&
4038 (strcmp(tokens[5], "table") == 0)) {
4039 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4044 if (n_tokens >= 6 &&
4045 (strcmp(tokens[2], "port") == 0) &&
4046 (strcmp(tokens[3], "in") == 0) &&
4047 (strcmp(tokens[5], "stats") == 0)) {
4048 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4053 if (n_tokens >= 6 &&
4054 (strcmp(tokens[2], "port") == 0) &&
4055 (strcmp(tokens[3], "in") == 0) &&
4056 (strcmp(tokens[5], "enable") == 0)) {
4057 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4062 if (n_tokens >= 6 &&
4063 (strcmp(tokens[2], "port") == 0) &&
4064 (strcmp(tokens[3], "in") == 0) &&
4065 (strcmp(tokens[5], "disable") == 0)) {
4066 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4071 if (n_tokens >= 6 &&
4072 (strcmp(tokens[2], "port") == 0) &&
4073 (strcmp(tokens[3], "out") == 0) &&
4074 (strcmp(tokens[5], "stats") == 0)) {
4075 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4080 if (n_tokens >= 5 &&
4081 (strcmp(tokens[2], "table") == 0) &&
4082 (strcmp(tokens[4], "stats") == 0)) {
4083 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4088 if (n_tokens >= 7 &&
4089 (strcmp(tokens[2], "table") == 0) &&
4090 (strcmp(tokens[4], "rule") == 0) &&
4091 (strcmp(tokens[5], "add") == 0) &&
4092 (strcmp(tokens[6], "match") == 0)) {
4093 if (n_tokens >= 8 &&
4094 (strcmp(tokens[7], "default") == 0)) {
4095 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4096 n_tokens, out, out_size);
4100 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4105 if (n_tokens >= 7 &&
4106 (strcmp(tokens[2], "table") == 0) &&
4107 (strcmp(tokens[4], "rule") == 0) &&
4108 (strcmp(tokens[5], "add") == 0) &&
4109 (strcmp(tokens[6], "bulk") == 0)) {
4110 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4111 n_tokens, out, out_size);
4115 if (n_tokens >= 7 &&
4116 (strcmp(tokens[2], "table") == 0) &&
4117 (strcmp(tokens[4], "rule") == 0) &&
4118 (strcmp(tokens[5], "delete") == 0) &&
4119 (strcmp(tokens[6], "match") == 0)) {
4120 if (n_tokens >= 8 &&
4121 (strcmp(tokens[7], "default") == 0)) {
4122 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
4123 n_tokens, out, out_size);
4127 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
4132 if (n_tokens >= 7 &&
4133 (strcmp(tokens[2], "table") == 0) &&
4134 (strcmp(tokens[4], "rule") == 0) &&
4135 (strcmp(tokens[5], "read") == 0) &&
4136 (strcmp(tokens[6], "stats") == 0)) {
4137 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
4142 if (n_tokens >= 8 &&
4143 (strcmp(tokens[2], "table") == 0) &&
4144 (strcmp(tokens[4], "meter") == 0) &&
4145 (strcmp(tokens[5], "profile") == 0) &&
4146 (strcmp(tokens[7], "add") == 0)) {
4147 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
4152 if (n_tokens >= 8 &&
4153 (strcmp(tokens[2], "table") == 0) &&
4154 (strcmp(tokens[4], "meter") == 0) &&
4155 (strcmp(tokens[5], "profile") == 0) &&
4156 (strcmp(tokens[7], "delete") == 0)) {
4157 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
4158 n_tokens, out, out_size);
4162 if (n_tokens >= 7 &&
4163 (strcmp(tokens[2], "table") == 0) &&
4164 (strcmp(tokens[4], "rule") == 0) &&
4165 (strcmp(tokens[5], "read") == 0) &&
4166 (strcmp(tokens[6], "meter") == 0)) {
4167 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
4172 if (n_tokens >= 5 &&
4173 (strcmp(tokens[2], "table") == 0) &&
4174 (strcmp(tokens[4], "dscp") == 0)) {
4175 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
4180 if (n_tokens >= 7 &&
4181 (strcmp(tokens[2], "table") == 0) &&
4182 (strcmp(tokens[4], "rule") == 0) &&
4183 (strcmp(tokens[5], "read") == 0) &&
4184 (strcmp(tokens[6], "ttl") == 0)) {
4185 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
4191 if (strcmp(tokens[0], "thread") == 0) {
4192 if (n_tokens >= 5 &&
4193 (strcmp(tokens[4], "enable") == 0)) {
4194 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
4199 if (n_tokens >= 5 &&
4200 (strcmp(tokens[4], "disable") == 0)) {
4201 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
4207 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
4211 softnic_cli_script_process(struct pmd_internals *softnic,
4212 const char *file_name,
4213 size_t msg_in_len_max,
4214 size_t msg_out_len_max)
4216 char *msg_in = NULL, *msg_out = NULL;
4219 /* Check input arguments */
4220 if (file_name == NULL ||
4221 (strlen(file_name) == 0) ||
4222 msg_in_len_max == 0 ||
4223 msg_out_len_max == 0)
4226 msg_in = malloc(msg_in_len_max + 1);
4227 msg_out = malloc(msg_out_len_max + 1);
4228 if (msg_in == NULL ||
4235 /* Open input file */
4236 f = fopen(file_name, "r");
4245 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
4248 printf("%s", msg_in);
4251 softnic_cli_process(msg_in,
4256 if (strlen(msg_out))
4257 printf("%s", msg_out);
4268 cli_rule_file_process(const char *file_name,
4269 size_t line_len_max,
4270 struct softnic_table_rule_match *m,
4271 struct softnic_table_rule_action *a,
4273 uint32_t *line_number,
4279 uint32_t rule_id, line_id;
4282 /* Check input arguments */
4283 if (file_name == NULL ||
4284 (strlen(file_name) == 0) ||
4285 line_len_max == 0) {
4290 /* Memory allocation */
4291 line = malloc(line_len_max + 1);
4298 f = fopen(file_name, "r");
4306 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
4307 char *tokens[CMD_MAX_TOKENS];
4308 uint32_t n_tokens, n_tokens_parsed, t0;
4310 /* Read next line from file. */
4311 if (fgets(line, line_len_max + 1, f) == NULL)
4315 if (is_comment(line))
4319 n_tokens = RTE_DIM(tokens);
4320 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
4332 n_tokens_parsed = parse_match(tokens + t0,
4337 if (n_tokens_parsed == 0) {
4341 t0 += n_tokens_parsed;
4344 n_tokens_parsed = parse_table_action(tokens + t0,
4349 if (n_tokens_parsed == 0) {
4353 t0 += n_tokens_parsed;
4355 /* Line completed. */
4356 if (t0 < n_tokens) {
4361 /* Increment rule count */
4372 *line_number = line_id;