1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_cycles.h>
12 #include <rte_string_fns.h>
13 #include <rte_cryptodev.h>
15 #include "rte_eth_softnic_internals.h"
18 #ifndef CMD_MAX_TOKENS
19 #define CMD_MAX_TOKENS 256
22 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
23 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
24 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
25 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
26 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
27 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
28 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
29 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
30 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
31 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
32 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
37 if ((strlen(in) && index("!#%;", in[0])) ||
38 (strncmp(in, "//", 2) == 0) ||
39 (strncmp(in, "--", 2) == 0))
46 * mempool <mempool_name>
47 * buffer <buffer_size>
52 cmd_mempool(struct pmd_internals *softnic,
58 struct softnic_mempool_params p;
60 struct softnic_mempool *mempool;
63 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
69 if (strcmp(tokens[2], "buffer") != 0) {
70 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
74 if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
75 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
79 if (strcmp(tokens[4], "pool") != 0) {
80 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
84 if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
85 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
89 if (strcmp(tokens[6], "cache") != 0) {
90 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
94 if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
95 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
99 mempool = softnic_mempool_create(softnic, name, &p);
100 if (mempool == NULL) {
101 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
108 * dev <device_name> | port <port_id>
111 cmd_link(struct pmd_internals *softnic,
117 struct softnic_link_params p;
118 struct softnic_link *link;
121 memset(&p, 0, sizeof(p));
124 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
129 if (strcmp(tokens[2], "dev") == 0) {
130 p.dev_name = tokens[3];
131 } else if (strcmp(tokens[2], "port") == 0) {
134 if (softnic_parser_read_uint16(&p.port_id, tokens[3]) != 0) {
135 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
139 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
143 link = softnic_link_create(softnic, name, &p);
145 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
155 cmd_swq(struct pmd_internals *softnic,
161 struct softnic_swq_params p;
163 struct softnic_swq *swq;
166 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
172 if (strcmp(tokens[2], "size") != 0) {
173 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
177 if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
178 snprintf(out, out_size, MSG_ARG_INVALID, "size");
182 swq = softnic_swq_create(softnic, name, &p);
184 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
190 * tmgr shaper profile
192 * rate <tb_rate> size <tb_size>
193 * adj <packet_length_adjust>
196 cmd_tmgr_shaper_profile(struct pmd_internals *softnic,
202 struct rte_tm_shaper_params sp;
203 struct rte_tm_error error;
204 uint32_t shaper_profile_id;
208 memset(&sp, 0, sizeof(struct rte_tm_shaper_params));
210 if (n_tokens != 11) {
211 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
215 if (strcmp(tokens[1], "shaper") != 0) {
216 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
220 if (strcmp(tokens[2], "profile") != 0) {
221 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
225 if (strcmp(tokens[3], "id") != 0) {
226 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
230 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[4]) != 0) {
231 snprintf(out, out_size, MSG_ARG_INVALID, "profile_id");
235 if (strcmp(tokens[5], "rate") != 0) {
236 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
240 if (softnic_parser_read_uint64(&sp.peak.rate, tokens[6]) != 0) {
241 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
245 if (strcmp(tokens[7], "size") != 0) {
246 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
250 if (softnic_parser_read_uint64(&sp.peak.size, tokens[8]) != 0) {
251 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
255 if (strcmp(tokens[9], "adj") != 0) {
256 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "adj");
260 if (softnic_parser_read_int32(&sp.pkt_length_adjust, tokens[10]) != 0) {
261 snprintf(out, out_size, MSG_ARG_INVALID, "packet_length_adjust");
265 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
269 status = rte_tm_shaper_profile_add(port_id, shaper_profile_id, &sp, &error);
271 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
278 * id <shared_shaper_id>
279 * profile <shaper_profile_id>
282 cmd_tmgr_shared_shaper(struct pmd_internals *softnic,
288 struct rte_tm_error error;
289 uint32_t shared_shaper_id, shaper_profile_id;
294 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
298 if (strcmp(tokens[1], "shared") != 0) {
299 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared");
303 if (strcmp(tokens[2], "shaper") != 0) {
304 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
308 if (strcmp(tokens[3], "id") != 0) {
309 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
313 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[4]) != 0) {
314 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
318 if (strcmp(tokens[5], "profile") != 0) {
319 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
323 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[6]) != 0) {
324 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
328 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
332 status = rte_tm_shared_shaper_add_update(port_id,
337 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
345 * parent <parent_node_id | none>
346 * priority <priority>
348 * [shaper profile <shaper_profile_id>]
349 * [shared shaper <shared_shaper_id>]
350 * [nonleaf sp <n_sp_priorities>]
353 cmd_tmgr_node(struct pmd_internals *softnic,
359 struct rte_tm_error error;
360 struct rte_tm_node_params np;
361 uint32_t node_id, parent_node_id, priority, weight, shared_shaper_id;
365 memset(&np, 0, sizeof(struct rte_tm_node_params));
366 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
367 np.nonleaf.n_sp_priorities = 1;
370 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
374 if (strcmp(tokens[1], "node") != 0) {
375 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "node");
379 if (strcmp(tokens[2], "id") != 0) {
380 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
384 if (softnic_parser_read_uint32(&node_id, tokens[3]) != 0) {
385 snprintf(out, out_size, MSG_ARG_INVALID, "node_id");
389 if (strcmp(tokens[4], "parent") != 0) {
390 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "parent");
394 if (strcmp(tokens[5], "none") == 0)
395 parent_node_id = RTE_TM_NODE_ID_NULL;
397 if (softnic_parser_read_uint32(&parent_node_id, tokens[5]) != 0) {
398 snprintf(out, out_size, MSG_ARG_INVALID, "parent_node_id");
403 if (strcmp(tokens[6], "priority") != 0) {
404 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
408 if (softnic_parser_read_uint32(&priority, tokens[7]) != 0) {
409 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
413 if (strcmp(tokens[8], "weight") != 0) {
414 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight");
418 if (softnic_parser_read_uint32(&weight, tokens[9]) != 0) {
419 snprintf(out, out_size, MSG_ARG_INVALID, "weight");
427 (strcmp(tokens[0], "shaper") == 0) &&
428 (strcmp(tokens[1], "profile") == 0)) {
430 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
434 if (strcmp(tokens[2], "none") == 0) {
435 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
437 if (softnic_parser_read_uint32(&np.shaper_profile_id, tokens[2]) != 0) {
438 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
445 } /* shaper profile */
448 (strcmp(tokens[0], "shared") == 0) &&
449 (strcmp(tokens[1], "shaper") == 0)) {
451 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
455 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[2]) != 0) {
456 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
460 np.shared_shaper_id = &shared_shaper_id;
461 np.n_shared_shapers = 1;
465 } /* shared shaper */
468 (strcmp(tokens[0], "nonleaf") == 0) &&
469 (strcmp(tokens[1], "sp") == 0)) {
471 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
475 if (softnic_parser_read_uint32(&np.nonleaf.n_sp_priorities, tokens[2]) != 0) {
476 snprintf(out, out_size, MSG_ARG_INVALID, "n_sp_priorities");
482 } /* nonleaf sp <n_sp_priorities> */
485 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
489 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
493 status = rte_tm_node_add(port_id,
498 RTE_TM_NODE_LEVEL_ID_ANY,
502 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
508 root_node_id(uint32_t n_spp,
511 uint32_t n_queues = n_spp * n_pps * RTE_SCHED_QUEUES_PER_PIPE;
512 uint32_t n_tc = n_spp * n_pps * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
513 uint32_t n_pipes = n_spp * n_pps;
515 return n_queues + n_tc + n_pipes + n_spp;
519 subport_node_id(uint32_t n_spp,
523 uint32_t n_pipes = n_spp * n_pps;
524 uint32_t n_tc = n_pipes * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
525 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
527 return n_queues + n_tc + n_pipes + subport_id;
531 pipe_node_id(uint32_t n_spp,
536 uint32_t n_pipes = n_spp * n_pps;
537 uint32_t n_tc = n_pipes * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
538 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
547 tc_node_id(uint32_t n_spp,
553 uint32_t n_pipes = n_spp * n_pps;
554 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
558 (pipe_id + subport_id * n_pps) * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
562 queue_node_id(uint32_t n_spp __rte_unused,
570 tc_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
571 (pipe_id + subport_id * n_pps) * RTE_SCHED_QUEUES_PER_PIPE;
574 struct tmgr_hierarchy_default_params {
575 uint32_t n_spp; /**< Number of subports per port. */
576 uint32_t n_pps; /**< Number of pipes per subport. */
582 uint32_t tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
586 uint32_t tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
587 uint32_t tc_valid[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
591 uint32_t queue[RTE_SCHED_QUEUES_PER_PIPE];
596 tmgr_hierarchy_default(struct pmd_internals *softnic,
597 struct tmgr_hierarchy_default_params *params)
599 struct rte_tm_node_params root_node_params = {
600 .shaper_profile_id = params->shaper_profile_id.port,
602 .n_sp_priorities = 1,
606 struct rte_tm_node_params subport_node_params = {
607 .shaper_profile_id = params->shaper_profile_id.subport,
609 .n_sp_priorities = 1,
613 struct rte_tm_node_params pipe_node_params = {
614 .shaper_profile_id = params->shaper_profile_id.pipe,
616 .n_sp_priorities = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE,
620 struct rte_tm_node_params tc_node_params[] = {
622 .shaper_profile_id = params->shaper_profile_id.tc[0],
623 .shared_shaper_id = ¶ms->shared_shaper_id.tc[0],
625 (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0,
627 .n_sp_priorities = 1,
632 .shaper_profile_id = params->shaper_profile_id.tc[1],
633 .shared_shaper_id = ¶ms->shared_shaper_id.tc[1],
635 (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0,
637 .n_sp_priorities = 1,
642 .shaper_profile_id = params->shaper_profile_id.tc[2],
643 .shared_shaper_id = ¶ms->shared_shaper_id.tc[2],
645 (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0,
647 .n_sp_priorities = 1,
652 .shaper_profile_id = params->shaper_profile_id.tc[3],
653 .shared_shaper_id = ¶ms->shared_shaper_id.tc[3],
655 (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0,
657 .n_sp_priorities = 1,
662 struct rte_tm_node_params queue_node_params = {
663 .shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE,
666 struct rte_tm_error error;
667 uint32_t n_spp = params->n_spp, n_pps = params->n_pps, s;
671 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
675 /* Hierarchy level 0: Root node */
676 status = rte_tm_node_add(port_id,
677 root_node_id(n_spp, n_pps),
681 RTE_TM_NODE_LEVEL_ID_ANY,
687 /* Hierarchy level 1: Subport nodes */
688 for (s = 0; s < params->n_spp; s++) {
691 status = rte_tm_node_add(port_id,
692 subport_node_id(n_spp, n_pps, s),
693 root_node_id(n_spp, n_pps),
696 RTE_TM_NODE_LEVEL_ID_ANY,
697 &subport_node_params,
702 /* Hierarchy level 2: Pipe nodes */
703 for (p = 0; p < params->n_pps; p++) {
706 status = rte_tm_node_add(port_id,
707 pipe_node_id(n_spp, n_pps, s, p),
708 subport_node_id(n_spp, n_pps, s),
711 RTE_TM_NODE_LEVEL_ID_ANY,
717 /* Hierarchy level 3: Traffic class nodes */
718 for (t = 0; t < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; t++) {
721 status = rte_tm_node_add(port_id,
722 tc_node_id(n_spp, n_pps, s, p, t),
723 pipe_node_id(n_spp, n_pps, s, p),
726 RTE_TM_NODE_LEVEL_ID_ANY,
732 /* Hierarchy level 4: Queue nodes */
733 for (q = 0; q < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; q++) {
734 status = rte_tm_node_add(port_id,
735 queue_node_id(n_spp, n_pps, s, p, t, q),
736 tc_node_id(n_spp, n_pps, s, p, t),
738 params->weight.queue[q],
739 RTE_TM_NODE_LEVEL_ID_ANY,
754 * tmgr hierarchy-default
755 * spp <n_subports_per_port>
756 * pps <n_pipes_per_subport>
759 * subport <profile_id>
771 * queue <q0> ... <q15>
774 cmd_tmgr_hierarchy_default(struct pmd_internals *softnic,
780 struct tmgr_hierarchy_default_params p;
783 memset(&p, 0, sizeof(p));
785 if (n_tokens != 50) {
786 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
790 if (strcmp(tokens[1], "hierarchy-default") != 0) {
791 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "hierarchy-default");
795 if (strcmp(tokens[2], "spp") != 0) {
796 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
800 if (softnic_parser_read_uint32(&p.n_spp, tokens[3]) != 0) {
801 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
805 if (strcmp(tokens[4], "pps") != 0) {
806 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
810 if (softnic_parser_read_uint32(&p.n_pps, tokens[5]) != 0) {
811 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
817 if (strcmp(tokens[6], "shaper") != 0) {
818 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
822 if (strcmp(tokens[7], "profile") != 0) {
823 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
827 if (strcmp(tokens[8], "port") != 0) {
828 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
832 if (softnic_parser_read_uint32(&p.shaper_profile_id.port, tokens[9]) != 0) {
833 snprintf(out, out_size, MSG_ARG_INVALID, "port profile id");
837 if (strcmp(tokens[10], "subport") != 0) {
838 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "subport");
842 if (softnic_parser_read_uint32(&p.shaper_profile_id.subport, tokens[11]) != 0) {
843 snprintf(out, out_size, MSG_ARG_INVALID, "subport profile id");
847 if (strcmp(tokens[12], "pipe") != 0) {
848 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
852 if (softnic_parser_read_uint32(&p.shaper_profile_id.pipe, tokens[13]) != 0) {
853 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
857 if (strcmp(tokens[14], "tc0") != 0) {
858 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0");
862 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[0], tokens[15]) != 0) {
863 snprintf(out, out_size, MSG_ARG_INVALID, "tc0 profile id");
867 if (strcmp(tokens[16], "tc1") != 0) {
868 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1");
872 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[1], tokens[17]) != 0) {
873 snprintf(out, out_size, MSG_ARG_INVALID, "tc1 profile id");
877 if (strcmp(tokens[18], "tc2") != 0) {
878 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2");
882 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[2], tokens[19]) != 0) {
883 snprintf(out, out_size, MSG_ARG_INVALID, "tc2 profile id");
887 if (strcmp(tokens[20], "tc3") != 0) {
888 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3");
892 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[3], tokens[21]) != 0) {
893 snprintf(out, out_size, MSG_ARG_INVALID, "tc3 profile id");
899 if (strcmp(tokens[22], "shared") != 0) {
900 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared");
904 if (strcmp(tokens[23], "shaper") != 0) {
905 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
909 if (strcmp(tokens[24], "tc0") != 0) {
910 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0");
914 if (strcmp(tokens[25], "none") == 0)
915 p.shared_shaper_id.tc_valid[0] = 0;
917 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], tokens[25]) != 0) {
918 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc0");
922 p.shared_shaper_id.tc_valid[0] = 1;
925 if (strcmp(tokens[26], "tc1") != 0) {
926 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1");
930 if (strcmp(tokens[27], "none") == 0)
931 p.shared_shaper_id.tc_valid[1] = 0;
933 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], tokens[27]) != 0) {
934 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc1");
938 p.shared_shaper_id.tc_valid[1] = 1;
941 if (strcmp(tokens[28], "tc2") != 0) {
942 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2");
946 if (strcmp(tokens[29], "none") == 0)
947 p.shared_shaper_id.tc_valid[2] = 0;
949 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], tokens[29]) != 0) {
950 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc2");
954 p.shared_shaper_id.tc_valid[2] = 1;
957 if (strcmp(tokens[30], "tc3") != 0) {
958 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3");
962 if (strcmp(tokens[31], "none") == 0)
963 p.shared_shaper_id.tc_valid[3] = 0;
965 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], tokens[31]) != 0) {
966 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc3");
970 p.shared_shaper_id.tc_valid[3] = 1;
975 if (strcmp(tokens[32], "weight") != 0) {
976 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight");
980 if (strcmp(tokens[33], "queue") != 0) {
981 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queue");
985 for (i = 0; i < 16; i++) {
986 if (softnic_parser_read_uint32(&p.weight.queue[i], tokens[34 + i]) != 0) {
987 snprintf(out, out_size, MSG_ARG_INVALID, "weight queue");
992 status = tmgr_hierarchy_default(softnic, &p);
994 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1000 * tmgr hierarchy commit
1003 cmd_tmgr_hierarchy_commit(struct pmd_internals *softnic,
1009 struct rte_tm_error error;
1013 if (n_tokens != 3) {
1014 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1018 if (strcmp(tokens[1], "hierarchy") != 0) {
1019 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "hierarchy");
1023 if (strcmp(tokens[2], "commit") != 0) {
1024 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "commit");
1028 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
1032 status = rte_tm_hierarchy_commit(port_id, 1, &error);
1034 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1043 cmd_tmgr(struct pmd_internals *softnic,
1050 struct softnic_tmgr_port *tmgr_port;
1052 if (n_tokens != 2) {
1053 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1059 tmgr_port = softnic_tmgr_port_create(softnic, name);
1060 if (tmgr_port == NULL) {
1061 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1070 cmd_tap(struct pmd_internals *softnic,
1077 struct softnic_tap *tap;
1079 if (n_tokens != 2) {
1080 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1086 tap = softnic_tap_create(softnic, name);
1088 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1094 * cryptodev <tap_name> dev <device_name> | dev_id <device_id>
1095 * queue <n_queues> <queue_size>
1099 cmd_cryptodev(struct pmd_internals *softnic,
1105 struct softnic_cryptodev_params params;
1108 memset(¶ms, 0, sizeof(params));
1109 if (n_tokens != 7) {
1110 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1116 if (strcmp(tokens[2], "dev") == 0)
1117 params.dev_name = tokens[3];
1118 else if (strcmp(tokens[2], "dev_id") == 0) {
1119 if (softnic_parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
1120 snprintf(out, out_size, MSG_ARG_INVALID,
1125 snprintf(out, out_size, MSG_ARG_INVALID,
1130 if (strcmp(tokens[4], "queue")) {
1131 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1136 if (softnic_parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
1137 snprintf(out, out_size, MSG_ARG_INVALID,
1142 if (softnic_parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
1143 snprintf(out, out_size, MSG_ARG_INVALID,
1148 if (softnic_cryptodev_create(softnic, name, ¶ms) == NULL) {
1149 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1155 * port in action profile <profile_name>
1156 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
1157 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
1160 cmd_port_in_action_profile(struct pmd_internals *softnic,
1166 struct softnic_port_in_action_profile_params p;
1167 struct softnic_port_in_action_profile *ap;
1171 memset(&p, 0, sizeof(p));
1174 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1178 if (strcmp(tokens[1], "in") != 0) {
1179 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1183 if (strcmp(tokens[2], "action") != 0) {
1184 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1188 if (strcmp(tokens[3], "profile") != 0) {
1189 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1197 if (t0 < n_tokens &&
1198 (strcmp(tokens[t0], "filter") == 0)) {
1201 if (n_tokens < t0 + 10) {
1202 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
1206 if (strcmp(tokens[t0 + 1], "match") == 0) {
1207 p.fltr.filter_on_match = 1;
1208 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
1209 p.fltr.filter_on_match = 0;
1211 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
1215 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1216 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1220 if (softnic_parser_read_uint32(&p.fltr.key_offset,
1221 tokens[t0 + 3]) != 0) {
1222 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1226 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1227 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1231 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
1232 if ((softnic_parse_hex_string(tokens[t0 + 5],
1233 p.fltr.key_mask, &size) != 0) ||
1234 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
1235 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1239 if (strcmp(tokens[t0 + 6], "key") != 0) {
1240 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1244 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
1245 if ((softnic_parse_hex_string(tokens[t0 + 7],
1246 p.fltr.key, &size) != 0) ||
1247 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
1248 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
1252 if (strcmp(tokens[t0 + 8], "port") != 0) {
1253 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1257 if (softnic_parser_read_uint32(&p.fltr.port_id,
1258 tokens[t0 + 9]) != 0) {
1259 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1263 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
1267 if (t0 < n_tokens &&
1268 (strcmp(tokens[t0], "balance") == 0)) {
1271 if (n_tokens < t0 + 22) {
1272 snprintf(out, out_size, MSG_ARG_MISMATCH,
1273 "port in action profile balance");
1277 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1278 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1282 if (softnic_parser_read_uint32(&p.lb.key_offset,
1283 tokens[t0 + 2]) != 0) {
1284 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1288 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1289 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1293 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1294 if (softnic_parse_hex_string(tokens[t0 + 4],
1295 p.lb.key_mask, &p.lb.key_size) != 0) {
1296 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1300 if (strcmp(tokens[t0 + 5], "port") != 0) {
1301 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1305 for (i = 0; i < 16; i++)
1306 if (softnic_parser_read_uint32(&p.lb.port_id[i],
1307 tokens[t0 + 6 + i]) != 0) {
1308 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1312 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
1316 if (t0 < n_tokens) {
1317 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1321 ap = softnic_port_in_action_profile_create(softnic, name, &p);
1323 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1329 * table action profile <profile_name>
1331 * offset <ip_offset>
1333 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
1334 * [meter srtcm | trtcm
1336 * stats none | pkts | bytes | both]
1337 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
1338 * [encap ether | vlan | qinq | mpls | pppoe |
1339 * vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]
1343 * stats none | pkts]
1344 * [stats pkts | bytes | both]
1351 cmd_table_action_profile(struct pmd_internals *softnic,
1357 struct softnic_table_action_profile_params p;
1358 struct softnic_table_action_profile *ap;
1362 memset(&p, 0, sizeof(p));
1365 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1369 if (strcmp(tokens[1], "action") != 0) {
1370 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1374 if (strcmp(tokens[2], "profile") != 0) {
1375 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1381 if (strcmp(tokens[4], "ipv4") == 0) {
1382 p.common.ip_version = 1;
1383 } else if (strcmp(tokens[4], "ipv6") == 0) {
1384 p.common.ip_version = 0;
1386 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1390 if (strcmp(tokens[5], "offset") != 0) {
1391 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1395 if (softnic_parser_read_uint32(&p.common.ip_offset,
1397 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1401 if (strcmp(tokens[7], "fwd") != 0) {
1402 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1406 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1409 if (t0 < n_tokens &&
1410 (strcmp(tokens[t0], "balance") == 0)) {
1411 if (n_tokens < t0 + 7) {
1412 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1416 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1421 if (softnic_parser_read_uint32(&p.lb.key_offset,
1422 tokens[t0 + 2]) != 0) {
1423 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1427 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1428 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1432 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1433 if (softnic_parse_hex_string(tokens[t0 + 4],
1434 p.lb.key_mask, &p.lb.key_size) != 0) {
1435 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1439 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1440 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1444 if (softnic_parser_read_uint32(&p.lb.out_offset,
1445 tokens[t0 + 6]) != 0) {
1446 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1450 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1454 if (t0 < n_tokens &&
1455 (strcmp(tokens[t0], "meter") == 0)) {
1456 if (n_tokens < t0 + 6) {
1457 snprintf(out, out_size, MSG_ARG_MISMATCH,
1458 "table action profile meter");
1462 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
1463 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1464 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
1465 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1467 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1472 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1473 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1477 if (softnic_parser_read_uint32(&p.mtr.n_tc,
1478 tokens[t0 + 3]) != 0) {
1479 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1483 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1484 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1488 if (strcmp(tokens[t0 + 5], "none") == 0) {
1489 p.mtr.n_packets_enabled = 0;
1490 p.mtr.n_bytes_enabled = 0;
1491 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1492 p.mtr.n_packets_enabled = 1;
1493 p.mtr.n_bytes_enabled = 0;
1494 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1495 p.mtr.n_packets_enabled = 0;
1496 p.mtr.n_bytes_enabled = 1;
1497 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1498 p.mtr.n_packets_enabled = 1;
1499 p.mtr.n_bytes_enabled = 1;
1501 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1502 "none or pkts or bytes or both");
1506 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1510 if (t0 < n_tokens &&
1511 (strcmp(tokens[t0], "tm") == 0)) {
1512 if (n_tokens < t0 + 5) {
1513 snprintf(out, out_size, MSG_ARG_MISMATCH,
1514 "table action profile tm");
1518 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1519 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1523 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
1524 tokens[t0 + 2]) != 0) {
1525 snprintf(out, out_size, MSG_ARG_INVALID,
1526 "n_subports_per_port");
1530 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1531 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1535 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
1536 tokens[t0 + 4]) != 0) {
1537 snprintf(out, out_size, MSG_ARG_INVALID,
1538 "n_pipes_per_subport");
1542 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1546 if (t0 < n_tokens &&
1547 (strcmp(tokens[t0], "encap") == 0)) {
1548 uint32_t n_extra_tokens = 0;
1550 if (n_tokens < t0 + 2) {
1551 snprintf(out, out_size, MSG_ARG_MISMATCH,
1552 "action profile encap");
1556 if (strcmp(tokens[t0 + 1], "ether") == 0) {
1557 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1558 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
1559 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1560 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
1561 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1562 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
1563 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1564 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
1565 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1566 } else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
1567 if (n_tokens < t0 + 2 + 5) {
1568 snprintf(out, out_size, MSG_ARG_MISMATCH,
1569 "action profile encap vxlan");
1573 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1574 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1579 if (softnic_parser_read_uint32(&p.encap.vxlan.data_offset,
1580 tokens[t0 + 2 + 1]) != 0) {
1581 snprintf(out, out_size, MSG_ARG_INVALID,
1582 "vxlan: ether_offset");
1586 if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
1587 p.encap.vxlan.ip_version = 1;
1588 else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
1589 p.encap.vxlan.ip_version = 0;
1591 snprintf(out, out_size, MSG_ARG_INVALID,
1592 "vxlan: ipv4 or ipv6");
1596 if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
1597 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1602 if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
1603 p.encap.vxlan.vlan = 1;
1604 else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
1605 p.encap.vxlan.vlan = 0;
1607 snprintf(out, out_size, MSG_ARG_INVALID,
1608 "vxlan: on or off");
1612 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
1616 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1619 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1620 t0 += 2 + n_extra_tokens;
1623 if (t0 < n_tokens &&
1624 (strcmp(tokens[t0], "nat") == 0)) {
1625 if (n_tokens < t0 + 4) {
1626 snprintf(out, out_size, MSG_ARG_MISMATCH,
1627 "table action profile nat");
1631 if (strcmp(tokens[t0 + 1], "src") == 0) {
1632 p.nat.source_nat = 1;
1633 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
1634 p.nat.source_nat = 0;
1636 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1641 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1642 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1646 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
1648 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
1651 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1656 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1660 if (t0 < n_tokens &&
1661 (strcmp(tokens[t0], "ttl") == 0)) {
1662 if (n_tokens < t0 + 4) {
1663 snprintf(out, out_size, MSG_ARG_MISMATCH,
1664 "table action profile ttl");
1668 if (strcmp(tokens[t0 + 1], "drop") == 0) {
1670 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
1673 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1678 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1679 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1683 if (strcmp(tokens[t0 + 3], "none") == 0) {
1684 p.ttl.n_packets_enabled = 0;
1685 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
1686 p.ttl.n_packets_enabled = 1;
1688 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1693 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1697 if (t0 < n_tokens &&
1698 (strcmp(tokens[t0], "stats") == 0)) {
1699 if (n_tokens < t0 + 2) {
1700 snprintf(out, out_size, MSG_ARG_MISMATCH,
1701 "table action profile stats");
1705 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1706 p.stats.n_packets_enabled = 1;
1707 p.stats.n_bytes_enabled = 0;
1708 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1709 p.stats.n_packets_enabled = 0;
1710 p.stats.n_bytes_enabled = 1;
1711 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1712 p.stats.n_packets_enabled = 1;
1713 p.stats.n_bytes_enabled = 1;
1715 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1716 "pkts or bytes or both");
1720 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1724 if (t0 < n_tokens &&
1725 (strcmp(tokens[t0], "time") == 0)) {
1726 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1730 if (t0 < n_tokens &&
1731 (strcmp(tokens[t0], "tag") == 0)) {
1732 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1736 if (t0 < n_tokens &&
1737 (strcmp(tokens[t0], "decap") == 0)) {
1738 p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
1742 if (t0 < n_tokens) {
1743 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1747 ap = softnic_table_action_profile_create(softnic, name, &p);
1749 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1755 * pipeline <pipeline_name>
1756 * period <timer_period_ms>
1757 * offset_port_id <offset_port_id>
1760 cmd_pipeline(struct pmd_internals *softnic,
1766 struct pipeline_params p;
1768 struct pipeline *pipeline;
1770 if (n_tokens != 6) {
1771 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1777 if (strcmp(tokens[2], "period") != 0) {
1778 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1782 if (softnic_parser_read_uint32(&p.timer_period_ms,
1784 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1788 if (strcmp(tokens[4], "offset_port_id") != 0) {
1789 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1793 if (softnic_parser_read_uint32(&p.offset_port_id,
1795 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1799 pipeline = softnic_pipeline_create(softnic, name, &p);
1800 if (pipeline == NULL) {
1801 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1807 * pipeline <pipeline_name> port in
1809 * link <link_name> rxq <queue_id>
1811 * | tmgr <tmgr_name>
1812 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
1813 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
1814 * | cryptodev <cryptodev_name> rxq <queue_id>
1815 * [action <port_in_action_profile_name>]
1819 cmd_pipeline_port_in(struct pmd_internals *softnic,
1825 struct softnic_port_in_params p;
1826 char *pipeline_name;
1828 int enabled, status;
1830 memset(&p, 0, sizeof(p));
1833 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1837 pipeline_name = tokens[1];
1839 if (strcmp(tokens[2], "port") != 0) {
1840 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1844 if (strcmp(tokens[3], "in") != 0) {
1845 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1849 if (strcmp(tokens[4], "bsz") != 0) {
1850 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1854 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1855 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1861 if (strcmp(tokens[t0], "link") == 0) {
1862 if (n_tokens < t0 + 4) {
1863 snprintf(out, out_size, MSG_ARG_MISMATCH,
1864 "pipeline port in link");
1868 p.type = PORT_IN_RXQ;
1870 strcpy(p.dev_name, tokens[t0 + 1]);
1872 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1873 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1877 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1878 tokens[t0 + 3]) != 0) {
1879 snprintf(out, out_size, MSG_ARG_INVALID,
1884 } else if (strcmp(tokens[t0], "swq") == 0) {
1885 if (n_tokens < t0 + 2) {
1886 snprintf(out, out_size, MSG_ARG_MISMATCH,
1887 "pipeline port in swq");
1891 p.type = PORT_IN_SWQ;
1893 strcpy(p.dev_name, tokens[t0 + 1]);
1896 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1897 if (n_tokens < t0 + 2) {
1898 snprintf(out, out_size, MSG_ARG_MISMATCH,
1899 "pipeline port in tmgr");
1903 p.type = PORT_IN_TMGR;
1905 strcpy(p.dev_name, tokens[t0 + 1]);
1908 } else if (strcmp(tokens[t0], "tap") == 0) {
1909 if (n_tokens < t0 + 6) {
1910 snprintf(out, out_size, MSG_ARG_MISMATCH,
1911 "pipeline port in tap");
1915 p.type = PORT_IN_TAP;
1917 strcpy(p.dev_name, tokens[t0 + 1]);
1919 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1920 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1925 p.tap.mempool_name = tokens[t0 + 3];
1927 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1928 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1933 if (softnic_parser_read_uint32(&p.tap.mtu,
1934 tokens[t0 + 5]) != 0) {
1935 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1940 } else if (strcmp(tokens[t0], "source") == 0) {
1941 if (n_tokens < t0 + 6) {
1942 snprintf(out, out_size, MSG_ARG_MISMATCH,
1943 "pipeline port in source");
1947 p.type = PORT_IN_SOURCE;
1949 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1950 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1955 p.source.mempool_name = tokens[t0 + 2];
1957 if (strcmp(tokens[t0 + 3], "file") != 0) {
1958 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1963 p.source.file_name = tokens[t0 + 4];
1965 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1966 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1971 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1972 tokens[t0 + 6]) != 0) {
1973 snprintf(out, out_size, MSG_ARG_INVALID,
1979 } else if (strcmp(tokens[t0], "cryptodev") == 0) {
1980 if (n_tokens < t0 + 3) {
1981 snprintf(out, out_size, MSG_ARG_MISMATCH,
1982 "pipeline port in cryptodev");
1986 p.type = PORT_IN_CRYPTODEV;
1988 strlcpy(p.dev_name, tokens[t0 + 1], sizeof(p.dev_name));
1989 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1990 tokens[t0 + 3]) != 0) {
1991 snprintf(out, out_size, MSG_ARG_INVALID,
1996 p.cryptodev.arg_callback = NULL;
1997 p.cryptodev.f_callback = NULL;
2001 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2005 if (n_tokens > t0 &&
2006 (strcmp(tokens[t0], "action") == 0)) {
2007 if (n_tokens < t0 + 2) {
2008 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2012 strcpy(p.action_profile_name, tokens[t0 + 1]);
2018 if (n_tokens > t0 &&
2019 (strcmp(tokens[t0], "disabled") == 0)) {
2025 if (n_tokens != t0) {
2026 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2030 status = softnic_pipeline_port_in_create(softnic,
2035 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2041 * pipeline <pipeline_name> port out
2043 * link <link_name> txq <txq_id>
2045 * | tmgr <tmgr_name>
2047 * | sink [file <file_name> pkts <max_n_pkts>]
2048 * | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>
2051 cmd_pipeline_port_out(struct pmd_internals *softnic,
2057 struct softnic_port_out_params p;
2058 char *pipeline_name;
2061 memset(&p, 0, sizeof(p));
2064 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2068 pipeline_name = tokens[1];
2070 if (strcmp(tokens[2], "port") != 0) {
2071 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2075 if (strcmp(tokens[3], "out") != 0) {
2076 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2080 if (strcmp(tokens[4], "bsz") != 0) {
2081 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
2085 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
2086 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
2090 if (strcmp(tokens[6], "link") == 0) {
2091 if (n_tokens != 10) {
2092 snprintf(out, out_size, MSG_ARG_MISMATCH,
2093 "pipeline port out link");
2097 p.type = PORT_OUT_TXQ;
2099 strcpy(p.dev_name, tokens[7]);
2101 if (strcmp(tokens[8], "txq") != 0) {
2102 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
2106 if (softnic_parser_read_uint16(&p.txq.queue_id,
2108 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
2111 } else if (strcmp(tokens[6], "swq") == 0) {
2112 if (n_tokens != 8) {
2113 snprintf(out, out_size, MSG_ARG_MISMATCH,
2114 "pipeline port out swq");
2118 p.type = PORT_OUT_SWQ;
2120 strcpy(p.dev_name, tokens[7]);
2121 } else if (strcmp(tokens[6], "tmgr") == 0) {
2122 if (n_tokens != 8) {
2123 snprintf(out, out_size, MSG_ARG_MISMATCH,
2124 "pipeline port out tmgr");
2128 p.type = PORT_OUT_TMGR;
2130 strcpy(p.dev_name, tokens[7]);
2131 } else if (strcmp(tokens[6], "tap") == 0) {
2132 if (n_tokens != 8) {
2133 snprintf(out, out_size, MSG_ARG_MISMATCH,
2134 "pipeline port out tap");
2138 p.type = PORT_OUT_TAP;
2140 strcpy(p.dev_name, tokens[7]);
2141 } else if (strcmp(tokens[6], "sink") == 0) {
2142 if ((n_tokens != 7) && (n_tokens != 11)) {
2143 snprintf(out, out_size, MSG_ARG_MISMATCH,
2144 "pipeline port out sink");
2148 p.type = PORT_OUT_SINK;
2150 if (n_tokens == 7) {
2151 p.sink.file_name = NULL;
2152 p.sink.max_n_pkts = 0;
2154 if (strcmp(tokens[7], "file") != 0) {
2155 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2160 p.sink.file_name = tokens[8];
2162 if (strcmp(tokens[9], "pkts") != 0) {
2163 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
2167 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
2169 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
2173 } else if (strcmp(tokens[6], "cryptodev") == 0) {
2174 if (n_tokens != 12) {
2175 snprintf(out, out_size, MSG_ARG_MISMATCH,
2176 "pipeline port out cryptodev");
2180 p.type = PORT_OUT_CRYPTODEV;
2182 strlcpy(p.dev_name, tokens[7], sizeof(p.dev_name));
2184 if (strcmp(tokens[8], "txq")) {
2185 snprintf(out, out_size, MSG_ARG_MISMATCH,
2186 "pipeline port out cryptodev");
2190 if (softnic_parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
2192 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
2196 if (strcmp(tokens[10], "offset")) {
2197 snprintf(out, out_size, MSG_ARG_MISMATCH,
2198 "pipeline port out cryptodev");
2202 if (softnic_parser_read_uint32(&p.cryptodev.op_offset,
2204 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
2208 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2212 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
2214 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2220 * pipeline <pipeline_name> table
2224 * offset <ip_header_offset>
2227 * offset <key_offset>
2233 * offset <key_offset>
2234 * buckets <n_buckets>
2238 * offset <ip_header_offset>
2241 * [action <table_action_profile_name>]
2244 cmd_pipeline_table(struct pmd_internals *softnic,
2250 struct softnic_table_params p;
2251 char *pipeline_name;
2255 memset(&p, 0, sizeof(p));
2258 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2262 pipeline_name = tokens[1];
2264 if (strcmp(tokens[2], "table") != 0) {
2265 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2269 if (strcmp(tokens[3], "match") != 0) {
2270 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2275 if (strcmp(tokens[t0], "acl") == 0) {
2276 if (n_tokens < t0 + 6) {
2277 snprintf(out, out_size, MSG_ARG_MISMATCH,
2278 "pipeline table acl");
2282 p.match_type = TABLE_ACL;
2284 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2285 p.match.acl.ip_version = 1;
2286 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2287 p.match.acl.ip_version = 0;
2289 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2294 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2295 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2299 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
2300 tokens[t0 + 3]) != 0) {
2301 snprintf(out, out_size, MSG_ARG_INVALID,
2302 "ip_header_offset");
2306 if (strcmp(tokens[t0 + 4], "size") != 0) {
2307 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2311 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
2312 tokens[t0 + 5]) != 0) {
2313 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2318 } else if (strcmp(tokens[t0], "array") == 0) {
2319 if (n_tokens < t0 + 5) {
2320 snprintf(out, out_size, MSG_ARG_MISMATCH,
2321 "pipeline table array");
2325 p.match_type = TABLE_ARRAY;
2327 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2328 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2332 if (softnic_parser_read_uint32(&p.match.array.key_offset,
2333 tokens[t0 + 2]) != 0) {
2334 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2338 if (strcmp(tokens[t0 + 3], "size") != 0) {
2339 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2343 if (softnic_parser_read_uint32(&p.match.array.n_keys,
2344 tokens[t0 + 4]) != 0) {
2345 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2350 } else if (strcmp(tokens[t0], "hash") == 0) {
2351 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2353 if (n_tokens < t0 + 12) {
2354 snprintf(out, out_size, MSG_ARG_MISMATCH,
2355 "pipeline table hash");
2359 p.match_type = TABLE_HASH;
2361 if (strcmp(tokens[t0 + 1], "ext") == 0) {
2362 p.match.hash.extendable_bucket = 1;
2363 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
2364 p.match.hash.extendable_bucket = 0;
2366 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2371 if (strcmp(tokens[t0 + 2], "key") != 0) {
2372 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2376 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
2377 tokens[t0 + 3]) != 0) ||
2378 p.match.hash.key_size == 0 ||
2379 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
2380 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2384 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2385 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2389 if ((softnic_parse_hex_string(tokens[t0 + 5],
2390 p.match.hash.key_mask, &key_mask_size) != 0) ||
2391 key_mask_size != p.match.hash.key_size) {
2392 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2396 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2397 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2401 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
2402 tokens[t0 + 7]) != 0) {
2403 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2407 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2408 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2412 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
2413 tokens[t0 + 9]) != 0) {
2414 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2418 if (strcmp(tokens[t0 + 10], "size") != 0) {
2419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2423 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
2424 tokens[t0 + 11]) != 0) {
2425 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2430 } else if (strcmp(tokens[t0], "lpm") == 0) {
2431 if (n_tokens < t0 + 6) {
2432 snprintf(out, out_size, MSG_ARG_MISMATCH,
2433 "pipeline table lpm");
2437 p.match_type = TABLE_LPM;
2439 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2440 p.match.lpm.key_size = 4;
2441 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2442 p.match.lpm.key_size = 16;
2444 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2449 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2450 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2454 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
2455 tokens[t0 + 3]) != 0) {
2456 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2460 if (strcmp(tokens[t0 + 4], "size") != 0) {
2461 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2465 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
2466 tokens[t0 + 5]) != 0) {
2467 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2472 } else if (strcmp(tokens[t0], "stub") == 0) {
2473 p.match_type = TABLE_STUB;
2477 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2481 if (n_tokens > t0 &&
2482 (strcmp(tokens[t0], "action") == 0)) {
2483 if (n_tokens < t0 + 2) {
2484 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2488 strcpy(p.action_profile_name, tokens[t0 + 1]);
2493 if (n_tokens > t0) {
2494 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2498 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
2500 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2506 * pipeline <pipeline_name> port in <port_id> table <table_id>
2509 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
2515 char *pipeline_name;
2516 uint32_t port_id, table_id;
2519 if (n_tokens != 7) {
2520 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2524 pipeline_name = tokens[1];
2526 if (strcmp(tokens[2], "port") != 0) {
2527 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2531 if (strcmp(tokens[3], "in") != 0) {
2532 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2536 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2537 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2541 if (strcmp(tokens[5], "table") != 0) {
2542 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2546 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
2547 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2551 status = softnic_pipeline_port_in_connect_to_table(softnic,
2556 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2562 * pipeline <pipeline_name> port in <port_id> stats read [clear]
2565 #define MSG_PIPELINE_PORT_IN_STATS \
2566 "Pkts in: %" PRIu64 "\n" \
2567 "Pkts dropped by AH: %" PRIu64 "\n" \
2568 "Pkts dropped by other: %" PRIu64 "\n"
2571 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
2577 struct rte_pipeline_port_in_stats stats;
2578 char *pipeline_name;
2582 if (n_tokens != 7 &&
2584 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2588 pipeline_name = tokens[1];
2590 if (strcmp(tokens[2], "port") != 0) {
2591 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2595 if (strcmp(tokens[3], "in") != 0) {
2596 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2600 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2601 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2605 if (strcmp(tokens[5], "stats") != 0) {
2606 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2610 if (strcmp(tokens[6], "read") != 0) {
2611 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2616 if (n_tokens == 8) {
2617 if (strcmp(tokens[7], "clear") != 0) {
2618 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2625 status = softnic_pipeline_port_in_stats_read(softnic,
2631 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2635 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2636 stats.stats.n_pkts_in,
2637 stats.n_pkts_dropped_by_ah,
2638 stats.stats.n_pkts_drop);
2642 * pipeline <pipeline_name> port in <port_id> enable
2645 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
2651 char *pipeline_name;
2655 if (n_tokens != 6) {
2656 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2660 pipeline_name = tokens[1];
2662 if (strcmp(tokens[2], "port") != 0) {
2663 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2667 if (strcmp(tokens[3], "in") != 0) {
2668 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2672 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2673 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2677 if (strcmp(tokens[5], "enable") != 0) {
2678 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2682 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
2684 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2690 * pipeline <pipeline_name> port in <port_id> disable
2693 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
2699 char *pipeline_name;
2703 if (n_tokens != 6) {
2704 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2708 pipeline_name = tokens[1];
2710 if (strcmp(tokens[2], "port") != 0) {
2711 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2715 if (strcmp(tokens[3], "in") != 0) {
2716 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2720 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2721 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2725 if (strcmp(tokens[5], "disable") != 0) {
2726 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2730 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2732 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2738 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2740 #define MSG_PIPELINE_PORT_OUT_STATS \
2741 "Pkts in: %" PRIu64 "\n" \
2742 "Pkts dropped by AH: %" PRIu64 "\n" \
2743 "Pkts dropped by other: %" PRIu64 "\n"
2746 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2752 struct rte_pipeline_port_out_stats stats;
2753 char *pipeline_name;
2757 if (n_tokens != 7 &&
2759 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2763 pipeline_name = tokens[1];
2765 if (strcmp(tokens[2], "port") != 0) {
2766 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2770 if (strcmp(tokens[3], "out") != 0) {
2771 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2775 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2776 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2780 if (strcmp(tokens[5], "stats") != 0) {
2781 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2785 if (strcmp(tokens[6], "read") != 0) {
2786 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2791 if (n_tokens == 8) {
2792 if (strcmp(tokens[7], "clear") != 0) {
2793 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2800 status = softnic_pipeline_port_out_stats_read(softnic,
2806 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2810 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2811 stats.stats.n_pkts_in,
2812 stats.n_pkts_dropped_by_ah,
2813 stats.stats.n_pkts_drop);
2817 * pipeline <pipeline_name> table <table_id> stats read [clear]
2819 #define MSG_PIPELINE_TABLE_STATS \
2820 "Pkts in: %" PRIu64 "\n" \
2821 "Pkts in with lookup miss: %" PRIu64 "\n" \
2822 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2823 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2824 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2825 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2828 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2834 struct rte_pipeline_table_stats stats;
2835 char *pipeline_name;
2839 if (n_tokens != 6 &&
2841 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2845 pipeline_name = tokens[1];
2847 if (strcmp(tokens[2], "table") != 0) {
2848 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2852 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2853 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2857 if (strcmp(tokens[4], "stats") != 0) {
2858 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2862 if (strcmp(tokens[5], "read") != 0) {
2863 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2868 if (n_tokens == 7) {
2869 if (strcmp(tokens[6], "clear") != 0) {
2870 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2877 status = softnic_pipeline_table_stats_read(softnic,
2883 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2887 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2888 stats.stats.n_pkts_in,
2889 stats.stats.n_pkts_lookup_miss,
2890 stats.n_pkts_dropped_by_lkp_hit_ah,
2891 stats.n_pkts_dropped_lkp_hit,
2892 stats.n_pkts_dropped_by_lkp_miss_ah,
2893 stats.n_pkts_dropped_lkp_miss);
2901 * priority <priority>
2902 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2903 * <sp0> <sp1> <dp0> <dp1> <proto>
2907 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2908 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2909 * | ipv4_addr <addr>
2910 * | ipv6_addr <addr>
2911 * | qinq <svlan> <cvlan>
2913 * ipv4 | ipv6 <addr> <depth>
2915 struct pkt_key_qinq {
2916 uint16_t ethertype_svlan;
2918 uint16_t ethertype_cvlan;
2920 } __attribute__((__packed__));
2922 struct pkt_key_ipv4_5tuple {
2923 uint8_t time_to_live;
2925 uint16_t hdr_checksum;
2930 } __attribute__((__packed__));
2932 struct pkt_key_ipv6_5tuple {
2933 uint16_t payload_length;
2940 } __attribute__((__packed__));
2942 struct pkt_key_ipv4_addr {
2944 } __attribute__((__packed__));
2946 struct pkt_key_ipv6_addr {
2948 } __attribute__((__packed__));
2951 parse_match(char **tokens,
2955 struct softnic_table_rule_match *m)
2957 memset(m, 0, sizeof(*m));
2962 if (strcmp(tokens[0], "match") != 0) {
2963 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2967 if (strcmp(tokens[1], "acl") == 0) {
2968 if (n_tokens < 14) {
2969 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2973 m->match_type = TABLE_ACL;
2975 if (strcmp(tokens[2], "priority") != 0) {
2976 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2980 if (softnic_parser_read_uint32(&m->match.acl.priority,
2982 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2986 if (strcmp(tokens[4], "ipv4") == 0) {
2987 struct in_addr saddr, daddr;
2989 m->match.acl.ip_version = 1;
2991 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2992 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2995 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2997 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2998 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3001 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
3002 } else if (strcmp(tokens[4], "ipv6") == 0) {
3003 struct in6_addr saddr, daddr;
3005 m->match.acl.ip_version = 0;
3007 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
3008 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
3011 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
3013 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
3014 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3017 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
3019 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
3024 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
3026 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
3030 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
3032 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
3036 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
3037 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
3041 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
3042 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
3046 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
3047 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
3051 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
3052 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
3056 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
3057 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
3061 m->match.acl.proto_mask = 0xff;
3066 if (strcmp(tokens[1], "array") == 0) {
3068 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3072 m->match_type = TABLE_ARRAY;
3074 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
3075 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
3082 if (strcmp(tokens[1], "hash") == 0) {
3084 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3088 m->match_type = TABLE_HASH;
3090 if (strcmp(tokens[2], "raw") == 0) {
3091 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
3094 snprintf(out, out_size, MSG_ARG_MISMATCH,
3099 if (softnic_parse_hex_string(tokens[3],
3100 m->match.hash.key, &key_size) != 0) {
3101 snprintf(out, out_size, MSG_ARG_INVALID, "key");
3108 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
3109 struct pkt_key_ipv4_5tuple *ipv4 =
3110 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
3111 struct in_addr saddr, daddr;
3116 snprintf(out, out_size, MSG_ARG_MISMATCH,
3121 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
3122 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
3126 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
3127 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3131 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
3132 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
3136 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
3137 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3141 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3142 snprintf(out, out_size, MSG_ARG_INVALID,
3147 ipv4->sa = saddr.s_addr;
3148 ipv4->da = daddr.s_addr;
3149 ipv4->sp = rte_cpu_to_be_16(sp);
3150 ipv4->dp = rte_cpu_to_be_16(dp);
3151 ipv4->proto = proto;
3154 } /* hash ipv4_5tuple */
3156 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
3157 struct pkt_key_ipv6_5tuple *ipv6 =
3158 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
3159 struct in6_addr saddr, daddr;
3164 snprintf(out, out_size, MSG_ARG_MISMATCH,
3169 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
3170 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
3174 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
3175 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3179 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
3180 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
3184 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
3185 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3189 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3190 snprintf(out, out_size, MSG_ARG_INVALID,
3195 memcpy(ipv6->sa, saddr.s6_addr, 16);
3196 memcpy(ipv6->da, daddr.s6_addr, 16);
3197 ipv6->sp = rte_cpu_to_be_16(sp);
3198 ipv6->dp = rte_cpu_to_be_16(dp);
3199 ipv6->proto = proto;
3202 } /* hash ipv6_5tuple */
3204 if (strcmp(tokens[2], "ipv4_addr") == 0) {
3205 struct pkt_key_ipv4_addr *ipv4_addr =
3206 (struct pkt_key_ipv4_addr *)m->match.hash.key;
3207 struct in_addr addr;
3210 snprintf(out, out_size, MSG_ARG_MISMATCH,
3215 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3216 snprintf(out, out_size, MSG_ARG_INVALID,
3221 ipv4_addr->addr = addr.s_addr;
3224 } /* hash ipv4_addr */
3226 if (strcmp(tokens[2], "ipv6_addr") == 0) {
3227 struct pkt_key_ipv6_addr *ipv6_addr =
3228 (struct pkt_key_ipv6_addr *)m->match.hash.key;
3229 struct in6_addr addr;
3232 snprintf(out, out_size, MSG_ARG_MISMATCH,
3237 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3238 snprintf(out, out_size, MSG_ARG_INVALID,
3243 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
3246 } /* hash ipv6_5tuple */
3248 if (strcmp(tokens[2], "qinq") == 0) {
3249 struct pkt_key_qinq *qinq =
3250 (struct pkt_key_qinq *)m->match.hash.key;
3251 uint16_t svlan, cvlan;
3254 snprintf(out, out_size, MSG_ARG_MISMATCH,
3259 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
3261 snprintf(out, out_size, MSG_ARG_INVALID,
3266 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3268 snprintf(out, out_size, MSG_ARG_INVALID,
3273 qinq->svlan = rte_cpu_to_be_16(svlan);
3274 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3279 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3283 if (strcmp(tokens[1], "lpm") == 0) {
3285 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3289 m->match_type = TABLE_LPM;
3291 if (strcmp(tokens[2], "ipv4") == 0) {
3292 struct in_addr addr;
3294 m->match.lpm.ip_version = 1;
3296 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3297 snprintf(out, out_size, MSG_ARG_INVALID,
3302 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3303 } else if (strcmp(tokens[2], "ipv6") == 0) {
3304 struct in6_addr addr;
3306 m->match.lpm.ip_version = 0;
3308 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3309 snprintf(out, out_size, MSG_ARG_INVALID,
3314 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3316 snprintf(out, out_size, MSG_ARG_MISMATCH,
3321 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3322 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3329 snprintf(out, out_size, MSG_ARG_MISMATCH,
3330 "acl or array or hash or lpm");
3342 * | table <table_id>
3343 * [balance <out0> ... <out7>]
3345 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3346 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3347 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3348 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3349 * [tm subport <subport_id> pipe <pipe_id>]
3352 * | vlan <da> <sa> <pcp> <dei> <vid>
3353 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3354 * | mpls unicast | multicast
3356 * label0 <label> <tc> <ttl>
3357 * [label1 <label> <tc> <ttl>
3358 * [label2 <label> <tc> <ttl>
3359 * [label3 <label> <tc> <ttl>]]]
3360 * | pppoe <da> <sa> <session_id>]
3361 * | vxlan ether <da> <sa>
3362 * [vlan <pcp> <dei> <vid>]
3363 * ipv4 <sa> <da> <dscp> <ttl>
3364 * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
3367 * [nat ipv4 | ipv6 <addr> <port>]
3377 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3379 * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
3380 * auth_algo <algo> auth_key <key> digest_size <size>
3382 * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
3383 * digest_size <size>
3384 * data_offset <data_offset>]
3387 * <pa> ::= g | y | r | drop
3390 parse_table_action_fwd(char **tokens,
3392 struct softnic_table_rule_action *a)
3394 if (n_tokens == 0 ||
3395 (strcmp(tokens[0], "fwd") != 0))
3401 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3402 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3403 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3407 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3411 softnic_parser_read_uint32(&id, tokens[1]))
3414 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3416 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3420 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3421 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3422 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3426 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3430 softnic_parser_read_uint32(&id, tokens[1]))
3433 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3435 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3443 parse_table_action_balance(char **tokens,
3445 struct softnic_table_rule_action *a)
3449 if (n_tokens == 0 ||
3450 (strcmp(tokens[0], "balance") != 0))
3456 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3459 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3460 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3463 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3464 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3468 parse_policer_action(char *token, enum rte_table_action_policer *a)
3470 if (strcmp(token, "g") == 0) {
3471 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3475 if (strcmp(token, "y") == 0) {
3476 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3480 if (strcmp(token, "r") == 0) {
3481 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3485 if (strcmp(token, "drop") == 0) {
3486 *a = RTE_TABLE_ACTION_POLICER_DROP;
3494 parse_table_action_meter_tc(char **tokens,
3496 struct rte_table_action_mtr_tc_params *mtr)
3499 strcmp(tokens[0], "meter") ||
3500 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3501 strcmp(tokens[2], "policer") ||
3502 strcmp(tokens[3], "g") ||
3503 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
3504 strcmp(tokens[5], "y") ||
3505 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
3506 strcmp(tokens[7], "r") ||
3507 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
3514 parse_table_action_meter(char **tokens,
3516 struct softnic_table_rule_action *a)
3518 if (n_tokens == 0 ||
3519 strcmp(tokens[0], "meter"))
3525 if (n_tokens < 10 ||
3526 strcmp(tokens[0], "tc0") ||
3527 (parse_table_action_meter_tc(tokens + 1,
3529 &a->mtr.mtr[0]) == 0))
3535 if (n_tokens == 0 ||
3536 strcmp(tokens[0], "tc1")) {
3538 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3542 if (n_tokens < 30 ||
3543 (parse_table_action_meter_tc(tokens + 1,
3544 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3545 strcmp(tokens[10], "tc2") ||
3546 (parse_table_action_meter_tc(tokens + 11,
3547 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3548 strcmp(tokens[20], "tc3") ||
3549 (parse_table_action_meter_tc(tokens + 21,
3550 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3553 a->mtr.tc_mask = 0xF;
3554 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3555 return 1 + 10 + 3 * 10;
3559 parse_table_action_tm(char **tokens,
3561 struct softnic_table_rule_action *a)
3563 uint32_t subport_id, pipe_id;
3566 strcmp(tokens[0], "tm") ||
3567 strcmp(tokens[1], "subport") ||
3568 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
3569 strcmp(tokens[3], "pipe") ||
3570 softnic_parser_read_uint32(&pipe_id, tokens[4]))
3573 a->tm.subport_id = subport_id;
3574 a->tm.pipe_id = pipe_id;
3575 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3580 parse_table_action_encap(char **tokens,
3582 struct softnic_table_rule_action *a)
3584 if (n_tokens == 0 ||
3585 strcmp(tokens[0], "encap"))
3592 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3594 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3595 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3598 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3599 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3604 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3605 uint32_t pcp, dei, vid;
3608 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3609 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3610 softnic_parser_read_uint32(&pcp, tokens[3]) ||
3612 softnic_parser_read_uint32(&dei, tokens[4]) ||
3614 softnic_parser_read_uint32(&vid, tokens[5]) ||
3618 a->encap.vlan.vlan.pcp = pcp & 0x7;
3619 a->encap.vlan.vlan.dei = dei & 0x1;
3620 a->encap.vlan.vlan.vid = vid & 0xFFF;
3621 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3622 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3627 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3628 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3629 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3632 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3633 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3634 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
3636 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
3638 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
3639 svlan_vid > 0xFFF ||
3640 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3642 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
3644 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
3648 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3649 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3650 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3651 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3652 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3653 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3654 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3655 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3660 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3661 uint32_t label, tc, ttl;
3666 if (strcmp(tokens[1], "unicast") == 0)
3667 a->encap.mpls.unicast = 1;
3668 else if (strcmp(tokens[1], "multicast") == 0)
3669 a->encap.mpls.unicast = 0;
3673 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3674 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3675 strcmp(tokens[4], "label0") ||
3676 softnic_parser_read_uint32(&label, tokens[5]) ||
3678 softnic_parser_read_uint32(&tc, tokens[6]) ||
3680 softnic_parser_read_uint32(&ttl, tokens[7]) ||
3684 a->encap.mpls.mpls[0].label = label;
3685 a->encap.mpls.mpls[0].tc = tc;
3686 a->encap.mpls.mpls[0].ttl = ttl;
3691 if (n_tokens == 0 ||
3692 strcmp(tokens[0], "label1")) {
3693 a->encap.mpls.mpls_count = 1;
3694 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3695 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3700 softnic_parser_read_uint32(&label, tokens[1]) ||
3702 softnic_parser_read_uint32(&tc, tokens[2]) ||
3704 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3708 a->encap.mpls.mpls[1].label = label;
3709 a->encap.mpls.mpls[1].tc = tc;
3710 a->encap.mpls.mpls[1].ttl = ttl;
3715 if (n_tokens == 0 ||
3716 strcmp(tokens[0], "label2")) {
3717 a->encap.mpls.mpls_count = 2;
3718 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3719 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3724 softnic_parser_read_uint32(&label, tokens[1]) ||
3726 softnic_parser_read_uint32(&tc, tokens[2]) ||
3728 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3732 a->encap.mpls.mpls[2].label = label;
3733 a->encap.mpls.mpls[2].tc = tc;
3734 a->encap.mpls.mpls[2].ttl = ttl;
3739 if (n_tokens == 0 ||
3740 strcmp(tokens[0], "label3")) {
3741 a->encap.mpls.mpls_count = 3;
3742 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3743 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3744 return 1 + 8 + 4 + 4;
3748 softnic_parser_read_uint32(&label, tokens[1]) ||
3750 softnic_parser_read_uint32(&tc, tokens[2]) ||
3752 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3756 a->encap.mpls.mpls[3].label = label;
3757 a->encap.mpls.mpls[3].tc = tc;
3758 a->encap.mpls.mpls[3].ttl = ttl;
3760 a->encap.mpls.mpls_count = 4;
3761 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3762 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3763 return 1 + 8 + 4 + 4 + 4;
3767 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3769 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3770 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3771 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3775 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3776 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3781 if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
3788 /* ether <da> <sa> */
3789 if ((n_tokens < 3) ||
3790 strcmp(tokens[0], "ether") ||
3791 softnic_parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
3792 softnic_parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
3799 /* [vlan <pcp> <dei> <vid>] */
3800 if (strcmp(tokens[0], "vlan") == 0) {
3801 uint32_t pcp, dei, vid;
3803 if ((n_tokens < 4) ||
3804 softnic_parser_read_uint32(&pcp, tokens[1]) ||
3806 softnic_parser_read_uint32(&dei, tokens[2]) ||
3808 softnic_parser_read_uint32(&vid, tokens[3]) ||
3812 a->encap.vxlan.vlan.pcp = pcp;
3813 a->encap.vxlan.vlan.dei = dei;
3814 a->encap.vxlan.vlan.vid = vid;
3821 /* ipv4 <sa> <da> <dscp> <ttl>
3822 | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
3823 if (strcmp(tokens[0], "ipv4") == 0) {
3824 struct in_addr sa, da;
3827 if ((n_tokens < 5) ||
3828 softnic_parse_ipv4_addr(tokens[1], &sa) ||
3829 softnic_parse_ipv4_addr(tokens[2], &da) ||
3830 softnic_parser_read_uint8(&dscp, tokens[3]) ||
3832 softnic_parser_read_uint8(&ttl, tokens[4]))
3835 a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
3836 a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
3837 a->encap.vxlan.ipv4.dscp = dscp;
3838 a->encap.vxlan.ipv4.ttl = ttl;
3843 } else if (strcmp(tokens[0], "ipv6") == 0) {
3844 struct in6_addr sa, da;
3845 uint32_t flow_label;
3846 uint8_t dscp, hop_limit;
3848 if ((n_tokens < 6) ||
3849 softnic_parse_ipv6_addr(tokens[1], &sa) ||
3850 softnic_parse_ipv6_addr(tokens[2], &da) ||
3851 softnic_parser_read_uint32(&flow_label, tokens[3]) ||
3852 softnic_parser_read_uint8(&dscp, tokens[4]) ||
3854 softnic_parser_read_uint8(&hop_limit, tokens[5]))
3857 memcpy(a->encap.vxlan.ipv6.sa, sa.s6_addr, 16);
3858 memcpy(a->encap.vxlan.ipv6.da, da.s6_addr, 16);
3859 a->encap.vxlan.ipv6.flow_label = flow_label;
3860 a->encap.vxlan.ipv6.dscp = dscp;
3861 a->encap.vxlan.ipv6.hop_limit = hop_limit;
3870 if ((n_tokens < 3) ||
3871 strcmp(tokens[0], "udp") ||
3872 softnic_parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
3873 softnic_parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
3881 if ((n_tokens < 2) ||
3882 strcmp(tokens[0], "vxlan") ||
3883 softnic_parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
3884 (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
3891 a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
3892 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3900 parse_table_action_nat(char **tokens,
3902 struct softnic_table_rule_action *a)
3905 strcmp(tokens[0], "nat"))
3908 if (strcmp(tokens[1], "ipv4") == 0) {
3909 struct in_addr addr;
3912 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3913 softnic_parser_read_uint16(&port, tokens[3]))
3916 a->nat.ip_version = 1;
3917 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3919 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3923 if (strcmp(tokens[1], "ipv6") == 0) {
3924 struct in6_addr addr;
3927 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3928 softnic_parser_read_uint16(&port, tokens[3]))
3931 a->nat.ip_version = 0;
3932 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3934 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3942 parse_table_action_ttl(char **tokens,
3944 struct softnic_table_rule_action *a)
3947 strcmp(tokens[0], "ttl"))
3950 if (strcmp(tokens[1], "dec") == 0)
3951 a->ttl.decrement = 1;
3952 else if (strcmp(tokens[1], "keep") == 0)
3953 a->ttl.decrement = 0;
3957 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3962 parse_table_action_stats(char **tokens,
3964 struct softnic_table_rule_action *a)
3967 strcmp(tokens[0], "stats"))
3970 a->stats.n_packets = 0;
3971 a->stats.n_bytes = 0;
3972 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3977 parse_table_action_time(char **tokens,
3979 struct softnic_table_rule_action *a)
3982 strcmp(tokens[0], "time"))
3985 a->time.time = rte_rdtsc();
3986 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3991 parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
3993 struct rte_crypto_sym_xform *xform[2] = {NULL};
3996 xform[0] = p->xform;
3998 xform[1] = xform[0]->next;
4000 for (i = 0; i < 2; i++) {
4001 if (xform[i] == NULL)
4004 switch (xform[i]->type) {
4005 case RTE_CRYPTO_SYM_XFORM_CIPHER:
4006 if (xform[i]->cipher.key.data)
4007 free(xform[i]->cipher.key.data);
4008 if (p->cipher_auth.cipher_iv.val)
4009 free(p->cipher_auth.cipher_iv.val);
4010 if (p->cipher_auth.cipher_iv_update.val)
4011 free(p->cipher_auth.cipher_iv_update.val);
4013 case RTE_CRYPTO_SYM_XFORM_AUTH:
4014 if (xform[i]->auth.key.data)
4015 free(xform[i]->cipher.key.data);
4016 if (p->cipher_auth.auth_iv.val)
4017 free(p->cipher_auth.cipher_iv.val);
4018 if (p->cipher_auth.auth_iv_update.val)
4019 free(p->cipher_auth.cipher_iv_update.val);
4021 case RTE_CRYPTO_SYM_XFORM_AEAD:
4022 if (xform[i]->aead.key.data)
4023 free(xform[i]->cipher.key.data);
4025 free(p->aead.iv.val);
4026 if (p->aead.aad.val)
4027 free(p->aead.aad.val);
4036 static struct rte_crypto_sym_xform *
4037 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
4038 char **tokens, uint32_t n_tokens, uint32_t encrypt,
4039 uint32_t *used_n_tokens)
4041 struct rte_crypto_sym_xform *xform_cipher;
4045 if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
4046 strcmp(tokens[3], "cipher_key") ||
4047 strcmp(tokens[5], "cipher_iv"))
4050 xform_cipher = calloc(1, sizeof(*xform_cipher));
4051 if (xform_cipher == NULL)
4054 xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
4055 xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
4056 RTE_CRYPTO_CIPHER_OP_DECRYPT;
4059 status = rte_cryptodev_get_cipher_algo_enum(
4060 &xform_cipher->cipher.algo, tokens[2]);
4065 len = strlen(tokens[4]);
4066 xform_cipher->cipher.key.data = calloc(1, len / 2 + 1);
4067 if (xform_cipher->cipher.key.data == NULL)
4070 status = softnic_parse_hex_string(tokens[4],
4071 xform_cipher->cipher.key.data,
4076 xform_cipher->cipher.key.length = (uint16_t)len;
4079 len = strlen(tokens[6]);
4081 p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
4082 if (p->cipher_auth.cipher_iv.val == NULL)
4085 status = softnic_parse_hex_string(tokens[6],
4086 p->cipher_auth.cipher_iv.val,
4091 xform_cipher->cipher.iv.length = (uint16_t)len;
4092 xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
4093 p->cipher_auth.cipher_iv.length = (uint32_t)len;
4096 return xform_cipher;
4099 if (xform_cipher->cipher.key.data)
4100 free(xform_cipher->cipher.key.data);
4102 if (p->cipher_auth.cipher_iv.val) {
4103 free(p->cipher_auth.cipher_iv.val);
4104 p->cipher_auth.cipher_iv.val = NULL;
4112 static struct rte_crypto_sym_xform *
4113 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
4114 char **tokens, uint32_t n_tokens, uint32_t encrypt,
4115 uint32_t *used_n_tokens)
4117 struct rte_crypto_sym_xform *xform_cipher;
4118 struct rte_crypto_sym_xform *xform_auth;
4122 if (n_tokens < 13 ||
4123 strcmp(tokens[7], "auth_algo") ||
4124 strcmp(tokens[9], "auth_key") ||
4125 strcmp(tokens[11], "digest_size"))
4128 xform_auth = calloc(1, sizeof(*xform_auth));
4129 if (xform_auth == NULL)
4132 xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
4133 xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
4134 RTE_CRYPTO_AUTH_OP_VERIFY;
4137 status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
4143 len = strlen(tokens[10]);
4144 xform_auth->auth.key.data = calloc(1, len / 2 + 1);
4145 if (xform_auth->auth.key.data == NULL)
4148 status = softnic_parse_hex_string(tokens[10],
4149 xform_auth->auth.key.data, (uint32_t *)&len);
4153 xform_auth->auth.key.length = (uint16_t)len;
4155 if (strcmp(tokens[11], "digest_size"))
4158 status = softnic_parser_read_uint16(&xform_auth->auth.digest_length,
4163 xform_cipher = parse_table_action_cipher(p, tokens, 7, encrypt,
4165 if (xform_cipher == NULL)
4168 *used_n_tokens += 6;
4171 xform_cipher->next = xform_auth;
4172 return xform_cipher;
4174 xform_auth->next = xform_cipher;
4179 if (xform_auth->auth.key.data)
4180 free(xform_auth->auth.key.data);
4181 if (p->cipher_auth.auth_iv.val) {
4182 free(p->cipher_auth.auth_iv.val);
4183 p->cipher_auth.auth_iv.val = 0;
4191 static struct rte_crypto_sym_xform *
4192 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
4193 char **tokens, uint32_t n_tokens, uint32_t encrypt,
4194 uint32_t *used_n_tokens)
4196 struct rte_crypto_sym_xform *xform_aead;
4200 if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
4201 strcmp(tokens[3], "aead_key") ||
4202 strcmp(tokens[5], "aead_iv") ||
4203 strcmp(tokens[7], "aead_aad") ||
4204 strcmp(tokens[9], "digest_size"))
4207 xform_aead = calloc(1, sizeof(*xform_aead));
4208 if (xform_aead == NULL)
4211 xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
4212 xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
4213 RTE_CRYPTO_AEAD_OP_DECRYPT;
4216 status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
4222 len = strlen(tokens[4]);
4223 xform_aead->aead.key.data = calloc(1, len / 2 + 1);
4224 if (xform_aead->aead.key.data == NULL)
4227 status = softnic_parse_hex_string(tokens[4], xform_aead->aead.key.data,
4232 xform_aead->aead.key.length = (uint16_t)len;
4235 len = strlen(tokens[6]);
4236 p->aead.iv.val = calloc(1, len / 2 + 1);
4237 if (p->aead.iv.val == NULL)
4240 status = softnic_parse_hex_string(tokens[6], p->aead.iv.val,
4245 xform_aead->aead.iv.length = (uint16_t)len;
4246 xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
4247 p->aead.iv.length = (uint32_t)len;
4250 len = strlen(tokens[8]);
4251 p->aead.aad.val = calloc(1, len / 2 + 1);
4252 if (p->aead.aad.val == NULL)
4255 status = softnic_parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
4259 xform_aead->aead.aad_length = (uint16_t)len;
4260 p->aead.aad.length = (uint32_t)len;
4263 status = softnic_parser_read_uint16(&xform_aead->aead.digest_length,
4268 *used_n_tokens = 11;
4273 if (xform_aead->aead.key.data)
4274 free(xform_aead->aead.key.data);
4275 if (p->aead.iv.val) {
4276 free(p->aead.iv.val);
4277 p->aead.iv.val = NULL;
4279 if (p->aead.aad.val) {
4280 free(p->aead.aad.val);
4281 p->aead.aad.val = NULL;
4291 parse_table_action_sym_crypto(char **tokens,
4293 struct softnic_table_rule_action *a)
4295 struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
4296 struct rte_crypto_sym_xform *xform = NULL;
4297 uint32_t used_n_tokens;
4301 if ((n_tokens < 12) ||
4302 strcmp(tokens[0], "sym_crypto") ||
4303 strcmp(tokens[2], "type"))
4306 memset(p, 0, sizeof(*p));
4308 if (strcmp(tokens[1], "encrypt") == 0)
4313 status = softnic_parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
4317 if (strcmp(tokens[3], "cipher") == 0) {
4321 xform = parse_table_action_cipher(p, tokens, n_tokens, encrypt,
4323 } else if (strcmp(tokens[3], "cipher_auth") == 0) {
4327 xform = parse_table_action_cipher_auth(p, tokens, n_tokens,
4328 encrypt, &used_n_tokens);
4329 } else if (strcmp(tokens[3], "aead") == 0) {
4333 xform = parse_table_action_aead(p, tokens, n_tokens, encrypt,
4342 if (strcmp(tokens[used_n_tokens], "data_offset")) {
4343 parse_free_sym_crypto_param_data(p);
4347 a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
4349 return used_n_tokens + 5;
4353 parse_table_action_tag(char **tokens,
4355 struct softnic_table_rule_action *a)
4358 strcmp(tokens[0], "tag"))
4361 if (softnic_parser_read_uint32(&a->tag.tag, tokens[1]))
4364 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
4369 parse_table_action_decap(char **tokens,
4371 struct softnic_table_rule_action *a)
4374 strcmp(tokens[0], "decap"))
4377 if (softnic_parser_read_uint16(&a->decap.n, tokens[1]))
4380 a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
4385 parse_table_action(char **tokens,
4389 struct softnic_table_rule_action *a)
4391 uint32_t n_tokens0 = n_tokens;
4393 memset(a, 0, sizeof(*a));
4396 strcmp(tokens[0], "action"))
4402 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
4405 n = parse_table_action_fwd(tokens, n_tokens, a);
4407 snprintf(out, out_size, MSG_ARG_INVALID,
4416 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
4419 n = parse_table_action_balance(tokens, n_tokens, a);
4421 snprintf(out, out_size, MSG_ARG_INVALID,
4430 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
4433 n = parse_table_action_meter(tokens, n_tokens, a);
4435 snprintf(out, out_size, MSG_ARG_INVALID,
4444 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
4447 n = parse_table_action_tm(tokens, n_tokens, a);
4449 snprintf(out, out_size, MSG_ARG_INVALID,
4458 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
4461 n = parse_table_action_encap(tokens, n_tokens, a);
4463 snprintf(out, out_size, MSG_ARG_INVALID,
4472 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
4475 n = parse_table_action_nat(tokens, n_tokens, a);
4477 snprintf(out, out_size, MSG_ARG_INVALID,
4486 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
4489 n = parse_table_action_ttl(tokens, n_tokens, a);
4491 snprintf(out, out_size, MSG_ARG_INVALID,
4500 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
4503 n = parse_table_action_stats(tokens, n_tokens, a);
4505 snprintf(out, out_size, MSG_ARG_INVALID,
4514 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
4517 n = parse_table_action_time(tokens, n_tokens, a);
4519 snprintf(out, out_size, MSG_ARG_INVALID,
4528 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
4531 n = parse_table_action_tag(tokens, n_tokens, a);
4533 snprintf(out, out_size, MSG_ARG_INVALID,
4542 if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
4545 n = parse_table_action_decap(tokens, n_tokens, a);
4547 snprintf(out, out_size, MSG_ARG_INVALID,
4556 if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
4559 n = parse_table_action_sym_crypto(tokens, n_tokens, a);
4561 snprintf(out, out_size, MSG_ARG_INVALID,
4562 "action sym_crypto");
4569 if (n_tokens0 - n_tokens == 1) {
4570 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4574 return n_tokens0 - n_tokens;
4578 * pipeline <pipeline_name> table <table_id> rule add
4580 * action <table_action>
4583 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
4589 struct softnic_table_rule_match m;
4590 struct softnic_table_rule_action a;
4591 char *pipeline_name;
4593 uint32_t table_id, t0, n_tokens_parsed;
4597 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4601 pipeline_name = tokens[1];
4603 if (strcmp(tokens[2], "table") != 0) {
4604 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4608 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4609 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4613 if (strcmp(tokens[4], "rule") != 0) {
4614 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4618 if (strcmp(tokens[5], "add") != 0) {
4619 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4626 n_tokens_parsed = parse_match(tokens + t0,
4631 if (n_tokens_parsed == 0)
4633 t0 += n_tokens_parsed;
4636 n_tokens_parsed = parse_table_action(tokens + t0,
4641 if (n_tokens_parsed == 0)
4643 t0 += n_tokens_parsed;
4645 if (t0 != n_tokens) {
4646 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
4650 status = softnic_pipeline_table_rule_add(softnic,
4657 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4663 * pipeline <pipeline_name> table <table_id> rule add
4671 * | table <table_id>
4674 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
4680 struct softnic_table_rule_action action;
4682 char *pipeline_name;
4686 if (n_tokens != 11 &&
4688 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4692 pipeline_name = tokens[1];
4694 if (strcmp(tokens[2], "table") != 0) {
4695 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4699 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4700 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4704 if (strcmp(tokens[4], "rule") != 0) {
4705 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4709 if (strcmp(tokens[5], "add") != 0) {
4710 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4714 if (strcmp(tokens[6], "match") != 0) {
4715 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4719 if (strcmp(tokens[7], "default") != 0) {
4720 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4724 if (strcmp(tokens[8], "action") != 0) {
4725 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4729 if (strcmp(tokens[9], "fwd") != 0) {
4730 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4734 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4736 if (strcmp(tokens[10], "drop") == 0) {
4737 if (n_tokens != 11) {
4738 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4742 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4743 } else if (strcmp(tokens[10], "port") == 0) {
4746 if (n_tokens != 12) {
4747 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4751 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4752 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4756 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4758 } else if (strcmp(tokens[10], "meta") == 0) {
4759 if (n_tokens != 11) {
4760 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4764 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4765 } else if (strcmp(tokens[10], "table") == 0) {
4768 if (n_tokens != 12) {
4769 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4773 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4774 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4778 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4781 snprintf(out, out_size, MSG_ARG_INVALID,
4782 "drop or port or meta or table");
4786 status = softnic_pipeline_table_rule_add_default(softnic,
4792 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4798 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
4801 * - line format: match <match> action <action>
4804 cli_rule_file_process(const char *file_name,
4805 size_t line_len_max,
4806 struct softnic_table_rule_match *m,
4807 struct softnic_table_rule_action *a,
4809 uint32_t *line_number,
4814 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
4820 struct softnic_table_rule_match *match;
4821 struct softnic_table_rule_action *action;
4823 char *pipeline_name, *file_name;
4824 uint32_t table_id, n_rules, n_rules_parsed, line_number;
4827 if (n_tokens != 9) {
4828 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4832 pipeline_name = tokens[1];
4834 if (strcmp(tokens[2], "table") != 0) {
4835 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4839 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4840 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4844 if (strcmp(tokens[4], "rule") != 0) {
4845 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4849 if (strcmp(tokens[5], "add") != 0) {
4850 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4854 if (strcmp(tokens[6], "bulk") != 0) {
4855 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4859 file_name = tokens[7];
4861 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
4863 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
4867 /* Memory allocation. */
4868 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
4869 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
4870 data = calloc(n_rules, sizeof(void *));
4871 if (match == NULL ||
4874 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
4881 /* Load rule file */
4882 n_rules_parsed = n_rules;
4883 status = cli_rule_file_process(file_name,
4892 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4898 if (n_rules_parsed != n_rules) {
4899 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
4907 status = softnic_pipeline_table_rule_add_bulk(softnic,
4915 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4929 * pipeline <pipeline_name> table <table_id> rule delete
4933 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
4939 struct softnic_table_rule_match m;
4940 char *pipeline_name;
4941 uint32_t table_id, n_tokens_parsed, t0;
4945 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4949 pipeline_name = tokens[1];
4951 if (strcmp(tokens[2], "table") != 0) {
4952 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4956 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4957 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4961 if (strcmp(tokens[4], "rule") != 0) {
4962 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4966 if (strcmp(tokens[5], "delete") != 0) {
4967 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4974 n_tokens_parsed = parse_match(tokens + t0,
4979 if (n_tokens_parsed == 0)
4981 t0 += n_tokens_parsed;
4983 if (n_tokens != t0) {
4984 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4988 status = softnic_pipeline_table_rule_delete(softnic,
4993 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4999 * pipeline <pipeline_name> table <table_id> rule delete
5004 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
5010 char *pipeline_name;
5014 if (n_tokens != 8) {
5015 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5019 pipeline_name = tokens[1];
5021 if (strcmp(tokens[2], "table") != 0) {
5022 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5026 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
5027 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5031 if (strcmp(tokens[4], "rule") != 0) {
5032 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
5036 if (strcmp(tokens[5], "delete") != 0) {
5037 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
5041 if (strcmp(tokens[6], "match") != 0) {
5042 snprintf(out, out_size, MSG_ARG_INVALID, "match");
5046 if (strcmp(tokens[7], "default") != 0) {
5047 snprintf(out, out_size, MSG_ARG_INVALID, "default");
5051 status = softnic_pipeline_table_rule_delete_default(softnic,
5055 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5061 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
5064 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
5066 uint32_t n_tokens __rte_unused,
5070 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
5074 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
5075 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
5076 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
5079 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
5085 struct rte_table_action_meter_profile p;
5086 char *pipeline_name;
5087 uint32_t table_id, meter_profile_id;
5091 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5095 pipeline_name = tokens[1];
5097 if (strcmp(tokens[2], "table") != 0) {
5098 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5102 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
5103 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5107 if (strcmp(tokens[4], "meter") != 0) {
5108 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5112 if (strcmp(tokens[5], "profile") != 0) {
5113 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5117 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5118 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5122 if (strcmp(tokens[7], "add") != 0) {
5123 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
5127 if (strcmp(tokens[8], "srtcm") == 0) {
5128 if (n_tokens != 15) {
5129 snprintf(out, out_size, MSG_ARG_MISMATCH,
5134 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
5136 if (strcmp(tokens[9], "cir") != 0) {
5137 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5141 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
5142 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5146 if (strcmp(tokens[11], "cbs") != 0) {
5147 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5151 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
5152 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5156 if (strcmp(tokens[13], "ebs") != 0) {
5157 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
5161 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
5162 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
5165 } else if (strcmp(tokens[8], "trtcm") == 0) {
5166 if (n_tokens != 17) {
5167 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5171 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
5173 if (strcmp(tokens[9], "cir") != 0) {
5174 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
5178 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
5179 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
5183 if (strcmp(tokens[11], "pir") != 0) {
5184 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
5188 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
5189 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
5192 if (strcmp(tokens[13], "cbs") != 0) {
5193 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
5197 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
5198 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
5202 if (strcmp(tokens[15], "pbs") != 0) {
5203 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
5207 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
5208 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
5212 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5216 status = softnic_pipeline_table_mtr_profile_add(softnic,
5222 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5228 * pipeline <pipeline_name> table <table_id>
5229 * meter profile <meter_profile_id> delete
5232 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
5238 char *pipeline_name;
5239 uint32_t table_id, meter_profile_id;
5242 if (n_tokens != 8) {
5243 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5247 pipeline_name = tokens[1];
5249 if (strcmp(tokens[2], "table") != 0) {
5250 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5254 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
5255 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5259 if (strcmp(tokens[4], "meter") != 0) {
5260 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
5264 if (strcmp(tokens[5], "profile") != 0) {
5265 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
5269 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
5270 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
5274 if (strcmp(tokens[7], "delete") != 0) {
5275 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
5279 status = softnic_pipeline_table_mtr_profile_delete(softnic,
5284 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5290 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
5293 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
5295 uint32_t n_tokens __rte_unused,
5299 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
5303 * pipeline <pipeline_name> table <table_id> dscp <file_name>
5306 * - exactly 64 lines
5307 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
5310 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
5311 const char *file_name,
5312 uint32_t *line_number)
5317 /* Check input arguments */
5318 if (dscp_table == NULL ||
5319 file_name == NULL ||
5320 line_number == NULL) {
5326 /* Open input file */
5327 f = fopen(file_name, "r");
5334 for (dscp = 0, l = 1; ; l++) {
5337 enum rte_meter_color color;
5338 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
5340 if (fgets(line, sizeof(line), f) == NULL)
5343 if (is_comment(line))
5346 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
5355 if (dscp >= RTE_DIM(dscp_table->entry) ||
5356 n_tokens != RTE_DIM(tokens) ||
5357 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
5358 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
5359 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
5360 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
5361 (strlen(tokens[2]) != 1)) {
5367 switch (tokens[2][0]) {
5370 color = e_RTE_METER_GREEN;
5375 color = e_RTE_METER_YELLOW;
5380 color = e_RTE_METER_RED;
5389 dscp_table->entry[dscp].tc_id = tc_id;
5390 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
5391 dscp_table->entry[dscp].color = color;
5401 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
5407 struct rte_table_action_dscp_table dscp_table;
5408 char *pipeline_name, *file_name;
5409 uint32_t table_id, line_number;
5412 if (n_tokens != 6) {
5413 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5417 pipeline_name = tokens[1];
5419 if (strcmp(tokens[2], "table") != 0) {
5420 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5424 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
5425 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5429 if (strcmp(tokens[4], "dscp") != 0) {
5430 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
5434 file_name = tokens[5];
5436 status = load_dscp_table(&dscp_table, file_name, &line_number);
5438 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
5442 status = softnic_pipeline_table_dscp_table_update(softnic,
5448 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5454 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
5457 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
5459 uint32_t n_tokens __rte_unused,
5463 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
5467 * thread <thread_id> pipeline <pipeline_name> enable
5470 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
5476 char *pipeline_name;
5480 if (n_tokens != 5) {
5481 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5485 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
5486 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
5490 if (strcmp(tokens[2], "pipeline") != 0) {
5491 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5495 pipeline_name = tokens[3];
5497 if (strcmp(tokens[4], "enable") != 0) {
5498 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
5502 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
5504 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
5510 * thread <thread_id> pipeline <pipeline_name> disable
5513 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
5519 char *pipeline_name;
5523 if (n_tokens != 5) {
5524 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5528 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
5529 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
5533 if (strcmp(tokens[2], "pipeline") != 0) {
5534 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5538 pipeline_name = tokens[3];
5540 if (strcmp(tokens[4], "disable") != 0) {
5541 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
5545 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
5547 snprintf(out, out_size, MSG_CMD_FAIL,
5548 "thread pipeline disable");
5557 * pipeline <pipeline_name>
5561 cmd_softnic_flowapi_map(struct pmd_internals *softnic,
5567 char *pipeline_name;
5568 uint32_t group_id, table_id;
5569 int ingress, status;
5571 if (n_tokens != 9) {
5572 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5576 if (strcmp(tokens[1], "map") != 0) {
5577 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "map");
5581 if (strcmp(tokens[2], "group") != 0) {
5582 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group");
5586 if (softnic_parser_read_uint32(&group_id, tokens[3]) != 0) {
5587 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
5591 if (strcmp(tokens[4], "ingress") == 0) {
5593 } else if (strcmp(tokens[4], "egress") == 0) {
5596 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ingress | egress");
5600 if (strcmp(tokens[5], "pipeline") != 0) {
5601 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
5605 pipeline_name = tokens[6];
5607 if (strcmp(tokens[7], "table") != 0) {
5608 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
5612 if (softnic_parser_read_uint32(&table_id, tokens[8]) != 0) {
5613 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
5617 status = flow_attr_map_set(softnic,
5623 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
5629 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
5631 char *tokens[CMD_MAX_TOKENS];
5632 uint32_t n_tokens = RTE_DIM(tokens);
5633 struct pmd_internals *softnic = arg;
5639 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
5641 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
5648 if (strcmp(tokens[0], "mempool") == 0) {
5649 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
5653 if (strcmp(tokens[0], "link") == 0) {
5654 cmd_link(softnic, tokens, n_tokens, out, out_size);
5658 if (strcmp(tokens[0], "swq") == 0) {
5659 cmd_swq(softnic, tokens, n_tokens, out, out_size);
5663 if (strcmp(tokens[0], "tmgr") == 0) {
5664 if (n_tokens == 2) {
5665 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
5669 if (n_tokens >= 3 &&
5670 (strcmp(tokens[1], "shaper") == 0) &&
5671 (strcmp(tokens[2], "profile") == 0)) {
5672 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
5676 if (n_tokens >= 3 &&
5677 (strcmp(tokens[1], "shared") == 0) &&
5678 (strcmp(tokens[2], "shaper") == 0)) {
5679 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
5683 if (n_tokens >= 2 &&
5684 (strcmp(tokens[1], "node") == 0)) {
5685 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
5689 if (n_tokens >= 2 &&
5690 (strcmp(tokens[1], "hierarchy-default") == 0)) {
5691 cmd_tmgr_hierarchy_default(softnic, tokens, n_tokens, out, out_size);
5695 if (n_tokens >= 3 &&
5696 (strcmp(tokens[1], "hierarchy") == 0) &&
5697 (strcmp(tokens[2], "commit") == 0)) {
5698 cmd_tmgr_hierarchy_commit(softnic, tokens, n_tokens, out, out_size);
5703 if (strcmp(tokens[0], "tap") == 0) {
5704 cmd_tap(softnic, tokens, n_tokens, out, out_size);
5708 if (strcmp(tokens[0], "cryptodev") == 0) {
5709 cmd_cryptodev(softnic, tokens, n_tokens, out, out_size);
5713 if (strcmp(tokens[0], "port") == 0) {
5714 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
5718 if (strcmp(tokens[0], "table") == 0) {
5719 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
5723 if (strcmp(tokens[0], "pipeline") == 0) {
5724 if (n_tokens >= 3 &&
5725 (strcmp(tokens[2], "period") == 0)) {
5726 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
5730 if (n_tokens >= 5 &&
5731 (strcmp(tokens[2], "port") == 0) &&
5732 (strcmp(tokens[3], "in") == 0) &&
5733 (strcmp(tokens[4], "bsz") == 0)) {
5734 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
5738 if (n_tokens >= 5 &&
5739 (strcmp(tokens[2], "port") == 0) &&
5740 (strcmp(tokens[3], "out") == 0) &&
5741 (strcmp(tokens[4], "bsz") == 0)) {
5742 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
5746 if (n_tokens >= 4 &&
5747 (strcmp(tokens[2], "table") == 0) &&
5748 (strcmp(tokens[3], "match") == 0)) {
5749 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
5753 if (n_tokens >= 6 &&
5754 (strcmp(tokens[2], "port") == 0) &&
5755 (strcmp(tokens[3], "in") == 0) &&
5756 (strcmp(tokens[5], "table") == 0)) {
5757 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
5762 if (n_tokens >= 6 &&
5763 (strcmp(tokens[2], "port") == 0) &&
5764 (strcmp(tokens[3], "in") == 0) &&
5765 (strcmp(tokens[5], "stats") == 0)) {
5766 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
5771 if (n_tokens >= 6 &&
5772 (strcmp(tokens[2], "port") == 0) &&
5773 (strcmp(tokens[3], "in") == 0) &&
5774 (strcmp(tokens[5], "enable") == 0)) {
5775 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
5780 if (n_tokens >= 6 &&
5781 (strcmp(tokens[2], "port") == 0) &&
5782 (strcmp(tokens[3], "in") == 0) &&
5783 (strcmp(tokens[5], "disable") == 0)) {
5784 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
5789 if (n_tokens >= 6 &&
5790 (strcmp(tokens[2], "port") == 0) &&
5791 (strcmp(tokens[3], "out") == 0) &&
5792 (strcmp(tokens[5], "stats") == 0)) {
5793 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
5798 if (n_tokens >= 5 &&
5799 (strcmp(tokens[2], "table") == 0) &&
5800 (strcmp(tokens[4], "stats") == 0)) {
5801 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
5806 if (n_tokens >= 7 &&
5807 (strcmp(tokens[2], "table") == 0) &&
5808 (strcmp(tokens[4], "rule") == 0) &&
5809 (strcmp(tokens[5], "add") == 0) &&
5810 (strcmp(tokens[6], "match") == 0)) {
5811 if (n_tokens >= 8 &&
5812 (strcmp(tokens[7], "default") == 0)) {
5813 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
5814 n_tokens, out, out_size);
5818 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
5823 if (n_tokens >= 7 &&
5824 (strcmp(tokens[2], "table") == 0) &&
5825 (strcmp(tokens[4], "rule") == 0) &&
5826 (strcmp(tokens[5], "add") == 0) &&
5827 (strcmp(tokens[6], "bulk") == 0)) {
5828 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
5829 n_tokens, out, out_size);
5833 if (n_tokens >= 7 &&
5834 (strcmp(tokens[2], "table") == 0) &&
5835 (strcmp(tokens[4], "rule") == 0) &&
5836 (strcmp(tokens[5], "delete") == 0) &&
5837 (strcmp(tokens[6], "match") == 0)) {
5838 if (n_tokens >= 8 &&
5839 (strcmp(tokens[7], "default") == 0)) {
5840 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
5841 n_tokens, out, out_size);
5845 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
5850 if (n_tokens >= 7 &&
5851 (strcmp(tokens[2], "table") == 0) &&
5852 (strcmp(tokens[4], "rule") == 0) &&
5853 (strcmp(tokens[5], "read") == 0) &&
5854 (strcmp(tokens[6], "stats") == 0)) {
5855 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
5860 if (n_tokens >= 8 &&
5861 (strcmp(tokens[2], "table") == 0) &&
5862 (strcmp(tokens[4], "meter") == 0) &&
5863 (strcmp(tokens[5], "profile") == 0) &&
5864 (strcmp(tokens[7], "add") == 0)) {
5865 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
5870 if (n_tokens >= 8 &&
5871 (strcmp(tokens[2], "table") == 0) &&
5872 (strcmp(tokens[4], "meter") == 0) &&
5873 (strcmp(tokens[5], "profile") == 0) &&
5874 (strcmp(tokens[7], "delete") == 0)) {
5875 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
5876 n_tokens, out, out_size);
5880 if (n_tokens >= 7 &&
5881 (strcmp(tokens[2], "table") == 0) &&
5882 (strcmp(tokens[4], "rule") == 0) &&
5883 (strcmp(tokens[5], "read") == 0) &&
5884 (strcmp(tokens[6], "meter") == 0)) {
5885 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
5890 if (n_tokens >= 5 &&
5891 (strcmp(tokens[2], "table") == 0) &&
5892 (strcmp(tokens[4], "dscp") == 0)) {
5893 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
5898 if (n_tokens >= 7 &&
5899 (strcmp(tokens[2], "table") == 0) &&
5900 (strcmp(tokens[4], "rule") == 0) &&
5901 (strcmp(tokens[5], "read") == 0) &&
5902 (strcmp(tokens[6], "ttl") == 0)) {
5903 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
5909 if (strcmp(tokens[0], "thread") == 0) {
5910 if (n_tokens >= 5 &&
5911 (strcmp(tokens[4], "enable") == 0)) {
5912 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
5917 if (n_tokens >= 5 &&
5918 (strcmp(tokens[4], "disable") == 0)) {
5919 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
5925 if (strcmp(tokens[0], "flowapi") == 0) {
5926 cmd_softnic_flowapi_map(softnic, tokens, n_tokens, out,
5931 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5935 softnic_cli_script_process(struct pmd_internals *softnic,
5936 const char *file_name,
5937 size_t msg_in_len_max,
5938 size_t msg_out_len_max)
5940 char *msg_in = NULL, *msg_out = NULL;
5943 /* Check input arguments */
5944 if (file_name == NULL ||
5945 (strlen(file_name) == 0) ||
5946 msg_in_len_max == 0 ||
5947 msg_out_len_max == 0)
5950 msg_in = malloc(msg_in_len_max + 1);
5951 msg_out = malloc(msg_out_len_max + 1);
5952 if (msg_in == NULL ||
5959 /* Open input file */
5960 f = fopen(file_name, "r");
5969 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5972 printf("%s", msg_in);
5975 softnic_cli_process(msg_in,
5980 if (strlen(msg_out))
5981 printf("%s", msg_out);
5992 cli_rule_file_process(const char *file_name,
5993 size_t line_len_max,
5994 struct softnic_table_rule_match *m,
5995 struct softnic_table_rule_action *a,
5997 uint32_t *line_number,
6003 uint32_t rule_id, line_id;
6006 /* Check input arguments */
6007 if (file_name == NULL ||
6008 (strlen(file_name) == 0) ||
6009 line_len_max == 0) {
6014 /* Memory allocation */
6015 line = malloc(line_len_max + 1);
6022 f = fopen(file_name, "r");
6030 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
6031 char *tokens[CMD_MAX_TOKENS];
6032 uint32_t n_tokens, n_tokens_parsed, t0;
6034 /* Read next line from file. */
6035 if (fgets(line, line_len_max + 1, f) == NULL)
6039 if (is_comment(line))
6043 n_tokens = RTE_DIM(tokens);
6044 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
6056 n_tokens_parsed = parse_match(tokens + t0,
6061 if (n_tokens_parsed == 0) {
6065 t0 += n_tokens_parsed;
6068 n_tokens_parsed = parse_table_action(tokens + t0,
6073 if (n_tokens_parsed == 0) {
6077 t0 += n_tokens_parsed;
6079 /* Line completed. */
6080 if (t0 < n_tokens) {
6085 /* Increment rule count */
6096 *line_number = line_id;