1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include "rte_eth_softnic_internals.h"
13 #ifndef CMD_MAX_TOKENS
14 #define CMD_MAX_TOKENS 256
17 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
18 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
19 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
20 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
21 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
22 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
23 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
24 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
25 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
26 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
27 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
32 if ((strlen(in) && index("!#%;", in[0])) ||
33 (strncmp(in, "//", 2) == 0) ||
34 (strncmp(in, "--", 2) == 0))
41 * mempool <mempool_name>
42 * buffer <buffer_size>
47 cmd_mempool(struct pmd_internals *softnic,
53 struct softnic_mempool_params p;
55 struct softnic_mempool *mempool;
58 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
64 if (strcmp(tokens[2], "buffer") != 0) {
65 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
69 if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
70 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
74 if (strcmp(tokens[4], "pool") != 0) {
75 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
79 if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
80 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
84 if (strcmp(tokens[6], "cache") != 0) {
85 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
89 if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
90 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
94 mempool = softnic_mempool_create(softnic, name, &p);
95 if (mempool == NULL) {
96 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
103 * dev <device_name> | port <port_id>
106 cmd_link(struct pmd_internals *softnic,
112 struct softnic_link_params p;
113 struct softnic_link *link;
116 memset(&p, 0, sizeof(p));
119 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
124 if (strcmp(tokens[2], "dev") == 0) {
125 p.dev_name = tokens[3];
126 } else if (strcmp(tokens[2], "port") == 0) {
129 if (softnic_parser_read_uint16(&p.port_id, tokens[3]) != 0) {
130 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
134 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
138 link = softnic_link_create(softnic, name, &p);
140 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
150 cmd_swq(struct pmd_internals *softnic,
156 struct softnic_swq_params p;
158 struct softnic_swq *swq;
161 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
167 if (strcmp(tokens[2], "size") != 0) {
168 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
172 if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
173 snprintf(out, out_size, MSG_ARG_INVALID, "size");
177 swq = softnic_swq_create(softnic, name, &p);
179 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
188 cmd_tap(struct pmd_internals *softnic,
195 struct softnic_tap *tap;
198 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
204 tap = softnic_tap_create(softnic, name);
206 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
212 * port in action profile <profile_name>
213 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
214 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
217 cmd_port_in_action_profile(struct pmd_internals *softnic,
223 struct softnic_port_in_action_profile_params p;
224 struct softnic_port_in_action_profile *ap;
228 memset(&p, 0, sizeof(p));
231 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
235 if (strcmp(tokens[1], "in") != 0) {
236 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
240 if (strcmp(tokens[2], "action") != 0) {
241 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
245 if (strcmp(tokens[3], "profile") != 0) {
246 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
255 (strcmp(tokens[t0], "filter") == 0)) {
258 if (n_tokens < t0 + 10) {
259 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
263 if (strcmp(tokens[t0 + 1], "match") == 0) {
264 p.fltr.filter_on_match = 1;
265 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
266 p.fltr.filter_on_match = 0;
268 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
272 if (strcmp(tokens[t0 + 2], "offset") != 0) {
273 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
277 if (softnic_parser_read_uint32(&p.fltr.key_offset,
278 tokens[t0 + 3]) != 0) {
279 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
283 if (strcmp(tokens[t0 + 4], "mask") != 0) {
284 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
288 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
289 if ((softnic_parse_hex_string(tokens[t0 + 5],
290 p.fltr.key_mask, &size) != 0) ||
291 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
292 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
296 if (strcmp(tokens[t0 + 6], "key") != 0) {
297 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
301 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
302 if ((softnic_parse_hex_string(tokens[t0 + 7],
303 p.fltr.key, &size) != 0) ||
304 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
305 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
309 if (strcmp(tokens[t0 + 8], "port") != 0) {
310 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
314 if (softnic_parser_read_uint32(&p.fltr.port_id,
315 tokens[t0 + 9]) != 0) {
316 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
320 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
325 (strcmp(tokens[t0], "balance") == 0)) {
328 if (n_tokens < t0 + 22) {
329 snprintf(out, out_size, MSG_ARG_MISMATCH,
330 "port in action profile balance");
334 if (strcmp(tokens[t0 + 1], "offset") != 0) {
335 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
339 if (softnic_parser_read_uint32(&p.lb.key_offset,
340 tokens[t0 + 2]) != 0) {
341 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
345 if (strcmp(tokens[t0 + 3], "mask") != 0) {
346 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
350 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
351 if (softnic_parse_hex_string(tokens[t0 + 4],
352 p.lb.key_mask, &p.lb.key_size) != 0) {
353 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
357 if (strcmp(tokens[t0 + 5], "port") != 0) {
358 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
362 for (i = 0; i < 16; i++)
363 if (softnic_parser_read_uint32(&p.lb.port_id[i],
364 tokens[t0 + 6 + i]) != 0) {
365 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
369 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
374 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
378 ap = softnic_port_in_action_profile_create(softnic, name, &p);
380 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
386 * table action profile <profile_name>
390 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
391 * [meter srtcm | trtcm
393 * stats none | pkts | bytes | both]
394 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
395 * [encap ether | vlan | qinq | mpls | pppoe]
400 * [stats pkts | bytes | both]
404 cmd_table_action_profile(struct pmd_internals *softnic,
410 struct softnic_table_action_profile_params p;
411 struct softnic_table_action_profile *ap;
415 memset(&p, 0, sizeof(p));
418 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
422 if (strcmp(tokens[1], "action") != 0) {
423 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
427 if (strcmp(tokens[2], "profile") != 0) {
428 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
434 if (strcmp(tokens[4], "ipv4") == 0) {
435 p.common.ip_version = 1;
436 } else if (strcmp(tokens[4], "ipv6") == 0) {
437 p.common.ip_version = 0;
439 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
443 if (strcmp(tokens[5], "offset") != 0) {
444 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
448 if (softnic_parser_read_uint32(&p.common.ip_offset,
450 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
454 if (strcmp(tokens[7], "fwd") != 0) {
455 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
459 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
463 (strcmp(tokens[t0], "balance") == 0)) {
464 if (n_tokens < t0 + 7) {
465 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
469 if (strcmp(tokens[t0 + 1], "offset") != 0) {
470 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
474 if (softnic_parser_read_uint32(&p.lb.key_offset,
475 tokens[t0 + 2]) != 0) {
476 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
480 if (strcmp(tokens[t0 + 3], "mask") != 0) {
481 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
485 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
486 if (softnic_parse_hex_string(tokens[t0 + 4],
487 p.lb.key_mask, &p.lb.key_size) != 0) {
488 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
492 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
497 if (softnic_parser_read_uint32(&p.lb.out_offset,
498 tokens[t0 + 6]) != 0) {
499 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
503 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
508 (strcmp(tokens[t0], "meter") == 0)) {
509 if (n_tokens < t0 + 6) {
510 snprintf(out, out_size, MSG_ARG_MISMATCH,
511 "table action profile meter");
515 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
516 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
517 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
518 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
520 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
525 if (strcmp(tokens[t0 + 2], "tc") != 0) {
526 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
530 if (softnic_parser_read_uint32(&p.mtr.n_tc,
531 tokens[t0 + 3]) != 0) {
532 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
536 if (strcmp(tokens[t0 + 4], "stats") != 0) {
537 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
541 if (strcmp(tokens[t0 + 5], "none") == 0) {
542 p.mtr.n_packets_enabled = 0;
543 p.mtr.n_bytes_enabled = 0;
544 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
545 p.mtr.n_packets_enabled = 1;
546 p.mtr.n_bytes_enabled = 0;
547 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
548 p.mtr.n_packets_enabled = 0;
549 p.mtr.n_bytes_enabled = 1;
550 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
551 p.mtr.n_packets_enabled = 1;
552 p.mtr.n_bytes_enabled = 1;
554 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
555 "none or pkts or bytes or both");
559 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
564 (strcmp(tokens[t0], "tm") == 0)) {
565 if (n_tokens < t0 + 5) {
566 snprintf(out, out_size, MSG_ARG_MISMATCH,
567 "table action profile tm");
571 if (strcmp(tokens[t0 + 1], "spp") != 0) {
572 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
576 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
577 tokens[t0 + 2]) != 0) {
578 snprintf(out, out_size, MSG_ARG_INVALID,
579 "n_subports_per_port");
583 if (strcmp(tokens[t0 + 3], "pps") != 0) {
584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
588 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
589 tokens[t0 + 4]) != 0) {
590 snprintf(out, out_size, MSG_ARG_INVALID,
591 "n_pipes_per_subport");
595 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
600 (strcmp(tokens[t0], "encap") == 0)) {
601 if (n_tokens < t0 + 2) {
602 snprintf(out, out_size, MSG_ARG_MISMATCH,
603 "action profile encap");
607 if (strcmp(tokens[t0 + 1], "ether") == 0) {
608 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
609 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
610 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
611 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
612 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
613 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
614 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
615 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
616 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
618 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
622 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
627 (strcmp(tokens[t0], "nat") == 0)) {
628 if (n_tokens < t0 + 4) {
629 snprintf(out, out_size, MSG_ARG_MISMATCH,
630 "table action profile nat");
634 if (strcmp(tokens[t0 + 1], "src") == 0) {
635 p.nat.source_nat = 1;
636 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
637 p.nat.source_nat = 0;
639 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
644 if (strcmp(tokens[t0 + 2], "proto") != 0) {
645 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
649 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
651 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
654 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
659 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
664 (strcmp(tokens[t0], "ttl") == 0)) {
665 if (n_tokens < t0 + 4) {
666 snprintf(out, out_size, MSG_ARG_MISMATCH,
667 "table action profile ttl");
671 if (strcmp(tokens[t0 + 1], "drop") == 0) {
673 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
676 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
681 if (strcmp(tokens[t0 + 2], "stats") != 0) {
682 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
686 if (strcmp(tokens[t0 + 3], "none") == 0) {
687 p.ttl.n_packets_enabled = 0;
688 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
689 p.ttl.n_packets_enabled = 1;
691 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
696 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
701 (strcmp(tokens[t0], "stats") == 0)) {
702 if (n_tokens < t0 + 2) {
703 snprintf(out, out_size, MSG_ARG_MISMATCH,
704 "table action profile stats");
708 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
709 p.stats.n_packets_enabled = 1;
710 p.stats.n_bytes_enabled = 0;
711 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
712 p.stats.n_packets_enabled = 0;
713 p.stats.n_bytes_enabled = 1;
714 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
715 p.stats.n_packets_enabled = 1;
716 p.stats.n_bytes_enabled = 1;
718 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
719 "pkts or bytes or both");
723 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
728 (strcmp(tokens[t0], "time") == 0)) {
729 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
734 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
738 ap = softnic_table_action_profile_create(softnic, name, &p);
740 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
746 * pipeline <pipeline_name>
747 * period <timer_period_ms>
748 * offset_port_id <offset_port_id>
751 cmd_pipeline(struct pmd_internals *softnic,
757 struct pipeline_params p;
759 struct pipeline *pipeline;
762 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
768 if (strcmp(tokens[2], "period") != 0) {
769 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
773 if (softnic_parser_read_uint32(&p.timer_period_ms,
775 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
779 if (strcmp(tokens[4], "offset_port_id") != 0) {
780 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
784 if (softnic_parser_read_uint32(&p.offset_port_id,
786 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
790 pipeline = softnic_pipeline_create(softnic, name, &p);
791 if (pipeline == NULL) {
792 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
798 * pipeline <pipeline_name> port in
800 * link <link_name> rxq <queue_id>
803 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
804 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
805 * [action <port_in_action_profile_name>]
809 cmd_pipeline_port_in(struct pmd_internals *softnic,
815 struct softnic_port_in_params p;
821 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
825 pipeline_name = tokens[1];
827 if (strcmp(tokens[2], "port") != 0) {
828 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
832 if (strcmp(tokens[3], "in") != 0) {
833 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
837 if (strcmp(tokens[4], "bsz") != 0) {
838 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
842 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
843 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
849 if (strcmp(tokens[t0], "link") == 0) {
850 if (n_tokens < t0 + 4) {
851 snprintf(out, out_size, MSG_ARG_MISMATCH,
852 "pipeline port in link");
856 p.type = PORT_IN_RXQ;
858 p.dev_name = tokens[t0 + 1];
860 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
861 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
865 if (softnic_parser_read_uint16(&p.rxq.queue_id,
866 tokens[t0 + 3]) != 0) {
867 snprintf(out, out_size, MSG_ARG_INVALID,
872 } else if (strcmp(tokens[t0], "swq") == 0) {
873 if (n_tokens < t0 + 2) {
874 snprintf(out, out_size, MSG_ARG_MISMATCH,
875 "pipeline port in swq");
879 p.type = PORT_IN_SWQ;
881 p.dev_name = tokens[t0 + 1];
884 } else if (strcmp(tokens[t0], "tmgr") == 0) {
885 if (n_tokens < t0 + 2) {
886 snprintf(out, out_size, MSG_ARG_MISMATCH,
887 "pipeline port in tmgr");
891 p.type = PORT_IN_TMGR;
893 p.dev_name = tokens[t0 + 1];
896 } else if (strcmp(tokens[t0], "tap") == 0) {
897 if (n_tokens < t0 + 6) {
898 snprintf(out, out_size, MSG_ARG_MISMATCH,
899 "pipeline port in tap");
903 p.type = PORT_IN_TAP;
905 p.dev_name = tokens[t0 + 1];
907 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
908 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
913 p.tap.mempool_name = tokens[t0 + 3];
915 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
916 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
921 if (softnic_parser_read_uint32(&p.tap.mtu,
922 tokens[t0 + 5]) != 0) {
923 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
928 } else if (strcmp(tokens[t0], "source") == 0) {
929 if (n_tokens < t0 + 6) {
930 snprintf(out, out_size, MSG_ARG_MISMATCH,
931 "pipeline port in source");
935 p.type = PORT_IN_SOURCE;
939 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
940 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
945 p.source.mempool_name = tokens[t0 + 2];
947 if (strcmp(tokens[t0 + 3], "file") != 0) {
948 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
953 p.source.file_name = tokens[t0 + 4];
955 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
956 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
961 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
962 tokens[t0 + 6]) != 0) {
963 snprintf(out, out_size, MSG_ARG_INVALID,
970 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
974 p.action_profile_name = NULL;
976 (strcmp(tokens[t0], "action") == 0)) {
977 if (n_tokens < t0 + 2) {
978 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
982 p.action_profile_name = tokens[t0 + 1];
989 (strcmp(tokens[t0], "disabled") == 0)) {
995 if (n_tokens != t0) {
996 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1000 status = softnic_pipeline_port_in_create(softnic,
1005 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1011 * pipeline <pipeline_name> port out
1013 * link <link_name> txq <txq_id>
1015 * | tmgr <tmgr_name>
1017 * | sink [file <file_name> pkts <max_n_pkts>]
1020 cmd_pipeline_port_out(struct pmd_internals *softnic,
1026 struct softnic_port_out_params p;
1027 char *pipeline_name;
1030 memset(&p, 0, sizeof(p));
1033 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1037 pipeline_name = tokens[1];
1039 if (strcmp(tokens[2], "port") != 0) {
1040 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1044 if (strcmp(tokens[3], "out") != 0) {
1045 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1049 if (strcmp(tokens[4], "bsz") != 0) {
1050 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1054 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1055 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1059 if (strcmp(tokens[6], "link") == 0) {
1060 if (n_tokens != 10) {
1061 snprintf(out, out_size, MSG_ARG_MISMATCH,
1062 "pipeline port out link");
1066 p.type = PORT_OUT_TXQ;
1068 p.dev_name = tokens[7];
1070 if (strcmp(tokens[8], "txq") != 0) {
1071 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1075 if (softnic_parser_read_uint16(&p.txq.queue_id,
1077 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1080 } else if (strcmp(tokens[6], "swq") == 0) {
1081 if (n_tokens != 8) {
1082 snprintf(out, out_size, MSG_ARG_MISMATCH,
1083 "pipeline port out swq");
1087 p.type = PORT_OUT_SWQ;
1089 p.dev_name = tokens[7];
1090 } else if (strcmp(tokens[6], "tmgr") == 0) {
1091 if (n_tokens != 8) {
1092 snprintf(out, out_size, MSG_ARG_MISMATCH,
1093 "pipeline port out tmgr");
1097 p.type = PORT_OUT_TMGR;
1099 p.dev_name = tokens[7];
1100 } else if (strcmp(tokens[6], "tap") == 0) {
1101 if (n_tokens != 8) {
1102 snprintf(out, out_size, MSG_ARG_MISMATCH,
1103 "pipeline port out tap");
1107 p.type = PORT_OUT_TAP;
1109 p.dev_name = tokens[7];
1110 } else if (strcmp(tokens[6], "sink") == 0) {
1111 if ((n_tokens != 7) && (n_tokens != 11)) {
1112 snprintf(out, out_size, MSG_ARG_MISMATCH,
1113 "pipeline port out sink");
1117 p.type = PORT_OUT_SINK;
1121 if (n_tokens == 7) {
1122 p.sink.file_name = NULL;
1123 p.sink.max_n_pkts = 0;
1125 if (strcmp(tokens[7], "file") != 0) {
1126 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1131 p.sink.file_name = tokens[8];
1133 if (strcmp(tokens[9], "pkts") != 0) {
1134 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1138 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1140 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1145 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1149 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1151 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1157 * pipeline <pipeline_name> table
1161 * offset <ip_header_offset>
1164 * offset <key_offset>
1170 * offset <key_offset>
1171 * buckets <n_buckets>
1175 * offset <ip_header_offset>
1178 * [action <table_action_profile_name>]
1181 cmd_pipeline_table(struct pmd_internals *softnic,
1187 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1188 struct softnic_table_params p;
1189 char *pipeline_name;
1194 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1198 pipeline_name = tokens[1];
1200 if (strcmp(tokens[2], "table") != 0) {
1201 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1205 if (strcmp(tokens[3], "match") != 0) {
1206 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1211 if (strcmp(tokens[t0], "acl") == 0) {
1212 if (n_tokens < t0 + 6) {
1213 snprintf(out, out_size, MSG_ARG_MISMATCH,
1214 "pipeline table acl");
1218 p.match_type = TABLE_ACL;
1220 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1221 p.match.acl.ip_version = 1;
1222 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1223 p.match.acl.ip_version = 0;
1225 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1230 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1231 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1235 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1236 tokens[t0 + 3]) != 0) {
1237 snprintf(out, out_size, MSG_ARG_INVALID,
1238 "ip_header_offset");
1242 if (strcmp(tokens[t0 + 4], "size") != 0) {
1243 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1247 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1248 tokens[t0 + 5]) != 0) {
1249 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1254 } else if (strcmp(tokens[t0], "array") == 0) {
1255 if (n_tokens < t0 + 5) {
1256 snprintf(out, out_size, MSG_ARG_MISMATCH,
1257 "pipeline table array");
1261 p.match_type = TABLE_ARRAY;
1263 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1264 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1268 if (softnic_parser_read_uint32(&p.match.array.key_offset,
1269 tokens[t0 + 2]) != 0) {
1270 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1274 if (strcmp(tokens[t0 + 3], "size") != 0) {
1275 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1279 if (softnic_parser_read_uint32(&p.match.array.n_keys,
1280 tokens[t0 + 4]) != 0) {
1281 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1286 } else if (strcmp(tokens[t0], "hash") == 0) {
1287 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1289 if (n_tokens < t0 + 12) {
1290 snprintf(out, out_size, MSG_ARG_MISMATCH,
1291 "pipeline table hash");
1295 p.match_type = TABLE_HASH;
1297 if (strcmp(tokens[t0 + 1], "ext") == 0) {
1298 p.match.hash.extendable_bucket = 1;
1299 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1300 p.match.hash.extendable_bucket = 0;
1302 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1307 if (strcmp(tokens[t0 + 2], "key") != 0) {
1308 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1312 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1313 tokens[t0 + 3]) != 0) ||
1314 p.match.hash.key_size == 0 ||
1315 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1316 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1320 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1321 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1325 if ((softnic_parse_hex_string(tokens[t0 + 5],
1326 key_mask, &key_mask_size) != 0) ||
1327 key_mask_size != p.match.hash.key_size) {
1328 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1331 p.match.hash.key_mask = key_mask;
1333 if (strcmp(tokens[t0 + 6], "offset") != 0) {
1334 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1338 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1339 tokens[t0 + 7]) != 0) {
1340 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1344 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1345 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1349 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1350 tokens[t0 + 9]) != 0) {
1351 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1355 if (strcmp(tokens[t0 + 10], "size") != 0) {
1356 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1360 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1361 tokens[t0 + 11]) != 0) {
1362 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1367 } else if (strcmp(tokens[t0], "lpm") == 0) {
1368 if (n_tokens < t0 + 6) {
1369 snprintf(out, out_size, MSG_ARG_MISMATCH,
1370 "pipeline table lpm");
1374 p.match_type = TABLE_LPM;
1376 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1377 p.match.lpm.key_size = 4;
1378 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1379 p.match.lpm.key_size = 16;
1381 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1386 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1387 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1391 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1392 tokens[t0 + 3]) != 0) {
1393 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1397 if (strcmp(tokens[t0 + 4], "size") != 0) {
1398 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1402 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1403 tokens[t0 + 5]) != 0) {
1404 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1409 } else if (strcmp(tokens[t0], "stub") == 0) {
1410 p.match_type = TABLE_STUB;
1414 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1418 p.action_profile_name = NULL;
1419 if (n_tokens > t0 &&
1420 (strcmp(tokens[t0], "action") == 0)) {
1421 if (n_tokens < t0 + 2) {
1422 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1426 p.action_profile_name = tokens[t0 + 1];
1431 if (n_tokens > t0) {
1432 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1436 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1438 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1444 * pipeline <pipeline_name> port in <port_id> table <table_id>
1447 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1453 char *pipeline_name;
1454 uint32_t port_id, table_id;
1457 if (n_tokens != 7) {
1458 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1462 pipeline_name = tokens[1];
1464 if (strcmp(tokens[2], "port") != 0) {
1465 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1469 if (strcmp(tokens[3], "in") != 0) {
1470 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1474 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1475 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1479 if (strcmp(tokens[5], "table") != 0) {
1480 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1484 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1485 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1489 status = softnic_pipeline_port_in_connect_to_table(softnic,
1494 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1500 * pipeline <pipeline_name> port in <port_id> enable
1503 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1509 char *pipeline_name;
1513 if (n_tokens != 6) {
1514 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1518 pipeline_name = tokens[1];
1520 if (strcmp(tokens[2], "port") != 0) {
1521 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1525 if (strcmp(tokens[3], "in") != 0) {
1526 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1530 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1531 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1535 if (strcmp(tokens[5], "enable") != 0) {
1536 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1540 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1542 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1548 * pipeline <pipeline_name> port in <port_id> disable
1551 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1557 char *pipeline_name;
1561 if (n_tokens != 6) {
1562 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1566 pipeline_name = tokens[1];
1568 if (strcmp(tokens[2], "port") != 0) {
1569 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1573 if (strcmp(tokens[3], "in") != 0) {
1574 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1578 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1579 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1583 if (strcmp(tokens[5], "disable") != 0) {
1584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1588 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1590 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1596 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
1598 char *tokens[CMD_MAX_TOKENS];
1599 uint32_t n_tokens = RTE_DIM(tokens);
1600 struct pmd_internals *softnic = arg;
1606 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
1608 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
1615 if (strcmp(tokens[0], "mempool") == 0) {
1616 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
1620 if (strcmp(tokens[0], "link") == 0) {
1621 cmd_link(softnic, tokens, n_tokens, out, out_size);
1625 if (strcmp(tokens[0], "swq") == 0) {
1626 cmd_swq(softnic, tokens, n_tokens, out, out_size);
1630 if (strcmp(tokens[0], "tap") == 0) {
1631 cmd_tap(softnic, tokens, n_tokens, out, out_size);
1635 if (strcmp(tokens[0], "port") == 0) {
1636 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
1640 if (strcmp(tokens[0], "table") == 0) {
1641 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
1645 if (strcmp(tokens[0], "pipeline") == 0) {
1646 if (n_tokens >= 3 &&
1647 (strcmp(tokens[2], "period") == 0)) {
1648 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
1652 if (n_tokens >= 5 &&
1653 (strcmp(tokens[2], "port") == 0) &&
1654 (strcmp(tokens[3], "in") == 0) &&
1655 (strcmp(tokens[4], "bsz") == 0)) {
1656 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
1660 if (n_tokens >= 5 &&
1661 (strcmp(tokens[2], "port") == 0) &&
1662 (strcmp(tokens[3], "out") == 0) &&
1663 (strcmp(tokens[4], "bsz") == 0)) {
1664 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
1668 if (n_tokens >= 4 &&
1669 (strcmp(tokens[2], "table") == 0) &&
1670 (strcmp(tokens[3], "match") == 0)) {
1671 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
1675 if (n_tokens >= 6 &&
1676 (strcmp(tokens[2], "port") == 0) &&
1677 (strcmp(tokens[3], "in") == 0) &&
1678 (strcmp(tokens[5], "table") == 0)) {
1679 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
1684 if (n_tokens >= 6 &&
1685 (strcmp(tokens[2], "port") == 0) &&
1686 (strcmp(tokens[3], "in") == 0) &&
1687 (strcmp(tokens[5], "enable") == 0)) {
1688 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
1693 if (n_tokens >= 6 &&
1694 (strcmp(tokens[2], "port") == 0) &&
1695 (strcmp(tokens[3], "in") == 0) &&
1696 (strcmp(tokens[5], "disable") == 0)) {
1697 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
1703 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
1707 softnic_cli_script_process(struct pmd_internals *softnic,
1708 const char *file_name,
1709 size_t msg_in_len_max,
1710 size_t msg_out_len_max)
1712 char *msg_in = NULL, *msg_out = NULL;
1715 /* Check input arguments */
1716 if (file_name == NULL ||
1717 strlen(file_name) == 0 ||
1718 msg_in_len_max == 0 ||
1719 msg_out_len_max == 0)
1722 msg_in = malloc(msg_in_len_max + 1);
1723 msg_out = malloc(msg_out_len_max + 1);
1724 if (msg_in == NULL ||
1731 /* Open input file */
1732 f = fopen(file_name, "r");
1741 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
1744 printf("%s", msg_in);
1747 softnic_cli_process(msg_in,
1752 if (strlen(msg_out))
1753 printf("%s", msg_out);