1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
10 #include <rte_common.h>
11 #include <rte_cycles.h>
13 #include "rte_eth_softnic_internals.h"
16 #ifndef CMD_MAX_TOKENS
17 #define CMD_MAX_TOKENS 256
20 #define MSG_OUT_OF_MEMORY "Not enough memory.\n"
21 #define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
22 #define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
23 #define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
24 #define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
25 #define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
26 #define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
27 #define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
28 #define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
29 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
30 #define MSG_CMD_FAIL "Command \"%s\" failed.\n"
35 if ((strlen(in) && index("!#%;", in[0])) ||
36 (strncmp(in, "//", 2) == 0) ||
37 (strncmp(in, "--", 2) == 0))
44 * mempool <mempool_name>
45 * buffer <buffer_size>
50 cmd_mempool(struct pmd_internals *softnic,
56 struct softnic_mempool_params p;
58 struct softnic_mempool *mempool;
61 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
67 if (strcmp(tokens[2], "buffer") != 0) {
68 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
72 if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
73 snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
77 if (strcmp(tokens[4], "pool") != 0) {
78 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
82 if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
83 snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
87 if (strcmp(tokens[6], "cache") != 0) {
88 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
92 if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
93 snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
97 mempool = softnic_mempool_create(softnic, name, &p);
98 if (mempool == NULL) {
99 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
106 * dev <device_name> | port <port_id>
109 cmd_link(struct pmd_internals *softnic,
115 struct softnic_link_params p;
116 struct softnic_link *link;
119 memset(&p, 0, sizeof(p));
122 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
127 if (strcmp(tokens[2], "dev") == 0) {
128 p.dev_name = tokens[3];
129 } else if (strcmp(tokens[2], "port") == 0) {
132 if (softnic_parser_read_uint16(&p.port_id, tokens[3]) != 0) {
133 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
137 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
141 link = softnic_link_create(softnic, name, &p);
143 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
153 cmd_swq(struct pmd_internals *softnic,
159 struct softnic_swq_params p;
161 struct softnic_swq *swq;
164 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
170 if (strcmp(tokens[2], "size") != 0) {
171 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
175 if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
176 snprintf(out, out_size, MSG_ARG_INVALID, "size");
180 swq = softnic_swq_create(softnic, name, &p);
182 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
188 * tmgr shaper profile
190 * rate <tb_rate> size <tb_size>
191 * adj <packet_length_adjust>
194 cmd_tmgr_shaper_profile(struct pmd_internals *softnic,
200 struct rte_tm_shaper_params sp;
201 struct rte_tm_error error;
202 uint32_t shaper_profile_id;
206 memset(&sp, 0, sizeof(struct rte_tm_shaper_params));
208 if (n_tokens != 11) {
209 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
213 if (strcmp(tokens[1], "shaper") != 0) {
214 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
218 if (strcmp(tokens[2], "profile") != 0) {
219 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
223 if (strcmp(tokens[3], "id") != 0) {
224 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
228 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[4]) != 0) {
229 snprintf(out, out_size, MSG_ARG_INVALID, "profile_id");
233 if (strcmp(tokens[5], "rate") != 0) {
234 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
238 if (softnic_parser_read_uint64(&sp.peak.rate, tokens[6]) != 0) {
239 snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
243 if (strcmp(tokens[7], "size") != 0) {
244 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
248 if (softnic_parser_read_uint64(&sp.peak.size, tokens[8]) != 0) {
249 snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
253 if (strcmp(tokens[9], "adj") != 0) {
254 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "adj");
258 if (softnic_parser_read_int32(&sp.pkt_length_adjust, tokens[10]) != 0) {
259 snprintf(out, out_size, MSG_ARG_INVALID, "packet_length_adjust");
263 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
267 status = rte_tm_shaper_profile_add(port_id, shaper_profile_id, &sp, &error);
269 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
276 * id <shared_shaper_id>
277 * profile <shaper_profile_id>
280 cmd_tmgr_shared_shaper(struct pmd_internals *softnic,
286 struct rte_tm_error error;
287 uint32_t shared_shaper_id, shaper_profile_id;
292 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
296 if (strcmp(tokens[1], "shared") != 0) {
297 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared");
301 if (strcmp(tokens[2], "shaper") != 0) {
302 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
306 if (strcmp(tokens[3], "id") != 0) {
307 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
311 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[4]) != 0) {
312 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
316 if (strcmp(tokens[5], "profile") != 0) {
317 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
321 if (softnic_parser_read_uint32(&shaper_profile_id, tokens[6]) != 0) {
322 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
326 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
330 status = rte_tm_shared_shaper_add_update(port_id,
335 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
343 * parent <parent_node_id | none>
344 * priority <priority>
346 * [shaper profile <shaper_profile_id>]
347 * [shared shaper <shared_shaper_id>]
348 * [nonleaf sp <n_sp_priorities>]
351 cmd_tmgr_node(struct pmd_internals *softnic,
357 struct rte_tm_error error;
358 struct rte_tm_node_params np;
359 uint32_t node_id, parent_node_id, priority, weight, shared_shaper_id;
363 memset(&np, 0, sizeof(struct rte_tm_node_params));
364 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
365 np.nonleaf.n_sp_priorities = 1;
368 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
372 if (strcmp(tokens[1], "node") != 0) {
373 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "node");
377 if (strcmp(tokens[2], "id") != 0) {
378 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "id");
382 if (softnic_parser_read_uint32(&node_id, tokens[3]) != 0) {
383 snprintf(out, out_size, MSG_ARG_INVALID, "node_id");
387 if (strcmp(tokens[4], "parent") != 0) {
388 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "parent");
392 if (strcmp(tokens[5], "none") == 0)
393 parent_node_id = RTE_TM_NODE_ID_NULL;
395 if (softnic_parser_read_uint32(&parent_node_id, tokens[5]) != 0) {
396 snprintf(out, out_size, MSG_ARG_INVALID, "parent_node_id");
401 if (strcmp(tokens[6], "priority") != 0) {
402 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
406 if (softnic_parser_read_uint32(&priority, tokens[7]) != 0) {
407 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
411 if (strcmp(tokens[8], "weight") != 0) {
412 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight");
416 if (softnic_parser_read_uint32(&weight, tokens[9]) != 0) {
417 snprintf(out, out_size, MSG_ARG_INVALID, "weight");
425 (strcmp(tokens[0], "shaper") == 0) &&
426 (strcmp(tokens[1], "profile") == 0)) {
428 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
432 if (strcmp(tokens[2], "none") == 0) {
433 np.shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE;
435 if (softnic_parser_read_uint32(&np.shaper_profile_id, tokens[2]) != 0) {
436 snprintf(out, out_size, MSG_ARG_INVALID, "shaper_profile_id");
443 } /* shaper profile */
446 (strcmp(tokens[0], "shared") == 0) &&
447 (strcmp(tokens[1], "shaper") == 0)) {
449 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
453 if (softnic_parser_read_uint32(&shared_shaper_id, tokens[2]) != 0) {
454 snprintf(out, out_size, MSG_ARG_INVALID, "shared_shaper_id");
458 np.shared_shaper_id = &shared_shaper_id;
459 np.n_shared_shapers = 1;
463 } /* shared shaper */
466 (strcmp(tokens[0], "nonleaf") == 0) &&
467 (strcmp(tokens[1], "sp") == 0)) {
469 snprintf(out, out_size, MSG_ARG_MISMATCH, "tmgr node");
473 if (softnic_parser_read_uint32(&np.nonleaf.n_sp_priorities, tokens[2]) != 0) {
474 snprintf(out, out_size, MSG_ARG_INVALID, "n_sp_priorities");
480 } /* nonleaf sp <n_sp_priorities> */
483 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
487 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
491 status = rte_tm_node_add(port_id,
496 RTE_TM_NODE_LEVEL_ID_ANY,
500 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
506 root_node_id(uint32_t n_spp,
509 uint32_t n_queues = n_spp * n_pps * RTE_SCHED_QUEUES_PER_PIPE;
510 uint32_t n_tc = n_spp * n_pps * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
511 uint32_t n_pipes = n_spp * n_pps;
513 return n_queues + n_tc + n_pipes + n_spp;
517 subport_node_id(uint32_t n_spp,
521 uint32_t n_pipes = n_spp * n_pps;
522 uint32_t n_tc = n_pipes * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
523 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
525 return n_queues + n_tc + n_pipes + subport_id;
529 pipe_node_id(uint32_t n_spp,
534 uint32_t n_pipes = n_spp * n_pps;
535 uint32_t n_tc = n_pipes * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
536 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
545 tc_node_id(uint32_t n_spp,
551 uint32_t n_pipes = n_spp * n_pps;
552 uint32_t n_queues = n_pipes * RTE_SCHED_QUEUES_PER_PIPE;
556 (pipe_id + subport_id * n_pps) * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE;
560 queue_node_id(uint32_t n_spp __rte_unused,
568 tc_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
569 (pipe_id + subport_id * n_pps) * RTE_SCHED_QUEUES_PER_PIPE;
572 struct tmgr_hierarchy_default_params {
573 uint32_t n_spp; /**< Number of subports per port. */
574 uint32_t n_pps; /**< Number of pipes per subport. */
580 uint32_t tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
584 uint32_t tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
585 uint32_t tc_valid[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
589 uint32_t queue[RTE_SCHED_QUEUES_PER_PIPE];
594 tmgr_hierarchy_default(struct pmd_internals *softnic,
595 struct tmgr_hierarchy_default_params *params)
597 struct rte_tm_node_params root_node_params = {
598 .shaper_profile_id = params->shaper_profile_id.port,
600 .n_sp_priorities = 1,
604 struct rte_tm_node_params subport_node_params = {
605 .shaper_profile_id = params->shaper_profile_id.subport,
607 .n_sp_priorities = 1,
611 struct rte_tm_node_params pipe_node_params = {
612 .shaper_profile_id = params->shaper_profile_id.pipe,
614 .n_sp_priorities = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE,
618 struct rte_tm_node_params tc_node_params[] = {
620 .shaper_profile_id = params->shaper_profile_id.tc[0],
621 .shared_shaper_id = ¶ms->shared_shaper_id.tc[0],
623 (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0,
625 .n_sp_priorities = 1,
630 .shaper_profile_id = params->shaper_profile_id.tc[1],
631 .shared_shaper_id = ¶ms->shared_shaper_id.tc[1],
633 (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0,
635 .n_sp_priorities = 1,
640 .shaper_profile_id = params->shaper_profile_id.tc[2],
641 .shared_shaper_id = ¶ms->shared_shaper_id.tc[2],
643 (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0,
645 .n_sp_priorities = 1,
650 .shaper_profile_id = params->shaper_profile_id.tc[3],
651 .shared_shaper_id = ¶ms->shared_shaper_id.tc[3],
653 (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0,
655 .n_sp_priorities = 1,
660 struct rte_tm_node_params queue_node_params = {
661 .shaper_profile_id = RTE_TM_SHAPER_PROFILE_ID_NONE,
664 struct rte_tm_error error;
665 uint32_t n_spp = params->n_spp, n_pps = params->n_pps, s;
669 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
673 /* Hierarchy level 0: Root node */
674 status = rte_tm_node_add(port_id,
675 root_node_id(n_spp, n_pps),
679 RTE_TM_NODE_LEVEL_ID_ANY,
685 /* Hierarchy level 1: Subport nodes */
686 for (s = 0; s < params->n_spp; s++) {
689 status = rte_tm_node_add(port_id,
690 subport_node_id(n_spp, n_pps, s),
691 root_node_id(n_spp, n_pps),
694 RTE_TM_NODE_LEVEL_ID_ANY,
695 &subport_node_params,
700 /* Hierarchy level 2: Pipe nodes */
701 for (p = 0; p < params->n_pps; p++) {
704 status = rte_tm_node_add(port_id,
705 pipe_node_id(n_spp, n_pps, s, p),
706 subport_node_id(n_spp, n_pps, s),
709 RTE_TM_NODE_LEVEL_ID_ANY,
715 /* Hierarchy level 3: Traffic class nodes */
716 for (t = 0; t < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; t++) {
719 status = rte_tm_node_add(port_id,
720 tc_node_id(n_spp, n_pps, s, p, t),
721 pipe_node_id(n_spp, n_pps, s, p),
724 RTE_TM_NODE_LEVEL_ID_ANY,
730 /* Hierarchy level 4: Queue nodes */
731 for (q = 0; q < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; q++) {
732 status = rte_tm_node_add(port_id,
733 queue_node_id(n_spp, n_pps, s, p, t, q),
734 tc_node_id(n_spp, n_pps, s, p, t),
736 params->weight.queue[q],
737 RTE_TM_NODE_LEVEL_ID_ANY,
752 * tmgr hierarchy-default
753 * spp <n_subports_per_port>
754 * pps <n_pipes_per_subport>
757 * subport <profile_id>
769 * queue <q0> ... <q15>
772 cmd_tmgr_hierarchy_default(struct pmd_internals *softnic,
778 struct tmgr_hierarchy_default_params p;
781 memset(&p, 0, sizeof(p));
783 if (n_tokens != 50) {
784 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
788 if (strcmp(tokens[1], "hierarchy-default") != 0) {
789 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "hierarchy-default");
793 if (strcmp(tokens[2], "spp") != 0) {
794 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
798 if (softnic_parser_read_uint32(&p.n_spp, tokens[3]) != 0) {
799 snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
803 if (strcmp(tokens[4], "pps") != 0) {
804 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
808 if (softnic_parser_read_uint32(&p.n_pps, tokens[5]) != 0) {
809 snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
815 if (strcmp(tokens[6], "shaper") != 0) {
816 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
820 if (strcmp(tokens[7], "profile") != 0) {
821 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
825 if (strcmp(tokens[8], "port") != 0) {
826 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
830 if (softnic_parser_read_uint32(&p.shaper_profile_id.port, tokens[9]) != 0) {
831 snprintf(out, out_size, MSG_ARG_INVALID, "port profile id");
835 if (strcmp(tokens[10], "subport") != 0) {
836 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "subport");
840 if (softnic_parser_read_uint32(&p.shaper_profile_id.subport, tokens[11]) != 0) {
841 snprintf(out, out_size, MSG_ARG_INVALID, "subport profile id");
845 if (strcmp(tokens[12], "pipe") != 0) {
846 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
850 if (softnic_parser_read_uint32(&p.shaper_profile_id.pipe, tokens[13]) != 0) {
851 snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
855 if (strcmp(tokens[14], "tc0") != 0) {
856 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0");
860 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[0], tokens[15]) != 0) {
861 snprintf(out, out_size, MSG_ARG_INVALID, "tc0 profile id");
865 if (strcmp(tokens[16], "tc1") != 0) {
866 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1");
870 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[1], tokens[17]) != 0) {
871 snprintf(out, out_size, MSG_ARG_INVALID, "tc1 profile id");
875 if (strcmp(tokens[18], "tc2") != 0) {
876 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2");
880 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[2], tokens[19]) != 0) {
881 snprintf(out, out_size, MSG_ARG_INVALID, "tc2 profile id");
885 if (strcmp(tokens[20], "tc3") != 0) {
886 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3");
890 if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[3], tokens[21]) != 0) {
891 snprintf(out, out_size, MSG_ARG_INVALID, "tc3 profile id");
897 if (strcmp(tokens[22], "shared") != 0) {
898 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared");
902 if (strcmp(tokens[23], "shaper") != 0) {
903 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper");
907 if (strcmp(tokens[24], "tc0") != 0) {
908 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0");
912 if (strcmp(tokens[25], "none") == 0)
913 p.shared_shaper_id.tc_valid[0] = 0;
915 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], tokens[25]) != 0) {
916 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc0");
920 p.shared_shaper_id.tc_valid[0] = 1;
923 if (strcmp(tokens[26], "tc1") != 0) {
924 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1");
928 if (strcmp(tokens[27], "none") == 0)
929 p.shared_shaper_id.tc_valid[1] = 0;
931 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], tokens[27]) != 0) {
932 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc1");
936 p.shared_shaper_id.tc_valid[1] = 1;
939 if (strcmp(tokens[28], "tc2") != 0) {
940 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2");
944 if (strcmp(tokens[29], "none") == 0)
945 p.shared_shaper_id.tc_valid[2] = 0;
947 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], tokens[29]) != 0) {
948 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc2");
952 p.shared_shaper_id.tc_valid[2] = 1;
955 if (strcmp(tokens[30], "tc3") != 0) {
956 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3");
960 if (strcmp(tokens[31], "none") == 0)
961 p.shared_shaper_id.tc_valid[3] = 0;
963 if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], tokens[31]) != 0) {
964 snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc3");
968 p.shared_shaper_id.tc_valid[3] = 1;
973 if (strcmp(tokens[32], "weight") != 0) {
974 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight");
978 if (strcmp(tokens[33], "queue") != 0) {
979 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queue");
983 for (i = 0; i < 16; i++) {
984 if (softnic_parser_read_uint32(&p.weight.queue[i], tokens[34 + i]) != 0) {
985 snprintf(out, out_size, MSG_ARG_INVALID, "weight queue");
990 status = tmgr_hierarchy_default(softnic, &p);
992 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
998 * tmgr hierarchy commit
1001 cmd_tmgr_hierarchy_commit(struct pmd_internals *softnic,
1007 struct rte_tm_error error;
1011 if (n_tokens != 3) {
1012 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1016 if (strcmp(tokens[1], "hierarchy") != 0) {
1017 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "hierarchy");
1021 if (strcmp(tokens[2], "commit") != 0) {
1022 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "commit");
1026 status = rte_eth_dev_get_port_by_name(softnic->params.name, &port_id);
1030 status = rte_tm_hierarchy_commit(port_id, 1, &error);
1032 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1041 cmd_tmgr(struct pmd_internals *softnic,
1048 struct softnic_tmgr_port *tmgr_port;
1050 if (n_tokens != 2) {
1051 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1057 tmgr_port = softnic_tmgr_port_create(softnic, name);
1058 if (tmgr_port == NULL) {
1059 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1068 cmd_tap(struct pmd_internals *softnic,
1075 struct softnic_tap *tap;
1077 if (n_tokens != 2) {
1078 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1084 tap = softnic_tap_create(softnic, name);
1086 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1092 * port in action profile <profile_name>
1093 * [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
1094 * [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
1097 cmd_port_in_action_profile(struct pmd_internals *softnic,
1103 struct softnic_port_in_action_profile_params p;
1104 struct softnic_port_in_action_profile *ap;
1108 memset(&p, 0, sizeof(p));
1111 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1115 if (strcmp(tokens[1], "in") != 0) {
1116 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1120 if (strcmp(tokens[2], "action") != 0) {
1121 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1125 if (strcmp(tokens[3], "profile") != 0) {
1126 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1134 if (t0 < n_tokens &&
1135 (strcmp(tokens[t0], "filter") == 0)) {
1138 if (n_tokens < t0 + 10) {
1139 snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
1143 if (strcmp(tokens[t0 + 1], "match") == 0) {
1144 p.fltr.filter_on_match = 1;
1145 } else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
1146 p.fltr.filter_on_match = 0;
1148 snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
1152 if (strcmp(tokens[t0 + 2], "offset") != 0) {
1153 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1157 if (softnic_parser_read_uint32(&p.fltr.key_offset,
1158 tokens[t0 + 3]) != 0) {
1159 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1163 if (strcmp(tokens[t0 + 4], "mask") != 0) {
1164 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1168 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
1169 if ((softnic_parse_hex_string(tokens[t0 + 5],
1170 p.fltr.key_mask, &size) != 0) ||
1171 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
1172 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1176 if (strcmp(tokens[t0 + 6], "key") != 0) {
1177 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1181 size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
1182 if ((softnic_parse_hex_string(tokens[t0 + 7],
1183 p.fltr.key, &size) != 0) ||
1184 size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
1185 snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
1189 if (strcmp(tokens[t0 + 8], "port") != 0) {
1190 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1194 if (softnic_parser_read_uint32(&p.fltr.port_id,
1195 tokens[t0 + 9]) != 0) {
1196 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1200 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
1204 if (t0 < n_tokens &&
1205 (strcmp(tokens[t0], "balance") == 0)) {
1208 if (n_tokens < t0 + 22) {
1209 snprintf(out, out_size, MSG_ARG_MISMATCH,
1210 "port in action profile balance");
1214 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1215 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1219 if (softnic_parser_read_uint32(&p.lb.key_offset,
1220 tokens[t0 + 2]) != 0) {
1221 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1225 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1226 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1230 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1231 if (softnic_parse_hex_string(tokens[t0 + 4],
1232 p.lb.key_mask, &p.lb.key_size) != 0) {
1233 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1237 if (strcmp(tokens[t0 + 5], "port") != 0) {
1238 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1242 for (i = 0; i < 16; i++)
1243 if (softnic_parser_read_uint32(&p.lb.port_id[i],
1244 tokens[t0 + 6 + i]) != 0) {
1245 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1249 p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
1253 if (t0 < n_tokens) {
1254 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1258 ap = softnic_port_in_action_profile_create(softnic, name, &p);
1260 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1266 * table action profile <profile_name>
1268 * offset <ip_offset>
1270 * [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
1271 * [meter srtcm | trtcm
1273 * stats none | pkts | bytes | both]
1274 * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
1275 * [encap ether | vlan | qinq | mpls | pppoe]
1279 * stats none | pkts]
1280 * [stats pkts | bytes | both]
1286 cmd_table_action_profile(struct pmd_internals *softnic,
1292 struct softnic_table_action_profile_params p;
1293 struct softnic_table_action_profile *ap;
1297 memset(&p, 0, sizeof(p));
1300 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1304 if (strcmp(tokens[1], "action") != 0) {
1305 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1309 if (strcmp(tokens[2], "profile") != 0) {
1310 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1316 if (strcmp(tokens[4], "ipv4") == 0) {
1317 p.common.ip_version = 1;
1318 } else if (strcmp(tokens[4], "ipv6") == 0) {
1319 p.common.ip_version = 0;
1321 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1325 if (strcmp(tokens[5], "offset") != 0) {
1326 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1330 if (softnic_parser_read_uint32(&p.common.ip_offset,
1332 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1336 if (strcmp(tokens[7], "fwd") != 0) {
1337 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1341 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1344 if (t0 < n_tokens &&
1345 (strcmp(tokens[t0], "balance") == 0)) {
1346 if (n_tokens < t0 + 7) {
1347 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1351 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1352 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1356 if (softnic_parser_read_uint32(&p.lb.key_offset,
1357 tokens[t0 + 2]) != 0) {
1358 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1362 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1363 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1367 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1368 if (softnic_parse_hex_string(tokens[t0 + 4],
1369 p.lb.key_mask, &p.lb.key_size) != 0) {
1370 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1374 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1375 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1379 if (softnic_parser_read_uint32(&p.lb.out_offset,
1380 tokens[t0 + 6]) != 0) {
1381 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1385 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1389 if (t0 < n_tokens &&
1390 (strcmp(tokens[t0], "meter") == 0)) {
1391 if (n_tokens < t0 + 6) {
1392 snprintf(out, out_size, MSG_ARG_MISMATCH,
1393 "table action profile meter");
1397 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
1398 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1399 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
1400 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1402 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1407 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1408 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1412 if (softnic_parser_read_uint32(&p.mtr.n_tc,
1413 tokens[t0 + 3]) != 0) {
1414 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1418 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1423 if (strcmp(tokens[t0 + 5], "none") == 0) {
1424 p.mtr.n_packets_enabled = 0;
1425 p.mtr.n_bytes_enabled = 0;
1426 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1427 p.mtr.n_packets_enabled = 1;
1428 p.mtr.n_bytes_enabled = 0;
1429 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1430 p.mtr.n_packets_enabled = 0;
1431 p.mtr.n_bytes_enabled = 1;
1432 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1433 p.mtr.n_packets_enabled = 1;
1434 p.mtr.n_bytes_enabled = 1;
1436 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1437 "none or pkts or bytes or both");
1441 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1445 if (t0 < n_tokens &&
1446 (strcmp(tokens[t0], "tm") == 0)) {
1447 if (n_tokens < t0 + 5) {
1448 snprintf(out, out_size, MSG_ARG_MISMATCH,
1449 "table action profile tm");
1453 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1454 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1458 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
1459 tokens[t0 + 2]) != 0) {
1460 snprintf(out, out_size, MSG_ARG_INVALID,
1461 "n_subports_per_port");
1465 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1466 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1470 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
1471 tokens[t0 + 4]) != 0) {
1472 snprintf(out, out_size, MSG_ARG_INVALID,
1473 "n_pipes_per_subport");
1477 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1481 if (t0 < n_tokens &&
1482 (strcmp(tokens[t0], "encap") == 0)) {
1483 if (n_tokens < t0 + 2) {
1484 snprintf(out, out_size, MSG_ARG_MISMATCH,
1485 "action profile encap");
1489 if (strcmp(tokens[t0 + 1], "ether") == 0) {
1490 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1491 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
1492 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1493 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
1494 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1495 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
1496 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1497 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
1498 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1500 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1504 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1508 if (t0 < n_tokens &&
1509 (strcmp(tokens[t0], "nat") == 0)) {
1510 if (n_tokens < t0 + 4) {
1511 snprintf(out, out_size, MSG_ARG_MISMATCH,
1512 "table action profile nat");
1516 if (strcmp(tokens[t0 + 1], "src") == 0) {
1517 p.nat.source_nat = 1;
1518 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
1519 p.nat.source_nat = 0;
1521 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1526 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1527 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1531 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
1533 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
1536 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1541 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1545 if (t0 < n_tokens &&
1546 (strcmp(tokens[t0], "ttl") == 0)) {
1547 if (n_tokens < t0 + 4) {
1548 snprintf(out, out_size, MSG_ARG_MISMATCH,
1549 "table action profile ttl");
1553 if (strcmp(tokens[t0 + 1], "drop") == 0) {
1555 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
1558 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1563 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1564 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1568 if (strcmp(tokens[t0 + 3], "none") == 0) {
1569 p.ttl.n_packets_enabled = 0;
1570 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
1571 p.ttl.n_packets_enabled = 1;
1573 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1578 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1582 if (t0 < n_tokens &&
1583 (strcmp(tokens[t0], "stats") == 0)) {
1584 if (n_tokens < t0 + 2) {
1585 snprintf(out, out_size, MSG_ARG_MISMATCH,
1586 "table action profile stats");
1590 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1591 p.stats.n_packets_enabled = 1;
1592 p.stats.n_bytes_enabled = 0;
1593 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1594 p.stats.n_packets_enabled = 0;
1595 p.stats.n_bytes_enabled = 1;
1596 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1597 p.stats.n_packets_enabled = 1;
1598 p.stats.n_bytes_enabled = 1;
1600 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1601 "pkts or bytes or both");
1605 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1609 if (t0 < n_tokens &&
1610 (strcmp(tokens[t0], "time") == 0)) {
1611 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1615 if (t0 < n_tokens &&
1616 (strcmp(tokens[t0], "tag") == 0)) {
1617 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1621 if (t0 < n_tokens &&
1622 (strcmp(tokens[t0], "decap") == 0)) {
1623 p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
1627 if (t0 < n_tokens) {
1628 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1632 ap = softnic_table_action_profile_create(softnic, name, &p);
1634 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1640 * pipeline <pipeline_name>
1641 * period <timer_period_ms>
1642 * offset_port_id <offset_port_id>
1645 cmd_pipeline(struct pmd_internals *softnic,
1651 struct pipeline_params p;
1653 struct pipeline *pipeline;
1655 if (n_tokens != 6) {
1656 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1662 if (strcmp(tokens[2], "period") != 0) {
1663 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1667 if (softnic_parser_read_uint32(&p.timer_period_ms,
1669 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1673 if (strcmp(tokens[4], "offset_port_id") != 0) {
1674 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1678 if (softnic_parser_read_uint32(&p.offset_port_id,
1680 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1684 pipeline = softnic_pipeline_create(softnic, name, &p);
1685 if (pipeline == NULL) {
1686 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1692 * pipeline <pipeline_name> port in
1694 * link <link_name> rxq <queue_id>
1696 * | tmgr <tmgr_name>
1697 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
1698 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
1699 * [action <port_in_action_profile_name>]
1703 cmd_pipeline_port_in(struct pmd_internals *softnic,
1709 struct softnic_port_in_params p;
1710 char *pipeline_name;
1712 int enabled, status;
1714 memset(&p, 0, sizeof(p));
1717 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1721 pipeline_name = tokens[1];
1723 if (strcmp(tokens[2], "port") != 0) {
1724 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1728 if (strcmp(tokens[3], "in") != 0) {
1729 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1733 if (strcmp(tokens[4], "bsz") != 0) {
1734 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1738 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1739 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1745 if (strcmp(tokens[t0], "link") == 0) {
1746 if (n_tokens < t0 + 4) {
1747 snprintf(out, out_size, MSG_ARG_MISMATCH,
1748 "pipeline port in link");
1752 p.type = PORT_IN_RXQ;
1754 strcpy(p.dev_name, tokens[t0 + 1]);
1756 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1757 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1761 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1762 tokens[t0 + 3]) != 0) {
1763 snprintf(out, out_size, MSG_ARG_INVALID,
1768 } else if (strcmp(tokens[t0], "swq") == 0) {
1769 if (n_tokens < t0 + 2) {
1770 snprintf(out, out_size, MSG_ARG_MISMATCH,
1771 "pipeline port in swq");
1775 p.type = PORT_IN_SWQ;
1777 strcpy(p.dev_name, tokens[t0 + 1]);
1780 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1781 if (n_tokens < t0 + 2) {
1782 snprintf(out, out_size, MSG_ARG_MISMATCH,
1783 "pipeline port in tmgr");
1787 p.type = PORT_IN_TMGR;
1789 strcpy(p.dev_name, tokens[t0 + 1]);
1792 } else if (strcmp(tokens[t0], "tap") == 0) {
1793 if (n_tokens < t0 + 6) {
1794 snprintf(out, out_size, MSG_ARG_MISMATCH,
1795 "pipeline port in tap");
1799 p.type = PORT_IN_TAP;
1801 strcpy(p.dev_name, tokens[t0 + 1]);
1803 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1804 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1809 p.tap.mempool_name = tokens[t0 + 3];
1811 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1812 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1817 if (softnic_parser_read_uint32(&p.tap.mtu,
1818 tokens[t0 + 5]) != 0) {
1819 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1824 } else if (strcmp(tokens[t0], "source") == 0) {
1825 if (n_tokens < t0 + 6) {
1826 snprintf(out, out_size, MSG_ARG_MISMATCH,
1827 "pipeline port in source");
1831 p.type = PORT_IN_SOURCE;
1833 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1834 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1839 p.source.mempool_name = tokens[t0 + 2];
1841 if (strcmp(tokens[t0 + 3], "file") != 0) {
1842 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1847 p.source.file_name = tokens[t0 + 4];
1849 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1850 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1855 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1856 tokens[t0 + 6]) != 0) {
1857 snprintf(out, out_size, MSG_ARG_INVALID,
1864 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1868 if (n_tokens > t0 &&
1869 (strcmp(tokens[t0], "action") == 0)) {
1870 if (n_tokens < t0 + 2) {
1871 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1875 strcpy(p.action_profile_name, tokens[t0 + 1]);
1881 if (n_tokens > t0 &&
1882 (strcmp(tokens[t0], "disabled") == 0)) {
1888 if (n_tokens != t0) {
1889 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1893 status = softnic_pipeline_port_in_create(softnic,
1898 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1904 * pipeline <pipeline_name> port out
1906 * link <link_name> txq <txq_id>
1908 * | tmgr <tmgr_name>
1910 * | sink [file <file_name> pkts <max_n_pkts>]
1913 cmd_pipeline_port_out(struct pmd_internals *softnic,
1919 struct softnic_port_out_params p;
1920 char *pipeline_name;
1923 memset(&p, 0, sizeof(p));
1926 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1930 pipeline_name = tokens[1];
1932 if (strcmp(tokens[2], "port") != 0) {
1933 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1937 if (strcmp(tokens[3], "out") != 0) {
1938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1942 if (strcmp(tokens[4], "bsz") != 0) {
1943 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1947 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1948 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1952 if (strcmp(tokens[6], "link") == 0) {
1953 if (n_tokens != 10) {
1954 snprintf(out, out_size, MSG_ARG_MISMATCH,
1955 "pipeline port out link");
1959 p.type = PORT_OUT_TXQ;
1961 strcpy(p.dev_name, tokens[7]);
1963 if (strcmp(tokens[8], "txq") != 0) {
1964 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1968 if (softnic_parser_read_uint16(&p.txq.queue_id,
1970 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1973 } else if (strcmp(tokens[6], "swq") == 0) {
1974 if (n_tokens != 8) {
1975 snprintf(out, out_size, MSG_ARG_MISMATCH,
1976 "pipeline port out swq");
1980 p.type = PORT_OUT_SWQ;
1982 strcpy(p.dev_name, tokens[7]);
1983 } else if (strcmp(tokens[6], "tmgr") == 0) {
1984 if (n_tokens != 8) {
1985 snprintf(out, out_size, MSG_ARG_MISMATCH,
1986 "pipeline port out tmgr");
1990 p.type = PORT_OUT_TMGR;
1992 strcpy(p.dev_name, tokens[7]);
1993 } else if (strcmp(tokens[6], "tap") == 0) {
1994 if (n_tokens != 8) {
1995 snprintf(out, out_size, MSG_ARG_MISMATCH,
1996 "pipeline port out tap");
2000 p.type = PORT_OUT_TAP;
2002 strcpy(p.dev_name, tokens[7]);
2003 } else if (strcmp(tokens[6], "sink") == 0) {
2004 if ((n_tokens != 7) && (n_tokens != 11)) {
2005 snprintf(out, out_size, MSG_ARG_MISMATCH,
2006 "pipeline port out sink");
2010 p.type = PORT_OUT_SINK;
2012 if (n_tokens == 7) {
2013 p.sink.file_name = NULL;
2014 p.sink.max_n_pkts = 0;
2016 if (strcmp(tokens[7], "file") != 0) {
2017 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2022 p.sink.file_name = tokens[8];
2024 if (strcmp(tokens[9], "pkts") != 0) {
2025 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
2029 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
2031 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
2036 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2040 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
2042 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2048 * pipeline <pipeline_name> table
2052 * offset <ip_header_offset>
2055 * offset <key_offset>
2061 * offset <key_offset>
2062 * buckets <n_buckets>
2066 * offset <ip_header_offset>
2069 * [action <table_action_profile_name>]
2072 cmd_pipeline_table(struct pmd_internals *softnic,
2078 struct softnic_table_params p;
2079 char *pipeline_name;
2083 memset(&p, 0, sizeof(p));
2086 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2090 pipeline_name = tokens[1];
2092 if (strcmp(tokens[2], "table") != 0) {
2093 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2097 if (strcmp(tokens[3], "match") != 0) {
2098 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2103 if (strcmp(tokens[t0], "acl") == 0) {
2104 if (n_tokens < t0 + 6) {
2105 snprintf(out, out_size, MSG_ARG_MISMATCH,
2106 "pipeline table acl");
2110 p.match_type = TABLE_ACL;
2112 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2113 p.match.acl.ip_version = 1;
2114 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2115 p.match.acl.ip_version = 0;
2117 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2122 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2123 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2127 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
2128 tokens[t0 + 3]) != 0) {
2129 snprintf(out, out_size, MSG_ARG_INVALID,
2130 "ip_header_offset");
2134 if (strcmp(tokens[t0 + 4], "size") != 0) {
2135 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2139 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
2140 tokens[t0 + 5]) != 0) {
2141 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2146 } else if (strcmp(tokens[t0], "array") == 0) {
2147 if (n_tokens < t0 + 5) {
2148 snprintf(out, out_size, MSG_ARG_MISMATCH,
2149 "pipeline table array");
2153 p.match_type = TABLE_ARRAY;
2155 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2156 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2160 if (softnic_parser_read_uint32(&p.match.array.key_offset,
2161 tokens[t0 + 2]) != 0) {
2162 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2166 if (strcmp(tokens[t0 + 3], "size") != 0) {
2167 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2171 if (softnic_parser_read_uint32(&p.match.array.n_keys,
2172 tokens[t0 + 4]) != 0) {
2173 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2178 } else if (strcmp(tokens[t0], "hash") == 0) {
2179 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2181 if (n_tokens < t0 + 12) {
2182 snprintf(out, out_size, MSG_ARG_MISMATCH,
2183 "pipeline table hash");
2187 p.match_type = TABLE_HASH;
2189 if (strcmp(tokens[t0 + 1], "ext") == 0) {
2190 p.match.hash.extendable_bucket = 1;
2191 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
2192 p.match.hash.extendable_bucket = 0;
2194 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2199 if (strcmp(tokens[t0 + 2], "key") != 0) {
2200 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2204 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
2205 tokens[t0 + 3]) != 0) ||
2206 p.match.hash.key_size == 0 ||
2207 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
2208 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2212 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2213 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2217 if ((softnic_parse_hex_string(tokens[t0 + 5],
2218 p.match.hash.key_mask, &key_mask_size) != 0) ||
2219 key_mask_size != p.match.hash.key_size) {
2220 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2224 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2225 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2229 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
2230 tokens[t0 + 7]) != 0) {
2231 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2235 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2236 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2240 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
2241 tokens[t0 + 9]) != 0) {
2242 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2246 if (strcmp(tokens[t0 + 10], "size") != 0) {
2247 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2251 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
2252 tokens[t0 + 11]) != 0) {
2253 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2258 } else if (strcmp(tokens[t0], "lpm") == 0) {
2259 if (n_tokens < t0 + 6) {
2260 snprintf(out, out_size, MSG_ARG_MISMATCH,
2261 "pipeline table lpm");
2265 p.match_type = TABLE_LPM;
2267 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2268 p.match.lpm.key_size = 4;
2269 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2270 p.match.lpm.key_size = 16;
2272 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2277 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2278 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2282 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
2283 tokens[t0 + 3]) != 0) {
2284 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2288 if (strcmp(tokens[t0 + 4], "size") != 0) {
2289 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2293 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
2294 tokens[t0 + 5]) != 0) {
2295 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2300 } else if (strcmp(tokens[t0], "stub") == 0) {
2301 p.match_type = TABLE_STUB;
2305 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2309 if (n_tokens > t0 &&
2310 (strcmp(tokens[t0], "action") == 0)) {
2311 if (n_tokens < t0 + 2) {
2312 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2316 strcpy(p.action_profile_name, tokens[t0 + 1]);
2321 if (n_tokens > t0) {
2322 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2326 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
2328 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2334 * pipeline <pipeline_name> port in <port_id> table <table_id>
2337 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
2343 char *pipeline_name;
2344 uint32_t port_id, table_id;
2347 if (n_tokens != 7) {
2348 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2352 pipeline_name = tokens[1];
2354 if (strcmp(tokens[2], "port") != 0) {
2355 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2359 if (strcmp(tokens[3], "in") != 0) {
2360 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2364 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2365 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2369 if (strcmp(tokens[5], "table") != 0) {
2370 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2374 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
2375 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2379 status = softnic_pipeline_port_in_connect_to_table(softnic,
2384 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2390 * pipeline <pipeline_name> port in <port_id> stats read [clear]
2393 #define MSG_PIPELINE_PORT_IN_STATS \
2394 "Pkts in: %" PRIu64 "\n" \
2395 "Pkts dropped by AH: %" PRIu64 "\n" \
2396 "Pkts dropped by other: %" PRIu64 "\n"
2399 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
2405 struct rte_pipeline_port_in_stats stats;
2406 char *pipeline_name;
2410 if (n_tokens != 7 &&
2412 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2416 pipeline_name = tokens[1];
2418 if (strcmp(tokens[2], "port") != 0) {
2419 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2423 if (strcmp(tokens[3], "in") != 0) {
2424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2428 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2429 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2433 if (strcmp(tokens[5], "stats") != 0) {
2434 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2438 if (strcmp(tokens[6], "read") != 0) {
2439 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2444 if (n_tokens == 8) {
2445 if (strcmp(tokens[7], "clear") != 0) {
2446 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2453 status = softnic_pipeline_port_in_stats_read(softnic,
2459 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2463 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2464 stats.stats.n_pkts_in,
2465 stats.n_pkts_dropped_by_ah,
2466 stats.stats.n_pkts_drop);
2470 * pipeline <pipeline_name> port in <port_id> enable
2473 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
2479 char *pipeline_name;
2483 if (n_tokens != 6) {
2484 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2488 pipeline_name = tokens[1];
2490 if (strcmp(tokens[2], "port") != 0) {
2491 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2495 if (strcmp(tokens[3], "in") != 0) {
2496 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2500 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2501 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2505 if (strcmp(tokens[5], "enable") != 0) {
2506 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2510 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
2512 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2518 * pipeline <pipeline_name> port in <port_id> disable
2521 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
2527 char *pipeline_name;
2531 if (n_tokens != 6) {
2532 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2536 pipeline_name = tokens[1];
2538 if (strcmp(tokens[2], "port") != 0) {
2539 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2543 if (strcmp(tokens[3], "in") != 0) {
2544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2548 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2549 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2553 if (strcmp(tokens[5], "disable") != 0) {
2554 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2558 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2560 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2566 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2568 #define MSG_PIPELINE_PORT_OUT_STATS \
2569 "Pkts in: %" PRIu64 "\n" \
2570 "Pkts dropped by AH: %" PRIu64 "\n" \
2571 "Pkts dropped by other: %" PRIu64 "\n"
2574 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2580 struct rte_pipeline_port_out_stats stats;
2581 char *pipeline_name;
2585 if (n_tokens != 7 &&
2587 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2591 pipeline_name = tokens[1];
2593 if (strcmp(tokens[2], "port") != 0) {
2594 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2598 if (strcmp(tokens[3], "out") != 0) {
2599 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2603 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2604 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2608 if (strcmp(tokens[5], "stats") != 0) {
2609 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2613 if (strcmp(tokens[6], "read") != 0) {
2614 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2619 if (n_tokens == 8) {
2620 if (strcmp(tokens[7], "clear") != 0) {
2621 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2628 status = softnic_pipeline_port_out_stats_read(softnic,
2634 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2638 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2639 stats.stats.n_pkts_in,
2640 stats.n_pkts_dropped_by_ah,
2641 stats.stats.n_pkts_drop);
2645 * pipeline <pipeline_name> table <table_id> stats read [clear]
2647 #define MSG_PIPELINE_TABLE_STATS \
2648 "Pkts in: %" PRIu64 "\n" \
2649 "Pkts in with lookup miss: %" PRIu64 "\n" \
2650 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2651 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2652 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2653 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2656 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2662 struct rte_pipeline_table_stats stats;
2663 char *pipeline_name;
2667 if (n_tokens != 6 &&
2669 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2673 pipeline_name = tokens[1];
2675 if (strcmp(tokens[2], "table") != 0) {
2676 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2680 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2681 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2685 if (strcmp(tokens[4], "stats") != 0) {
2686 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2690 if (strcmp(tokens[5], "read") != 0) {
2691 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2696 if (n_tokens == 7) {
2697 if (strcmp(tokens[6], "clear") != 0) {
2698 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2705 status = softnic_pipeline_table_stats_read(softnic,
2711 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2715 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2716 stats.stats.n_pkts_in,
2717 stats.stats.n_pkts_lookup_miss,
2718 stats.n_pkts_dropped_by_lkp_hit_ah,
2719 stats.n_pkts_dropped_lkp_hit,
2720 stats.n_pkts_dropped_by_lkp_miss_ah,
2721 stats.n_pkts_dropped_lkp_miss);
2729 * priority <priority>
2730 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2731 * <sp0> <sp1> <dp0> <dp1> <proto>
2735 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2736 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2737 * | ipv4_addr <addr>
2738 * | ipv6_addr <addr>
2739 * | qinq <svlan> <cvlan>
2741 * ipv4 | ipv6 <addr> <depth>
2743 struct pkt_key_qinq {
2744 uint16_t ethertype_svlan;
2746 uint16_t ethertype_cvlan;
2748 } __attribute__((__packed__));
2750 struct pkt_key_ipv4_5tuple {
2751 uint8_t time_to_live;
2753 uint16_t hdr_checksum;
2758 } __attribute__((__packed__));
2760 struct pkt_key_ipv6_5tuple {
2761 uint16_t payload_length;
2768 } __attribute__((__packed__));
2770 struct pkt_key_ipv4_addr {
2772 } __attribute__((__packed__));
2774 struct pkt_key_ipv6_addr {
2776 } __attribute__((__packed__));
2779 parse_match(char **tokens,
2783 struct softnic_table_rule_match *m)
2785 memset(m, 0, sizeof(*m));
2790 if (strcmp(tokens[0], "match") != 0) {
2791 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2795 if (strcmp(tokens[1], "acl") == 0) {
2796 if (n_tokens < 14) {
2797 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2801 m->match_type = TABLE_ACL;
2803 if (strcmp(tokens[2], "priority") != 0) {
2804 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2808 if (softnic_parser_read_uint32(&m->match.acl.priority,
2810 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2814 if (strcmp(tokens[4], "ipv4") == 0) {
2815 struct in_addr saddr, daddr;
2817 m->match.acl.ip_version = 1;
2819 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2820 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2823 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2825 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2826 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2829 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2830 } else if (strcmp(tokens[4], "ipv6") == 0) {
2831 struct in6_addr saddr, daddr;
2833 m->match.acl.ip_version = 0;
2835 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2836 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2839 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2841 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2842 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2845 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2847 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2852 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2854 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2858 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2860 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2864 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2865 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2869 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2870 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2874 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2875 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2879 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2880 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2884 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2885 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2889 m->match.acl.proto_mask = 0xff;
2894 if (strcmp(tokens[1], "array") == 0) {
2896 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2900 m->match_type = TABLE_ARRAY;
2902 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2903 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2910 if (strcmp(tokens[1], "hash") == 0) {
2912 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2916 m->match_type = TABLE_HASH;
2918 if (strcmp(tokens[2], "raw") == 0) {
2919 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2922 snprintf(out, out_size, MSG_ARG_MISMATCH,
2927 if (softnic_parse_hex_string(tokens[3],
2928 m->match.hash.key, &key_size) != 0) {
2929 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2936 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2937 struct pkt_key_ipv4_5tuple *ipv4 =
2938 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2939 struct in_addr saddr, daddr;
2944 snprintf(out, out_size, MSG_ARG_MISMATCH,
2949 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2950 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2954 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2955 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2959 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2960 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2964 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2965 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2969 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2970 snprintf(out, out_size, MSG_ARG_INVALID,
2975 ipv4->sa = saddr.s_addr;
2976 ipv4->da = daddr.s_addr;
2977 ipv4->sp = rte_cpu_to_be_16(sp);
2978 ipv4->dp = rte_cpu_to_be_16(dp);
2979 ipv4->proto = proto;
2982 } /* hash ipv4_5tuple */
2984 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2985 struct pkt_key_ipv6_5tuple *ipv6 =
2986 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2987 struct in6_addr saddr, daddr;
2992 snprintf(out, out_size, MSG_ARG_MISMATCH,
2997 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2998 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
3002 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
3003 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3007 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
3008 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
3012 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
3013 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3017 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3018 snprintf(out, out_size, MSG_ARG_INVALID,
3023 memcpy(ipv6->sa, saddr.s6_addr, 16);
3024 memcpy(ipv6->da, daddr.s6_addr, 16);
3025 ipv6->sp = rte_cpu_to_be_16(sp);
3026 ipv6->dp = rte_cpu_to_be_16(dp);
3027 ipv6->proto = proto;
3030 } /* hash ipv6_5tuple */
3032 if (strcmp(tokens[2], "ipv4_addr") == 0) {
3033 struct pkt_key_ipv4_addr *ipv4_addr =
3034 (struct pkt_key_ipv4_addr *)m->match.hash.key;
3035 struct in_addr addr;
3038 snprintf(out, out_size, MSG_ARG_MISMATCH,
3043 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3044 snprintf(out, out_size, MSG_ARG_INVALID,
3049 ipv4_addr->addr = addr.s_addr;
3052 } /* hash ipv4_addr */
3054 if (strcmp(tokens[2], "ipv6_addr") == 0) {
3055 struct pkt_key_ipv6_addr *ipv6_addr =
3056 (struct pkt_key_ipv6_addr *)m->match.hash.key;
3057 struct in6_addr addr;
3060 snprintf(out, out_size, MSG_ARG_MISMATCH,
3065 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3066 snprintf(out, out_size, MSG_ARG_INVALID,
3071 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
3074 } /* hash ipv6_5tuple */
3076 if (strcmp(tokens[2], "qinq") == 0) {
3077 struct pkt_key_qinq *qinq =
3078 (struct pkt_key_qinq *)m->match.hash.key;
3079 uint16_t svlan, cvlan;
3082 snprintf(out, out_size, MSG_ARG_MISMATCH,
3087 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
3089 snprintf(out, out_size, MSG_ARG_INVALID,
3094 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3096 snprintf(out, out_size, MSG_ARG_INVALID,
3101 qinq->svlan = rte_cpu_to_be_16(svlan);
3102 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3107 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3111 if (strcmp(tokens[1], "lpm") == 0) {
3113 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3117 m->match_type = TABLE_LPM;
3119 if (strcmp(tokens[2], "ipv4") == 0) {
3120 struct in_addr addr;
3122 m->match.lpm.ip_version = 1;
3124 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3125 snprintf(out, out_size, MSG_ARG_INVALID,
3130 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3131 } else if (strcmp(tokens[2], "ipv6") == 0) {
3132 struct in6_addr addr;
3134 m->match.lpm.ip_version = 0;
3136 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3137 snprintf(out, out_size, MSG_ARG_INVALID,
3142 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3144 snprintf(out, out_size, MSG_ARG_MISMATCH,
3149 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3150 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3157 snprintf(out, out_size, MSG_ARG_MISMATCH,
3158 "acl or array or hash or lpm");
3170 * | table <table_id>
3171 * [balance <out0> ... <out7>]
3173 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3174 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3175 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3176 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3177 * [tm subport <subport_id> pipe <pipe_id>]
3180 * | vlan <da> <sa> <pcp> <dei> <vid>
3181 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3182 * | mpls unicast | multicast
3184 * label0 <label> <tc> <ttl>
3185 * [label1 <label> <tc> <ttl>
3186 * [label2 <label> <tc> <ttl>
3187 * [label3 <label> <tc> <ttl>]]]
3188 * | pppoe <da> <sa> <session_id>]
3189 * [nat ipv4 | ipv6 <addr> <port>]
3197 * <pa> ::= g | y | r | drop
3200 parse_table_action_fwd(char **tokens,
3202 struct softnic_table_rule_action *a)
3204 if (n_tokens == 0 ||
3205 (strcmp(tokens[0], "fwd") != 0))
3211 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3212 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3213 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3217 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3221 softnic_parser_read_uint32(&id, tokens[1]))
3224 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3226 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3230 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3231 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3232 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3236 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3240 softnic_parser_read_uint32(&id, tokens[1]))
3243 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3245 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3253 parse_table_action_balance(char **tokens,
3255 struct softnic_table_rule_action *a)
3259 if (n_tokens == 0 ||
3260 (strcmp(tokens[0], "balance") != 0))
3266 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3269 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3270 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3273 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3274 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3278 parse_policer_action(char *token, enum rte_table_action_policer *a)
3280 if (strcmp(token, "g") == 0) {
3281 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3285 if (strcmp(token, "y") == 0) {
3286 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3290 if (strcmp(token, "r") == 0) {
3291 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3295 if (strcmp(token, "drop") == 0) {
3296 *a = RTE_TABLE_ACTION_POLICER_DROP;
3304 parse_table_action_meter_tc(char **tokens,
3306 struct rte_table_action_mtr_tc_params *mtr)
3309 strcmp(tokens[0], "meter") ||
3310 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3311 strcmp(tokens[2], "policer") ||
3312 strcmp(tokens[3], "g") ||
3313 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
3314 strcmp(tokens[5], "y") ||
3315 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
3316 strcmp(tokens[7], "r") ||
3317 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
3324 parse_table_action_meter(char **tokens,
3326 struct softnic_table_rule_action *a)
3328 if (n_tokens == 0 ||
3329 strcmp(tokens[0], "meter"))
3335 if (n_tokens < 10 ||
3336 strcmp(tokens[0], "tc0") ||
3337 (parse_table_action_meter_tc(tokens + 1,
3339 &a->mtr.mtr[0]) == 0))
3345 if (n_tokens == 0 ||
3346 strcmp(tokens[0], "tc1")) {
3348 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3352 if (n_tokens < 30 ||
3353 (parse_table_action_meter_tc(tokens + 1,
3354 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3355 strcmp(tokens[10], "tc2") ||
3356 (parse_table_action_meter_tc(tokens + 11,
3357 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3358 strcmp(tokens[20], "tc3") ||
3359 (parse_table_action_meter_tc(tokens + 21,
3360 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3363 a->mtr.tc_mask = 0xF;
3364 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3365 return 1 + 10 + 3 * 10;
3369 parse_table_action_tm(char **tokens,
3371 struct softnic_table_rule_action *a)
3373 uint32_t subport_id, pipe_id;
3376 strcmp(tokens[0], "tm") ||
3377 strcmp(tokens[1], "subport") ||
3378 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
3379 strcmp(tokens[3], "pipe") ||
3380 softnic_parser_read_uint32(&pipe_id, tokens[4]))
3383 a->tm.subport_id = subport_id;
3384 a->tm.pipe_id = pipe_id;
3385 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3390 parse_table_action_encap(char **tokens,
3392 struct softnic_table_rule_action *a)
3394 if (n_tokens == 0 ||
3395 strcmp(tokens[0], "encap"))
3402 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3404 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3405 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3408 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3409 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3414 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3415 uint32_t pcp, dei, vid;
3418 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3419 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3420 softnic_parser_read_uint32(&pcp, tokens[3]) ||
3422 softnic_parser_read_uint32(&dei, tokens[4]) ||
3424 softnic_parser_read_uint32(&vid, tokens[5]) ||
3428 a->encap.vlan.vlan.pcp = pcp & 0x7;
3429 a->encap.vlan.vlan.dei = dei & 0x1;
3430 a->encap.vlan.vlan.vid = vid & 0xFFF;
3431 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3432 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3437 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3438 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3439 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3442 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3443 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3444 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
3446 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
3448 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
3449 svlan_vid > 0xFFF ||
3450 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3452 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
3454 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
3458 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3459 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3460 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3461 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3462 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3463 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3464 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3465 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3470 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3471 uint32_t label, tc, ttl;
3476 if (strcmp(tokens[1], "unicast") == 0)
3477 a->encap.mpls.unicast = 1;
3478 else if (strcmp(tokens[1], "multicast") == 0)
3479 a->encap.mpls.unicast = 0;
3483 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3484 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3485 strcmp(tokens[4], "label0") ||
3486 softnic_parser_read_uint32(&label, tokens[5]) ||
3488 softnic_parser_read_uint32(&tc, tokens[6]) ||
3490 softnic_parser_read_uint32(&ttl, tokens[7]) ||
3494 a->encap.mpls.mpls[0].label = label;
3495 a->encap.mpls.mpls[0].tc = tc;
3496 a->encap.mpls.mpls[0].ttl = ttl;
3501 if (n_tokens == 0 ||
3502 strcmp(tokens[0], "label1")) {
3503 a->encap.mpls.mpls_count = 1;
3504 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3505 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3510 softnic_parser_read_uint32(&label, tokens[1]) ||
3512 softnic_parser_read_uint32(&tc, tokens[2]) ||
3514 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3518 a->encap.mpls.mpls[1].label = label;
3519 a->encap.mpls.mpls[1].tc = tc;
3520 a->encap.mpls.mpls[1].ttl = ttl;
3525 if (n_tokens == 0 ||
3526 strcmp(tokens[0], "label2")) {
3527 a->encap.mpls.mpls_count = 2;
3528 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3529 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3534 softnic_parser_read_uint32(&label, tokens[1]) ||
3536 softnic_parser_read_uint32(&tc, tokens[2]) ||
3538 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3542 a->encap.mpls.mpls[2].label = label;
3543 a->encap.mpls.mpls[2].tc = tc;
3544 a->encap.mpls.mpls[2].ttl = ttl;
3549 if (n_tokens == 0 ||
3550 strcmp(tokens[0], "label3")) {
3551 a->encap.mpls.mpls_count = 3;
3552 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3553 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3554 return 1 + 8 + 4 + 4;
3558 softnic_parser_read_uint32(&label, tokens[1]) ||
3560 softnic_parser_read_uint32(&tc, tokens[2]) ||
3562 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3566 a->encap.mpls.mpls[3].label = label;
3567 a->encap.mpls.mpls[3].tc = tc;
3568 a->encap.mpls.mpls[3].ttl = ttl;
3570 a->encap.mpls.mpls_count = 4;
3571 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3572 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3573 return 1 + 8 + 4 + 4 + 4;
3577 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3579 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3580 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3581 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3585 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3586 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3594 parse_table_action_nat(char **tokens,
3596 struct softnic_table_rule_action *a)
3599 strcmp(tokens[0], "nat"))
3602 if (strcmp(tokens[1], "ipv4") == 0) {
3603 struct in_addr addr;
3606 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3607 softnic_parser_read_uint16(&port, tokens[3]))
3610 a->nat.ip_version = 1;
3611 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3613 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3617 if (strcmp(tokens[1], "ipv6") == 0) {
3618 struct in6_addr addr;
3621 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3622 softnic_parser_read_uint16(&port, tokens[3]))
3625 a->nat.ip_version = 0;
3626 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3628 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3636 parse_table_action_ttl(char **tokens,
3638 struct softnic_table_rule_action *a)
3641 strcmp(tokens[0], "ttl"))
3644 if (strcmp(tokens[1], "dec") == 0)
3645 a->ttl.decrement = 1;
3646 else if (strcmp(tokens[1], "keep") == 0)
3647 a->ttl.decrement = 0;
3651 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3656 parse_table_action_stats(char **tokens,
3658 struct softnic_table_rule_action *a)
3661 strcmp(tokens[0], "stats"))
3664 a->stats.n_packets = 0;
3665 a->stats.n_bytes = 0;
3666 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3671 parse_table_action_time(char **tokens,
3673 struct softnic_table_rule_action *a)
3676 strcmp(tokens[0], "time"))
3679 a->time.time = rte_rdtsc();
3680 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3685 parse_table_action_tag(char **tokens,
3687 struct softnic_table_rule_action *a)
3690 strcmp(tokens[0], "tag"))
3693 if (softnic_parser_read_uint32(&a->tag.tag, tokens[1]))
3696 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
3701 parse_table_action_decap(char **tokens,
3703 struct softnic_table_rule_action *a)
3706 strcmp(tokens[0], "decap"))
3709 if (softnic_parser_read_uint16(&a->decap.n, tokens[1]))
3712 a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
3717 parse_table_action(char **tokens,
3721 struct softnic_table_rule_action *a)
3723 uint32_t n_tokens0 = n_tokens;
3725 memset(a, 0, sizeof(*a));
3728 strcmp(tokens[0], "action"))
3734 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3737 n = parse_table_action_fwd(tokens, n_tokens, a);
3739 snprintf(out, out_size, MSG_ARG_INVALID,
3748 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3751 n = parse_table_action_balance(tokens, n_tokens, a);
3753 snprintf(out, out_size, MSG_ARG_INVALID,
3762 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3765 n = parse_table_action_meter(tokens, n_tokens, a);
3767 snprintf(out, out_size, MSG_ARG_INVALID,
3776 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3779 n = parse_table_action_tm(tokens, n_tokens, a);
3781 snprintf(out, out_size, MSG_ARG_INVALID,
3790 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3793 n = parse_table_action_encap(tokens, n_tokens, a);
3795 snprintf(out, out_size, MSG_ARG_INVALID,
3804 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3807 n = parse_table_action_nat(tokens, n_tokens, a);
3809 snprintf(out, out_size, MSG_ARG_INVALID,
3818 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3821 n = parse_table_action_ttl(tokens, n_tokens, a);
3823 snprintf(out, out_size, MSG_ARG_INVALID,
3832 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3835 n = parse_table_action_stats(tokens, n_tokens, a);
3837 snprintf(out, out_size, MSG_ARG_INVALID,
3846 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3849 n = parse_table_action_time(tokens, n_tokens, a);
3851 snprintf(out, out_size, MSG_ARG_INVALID,
3860 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
3863 n = parse_table_action_tag(tokens, n_tokens, a);
3865 snprintf(out, out_size, MSG_ARG_INVALID,
3874 if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
3877 n = parse_table_action_decap(tokens, n_tokens, a);
3879 snprintf(out, out_size, MSG_ARG_INVALID,
3888 if (n_tokens0 - n_tokens == 1) {
3889 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3893 return n_tokens0 - n_tokens;
3897 * pipeline <pipeline_name> table <table_id> rule add
3899 * action <table_action>
3902 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3908 struct softnic_table_rule_match m;
3909 struct softnic_table_rule_action a;
3910 char *pipeline_name;
3912 uint32_t table_id, t0, n_tokens_parsed;
3916 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3920 pipeline_name = tokens[1];
3922 if (strcmp(tokens[2], "table") != 0) {
3923 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3927 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3928 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3932 if (strcmp(tokens[4], "rule") != 0) {
3933 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3937 if (strcmp(tokens[5], "add") != 0) {
3938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3945 n_tokens_parsed = parse_match(tokens + t0,
3950 if (n_tokens_parsed == 0)
3952 t0 += n_tokens_parsed;
3955 n_tokens_parsed = parse_table_action(tokens + t0,
3960 if (n_tokens_parsed == 0)
3962 t0 += n_tokens_parsed;
3964 if (t0 != n_tokens) {
3965 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3969 status = softnic_pipeline_table_rule_add(softnic,
3976 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3982 * pipeline <pipeline_name> table <table_id> rule add
3990 * | table <table_id>
3993 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3999 struct softnic_table_rule_action action;
4001 char *pipeline_name;
4005 if (n_tokens != 11 &&
4007 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4011 pipeline_name = tokens[1];
4013 if (strcmp(tokens[2], "table") != 0) {
4014 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4018 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4019 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4023 if (strcmp(tokens[4], "rule") != 0) {
4024 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4028 if (strcmp(tokens[5], "add") != 0) {
4029 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4033 if (strcmp(tokens[6], "match") != 0) {
4034 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4038 if (strcmp(tokens[7], "default") != 0) {
4039 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4043 if (strcmp(tokens[8], "action") != 0) {
4044 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4048 if (strcmp(tokens[9], "fwd") != 0) {
4049 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4053 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4055 if (strcmp(tokens[10], "drop") == 0) {
4056 if (n_tokens != 11) {
4057 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4061 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4062 } else if (strcmp(tokens[10], "port") == 0) {
4065 if (n_tokens != 12) {
4066 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4070 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4071 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4075 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4077 } else if (strcmp(tokens[10], "meta") == 0) {
4078 if (n_tokens != 11) {
4079 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4083 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4084 } else if (strcmp(tokens[10], "table") == 0) {
4087 if (n_tokens != 12) {
4088 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4092 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4093 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4097 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4100 snprintf(out, out_size, MSG_ARG_INVALID,
4101 "drop or port or meta or table");
4105 status = softnic_pipeline_table_rule_add_default(softnic,
4111 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4117 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
4120 * - line format: match <match> action <action>
4123 cli_rule_file_process(const char *file_name,
4124 size_t line_len_max,
4125 struct softnic_table_rule_match *m,
4126 struct softnic_table_rule_action *a,
4128 uint32_t *line_number,
4133 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
4139 struct softnic_table_rule_match *match;
4140 struct softnic_table_rule_action *action;
4142 char *pipeline_name, *file_name;
4143 uint32_t table_id, n_rules, n_rules_parsed, line_number;
4146 if (n_tokens != 9) {
4147 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4151 pipeline_name = tokens[1];
4153 if (strcmp(tokens[2], "table") != 0) {
4154 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4158 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4159 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4163 if (strcmp(tokens[4], "rule") != 0) {
4164 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4168 if (strcmp(tokens[5], "add") != 0) {
4169 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4173 if (strcmp(tokens[6], "bulk") != 0) {
4174 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4178 file_name = tokens[7];
4180 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
4182 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
4186 /* Memory allocation. */
4187 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
4188 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
4189 data = calloc(n_rules, sizeof(void *));
4190 if (match == NULL ||
4193 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
4200 /* Load rule file */
4201 n_rules_parsed = n_rules;
4202 status = cli_rule_file_process(file_name,
4211 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4217 if (n_rules_parsed != n_rules) {
4218 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
4226 status = softnic_pipeline_table_rule_add_bulk(softnic,
4234 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4248 * pipeline <pipeline_name> table <table_id> rule delete
4252 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
4258 struct softnic_table_rule_match m;
4259 char *pipeline_name;
4260 uint32_t table_id, n_tokens_parsed, t0;
4264 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4268 pipeline_name = tokens[1];
4270 if (strcmp(tokens[2], "table") != 0) {
4271 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4275 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4276 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4280 if (strcmp(tokens[4], "rule") != 0) {
4281 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4285 if (strcmp(tokens[5], "delete") != 0) {
4286 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4293 n_tokens_parsed = parse_match(tokens + t0,
4298 if (n_tokens_parsed == 0)
4300 t0 += n_tokens_parsed;
4302 if (n_tokens != t0) {
4303 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4307 status = softnic_pipeline_table_rule_delete(softnic,
4312 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4318 * pipeline <pipeline_name> table <table_id> rule delete
4323 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
4329 char *pipeline_name;
4333 if (n_tokens != 8) {
4334 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4338 pipeline_name = tokens[1];
4340 if (strcmp(tokens[2], "table") != 0) {
4341 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4345 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4346 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4350 if (strcmp(tokens[4], "rule") != 0) {
4351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4355 if (strcmp(tokens[5], "delete") != 0) {
4356 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4360 if (strcmp(tokens[6], "match") != 0) {
4361 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4365 if (strcmp(tokens[7], "default") != 0) {
4366 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4370 status = softnic_pipeline_table_rule_delete_default(softnic,
4374 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4380 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
4383 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
4385 uint32_t n_tokens __rte_unused,
4389 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4393 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
4394 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
4395 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
4398 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
4404 struct rte_table_action_meter_profile p;
4405 char *pipeline_name;
4406 uint32_t table_id, meter_profile_id;
4410 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4414 pipeline_name = tokens[1];
4416 if (strcmp(tokens[2], "table") != 0) {
4417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4421 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4422 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4426 if (strcmp(tokens[4], "meter") != 0) {
4427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4431 if (strcmp(tokens[5], "profile") != 0) {
4432 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4436 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4437 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4441 if (strcmp(tokens[7], "add") != 0) {
4442 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4446 if (strcmp(tokens[8], "srtcm") == 0) {
4447 if (n_tokens != 15) {
4448 snprintf(out, out_size, MSG_ARG_MISMATCH,
4453 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
4455 if (strcmp(tokens[9], "cir") != 0) {
4456 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4460 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
4461 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4465 if (strcmp(tokens[11], "cbs") != 0) {
4466 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4470 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
4471 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4475 if (strcmp(tokens[13], "ebs") != 0) {
4476 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
4480 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
4481 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
4484 } else if (strcmp(tokens[8], "trtcm") == 0) {
4485 if (n_tokens != 17) {
4486 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4490 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
4492 if (strcmp(tokens[9], "cir") != 0) {
4493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4497 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
4498 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4502 if (strcmp(tokens[11], "pir") != 0) {
4503 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
4507 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
4508 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
4511 if (strcmp(tokens[13], "cbs") != 0) {
4512 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4516 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
4517 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4521 if (strcmp(tokens[15], "pbs") != 0) {
4522 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
4526 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
4527 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
4531 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4535 status = softnic_pipeline_table_mtr_profile_add(softnic,
4541 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4547 * pipeline <pipeline_name> table <table_id>
4548 * meter profile <meter_profile_id> delete
4551 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
4557 char *pipeline_name;
4558 uint32_t table_id, meter_profile_id;
4561 if (n_tokens != 8) {
4562 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4566 pipeline_name = tokens[1];
4568 if (strcmp(tokens[2], "table") != 0) {
4569 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4573 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4574 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4578 if (strcmp(tokens[4], "meter") != 0) {
4579 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4583 if (strcmp(tokens[5], "profile") != 0) {
4584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4588 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4589 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4593 if (strcmp(tokens[7], "delete") != 0) {
4594 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4598 status = softnic_pipeline_table_mtr_profile_delete(softnic,
4603 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4609 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
4612 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
4614 uint32_t n_tokens __rte_unused,
4618 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4622 * pipeline <pipeline_name> table <table_id> dscp <file_name>
4625 * - exactly 64 lines
4626 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
4629 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4630 const char *file_name,
4631 uint32_t *line_number)
4636 /* Check input arguments */
4637 if (dscp_table == NULL ||
4638 file_name == NULL ||
4639 line_number == NULL) {
4645 /* Open input file */
4646 f = fopen(file_name, "r");
4653 for (dscp = 0, l = 1; ; l++) {
4656 enum rte_meter_color color;
4657 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4659 if (fgets(line, sizeof(line), f) == NULL)
4662 if (is_comment(line))
4665 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
4674 if (dscp >= RTE_DIM(dscp_table->entry) ||
4675 n_tokens != RTE_DIM(tokens) ||
4676 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
4677 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
4678 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
4679 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
4680 (strlen(tokens[2]) != 1)) {
4686 switch (tokens[2][0]) {
4689 color = e_RTE_METER_GREEN;
4694 color = e_RTE_METER_YELLOW;
4699 color = e_RTE_METER_RED;
4708 dscp_table->entry[dscp].tc_id = tc_id;
4709 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4710 dscp_table->entry[dscp].color = color;
4720 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
4726 struct rte_table_action_dscp_table dscp_table;
4727 char *pipeline_name, *file_name;
4728 uint32_t table_id, line_number;
4731 if (n_tokens != 6) {
4732 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4736 pipeline_name = tokens[1];
4738 if (strcmp(tokens[2], "table") != 0) {
4739 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4743 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4744 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4748 if (strcmp(tokens[4], "dscp") != 0) {
4749 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4753 file_name = tokens[5];
4755 status = load_dscp_table(&dscp_table, file_name, &line_number);
4757 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4761 status = softnic_pipeline_table_dscp_table_update(softnic,
4767 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4773 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4776 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4778 uint32_t n_tokens __rte_unused,
4782 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4786 * thread <thread_id> pipeline <pipeline_name> enable
4789 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4795 char *pipeline_name;
4799 if (n_tokens != 5) {
4800 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4804 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4805 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4809 if (strcmp(tokens[2], "pipeline") != 0) {
4810 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4814 pipeline_name = tokens[3];
4816 if (strcmp(tokens[4], "enable") != 0) {
4817 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4821 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4823 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4829 * thread <thread_id> pipeline <pipeline_name> disable
4832 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4838 char *pipeline_name;
4842 if (n_tokens != 5) {
4843 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4847 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4848 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4852 if (strcmp(tokens[2], "pipeline") != 0) {
4853 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4857 pipeline_name = tokens[3];
4859 if (strcmp(tokens[4], "disable") != 0) {
4860 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4864 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4866 snprintf(out, out_size, MSG_CMD_FAIL,
4867 "thread pipeline disable");
4876 * pipeline <pipeline_name>
4880 cmd_softnic_flowapi_map(struct pmd_internals *softnic,
4886 char *pipeline_name;
4887 uint32_t group_id, table_id;
4888 int ingress, status;
4890 if (n_tokens != 9) {
4891 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4895 if (strcmp(tokens[1], "map") != 0) {
4896 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "map");
4900 if (strcmp(tokens[2], "group") != 0) {
4901 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group");
4905 if (softnic_parser_read_uint32(&group_id, tokens[3]) != 0) {
4906 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
4910 if (strcmp(tokens[4], "ingress") == 0) {
4912 } else if (strcmp(tokens[4], "egress") == 0) {
4915 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ingress | egress");
4919 if (strcmp(tokens[5], "pipeline") != 0) {
4920 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4924 pipeline_name = tokens[6];
4926 if (strcmp(tokens[7], "table") != 0) {
4927 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4931 if (softnic_parser_read_uint32(&table_id, tokens[8]) != 0) {
4932 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4936 status = flow_attr_map_set(softnic,
4942 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4948 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4950 char *tokens[CMD_MAX_TOKENS];
4951 uint32_t n_tokens = RTE_DIM(tokens);
4952 struct pmd_internals *softnic = arg;
4958 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4960 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4967 if (strcmp(tokens[0], "mempool") == 0) {
4968 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4972 if (strcmp(tokens[0], "link") == 0) {
4973 cmd_link(softnic, tokens, n_tokens, out, out_size);
4977 if (strcmp(tokens[0], "swq") == 0) {
4978 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4982 if (strcmp(tokens[0], "tmgr") == 0) {
4983 if (n_tokens == 2) {
4984 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4988 if (n_tokens >= 3 &&
4989 (strcmp(tokens[1], "shaper") == 0) &&
4990 (strcmp(tokens[2], "profile") == 0)) {
4991 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4995 if (n_tokens >= 3 &&
4996 (strcmp(tokens[1], "shared") == 0) &&
4997 (strcmp(tokens[2], "shaper") == 0)) {
4998 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
5002 if (n_tokens >= 2 &&
5003 (strcmp(tokens[1], "node") == 0)) {
5004 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
5008 if (n_tokens >= 2 &&
5009 (strcmp(tokens[1], "hierarchy-default") == 0)) {
5010 cmd_tmgr_hierarchy_default(softnic, tokens, n_tokens, out, out_size);
5014 if (n_tokens >= 3 &&
5015 (strcmp(tokens[1], "hierarchy") == 0) &&
5016 (strcmp(tokens[2], "commit") == 0)) {
5017 cmd_tmgr_hierarchy_commit(softnic, tokens, n_tokens, out, out_size);
5022 if (strcmp(tokens[0], "tap") == 0) {
5023 cmd_tap(softnic, tokens, n_tokens, out, out_size);
5027 if (strcmp(tokens[0], "port") == 0) {
5028 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
5032 if (strcmp(tokens[0], "table") == 0) {
5033 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
5037 if (strcmp(tokens[0], "pipeline") == 0) {
5038 if (n_tokens >= 3 &&
5039 (strcmp(tokens[2], "period") == 0)) {
5040 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
5044 if (n_tokens >= 5 &&
5045 (strcmp(tokens[2], "port") == 0) &&
5046 (strcmp(tokens[3], "in") == 0) &&
5047 (strcmp(tokens[4], "bsz") == 0)) {
5048 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
5052 if (n_tokens >= 5 &&
5053 (strcmp(tokens[2], "port") == 0) &&
5054 (strcmp(tokens[3], "out") == 0) &&
5055 (strcmp(tokens[4], "bsz") == 0)) {
5056 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
5060 if (n_tokens >= 4 &&
5061 (strcmp(tokens[2], "table") == 0) &&
5062 (strcmp(tokens[3], "match") == 0)) {
5063 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
5067 if (n_tokens >= 6 &&
5068 (strcmp(tokens[2], "port") == 0) &&
5069 (strcmp(tokens[3], "in") == 0) &&
5070 (strcmp(tokens[5], "table") == 0)) {
5071 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
5076 if (n_tokens >= 6 &&
5077 (strcmp(tokens[2], "port") == 0) &&
5078 (strcmp(tokens[3], "in") == 0) &&
5079 (strcmp(tokens[5], "stats") == 0)) {
5080 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
5085 if (n_tokens >= 6 &&
5086 (strcmp(tokens[2], "port") == 0) &&
5087 (strcmp(tokens[3], "in") == 0) &&
5088 (strcmp(tokens[5], "enable") == 0)) {
5089 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
5094 if (n_tokens >= 6 &&
5095 (strcmp(tokens[2], "port") == 0) &&
5096 (strcmp(tokens[3], "in") == 0) &&
5097 (strcmp(tokens[5], "disable") == 0)) {
5098 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
5103 if (n_tokens >= 6 &&
5104 (strcmp(tokens[2], "port") == 0) &&
5105 (strcmp(tokens[3], "out") == 0) &&
5106 (strcmp(tokens[5], "stats") == 0)) {
5107 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
5112 if (n_tokens >= 5 &&
5113 (strcmp(tokens[2], "table") == 0) &&
5114 (strcmp(tokens[4], "stats") == 0)) {
5115 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
5120 if (n_tokens >= 7 &&
5121 (strcmp(tokens[2], "table") == 0) &&
5122 (strcmp(tokens[4], "rule") == 0) &&
5123 (strcmp(tokens[5], "add") == 0) &&
5124 (strcmp(tokens[6], "match") == 0)) {
5125 if (n_tokens >= 8 &&
5126 (strcmp(tokens[7], "default") == 0)) {
5127 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
5128 n_tokens, out, out_size);
5132 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
5137 if (n_tokens >= 7 &&
5138 (strcmp(tokens[2], "table") == 0) &&
5139 (strcmp(tokens[4], "rule") == 0) &&
5140 (strcmp(tokens[5], "add") == 0) &&
5141 (strcmp(tokens[6], "bulk") == 0)) {
5142 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
5143 n_tokens, out, out_size);
5147 if (n_tokens >= 7 &&
5148 (strcmp(tokens[2], "table") == 0) &&
5149 (strcmp(tokens[4], "rule") == 0) &&
5150 (strcmp(tokens[5], "delete") == 0) &&
5151 (strcmp(tokens[6], "match") == 0)) {
5152 if (n_tokens >= 8 &&
5153 (strcmp(tokens[7], "default") == 0)) {
5154 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
5155 n_tokens, out, out_size);
5159 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
5164 if (n_tokens >= 7 &&
5165 (strcmp(tokens[2], "table") == 0) &&
5166 (strcmp(tokens[4], "rule") == 0) &&
5167 (strcmp(tokens[5], "read") == 0) &&
5168 (strcmp(tokens[6], "stats") == 0)) {
5169 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
5174 if (n_tokens >= 8 &&
5175 (strcmp(tokens[2], "table") == 0) &&
5176 (strcmp(tokens[4], "meter") == 0) &&
5177 (strcmp(tokens[5], "profile") == 0) &&
5178 (strcmp(tokens[7], "add") == 0)) {
5179 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
5184 if (n_tokens >= 8 &&
5185 (strcmp(tokens[2], "table") == 0) &&
5186 (strcmp(tokens[4], "meter") == 0) &&
5187 (strcmp(tokens[5], "profile") == 0) &&
5188 (strcmp(tokens[7], "delete") == 0)) {
5189 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
5190 n_tokens, out, out_size);
5194 if (n_tokens >= 7 &&
5195 (strcmp(tokens[2], "table") == 0) &&
5196 (strcmp(tokens[4], "rule") == 0) &&
5197 (strcmp(tokens[5], "read") == 0) &&
5198 (strcmp(tokens[6], "meter") == 0)) {
5199 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
5204 if (n_tokens >= 5 &&
5205 (strcmp(tokens[2], "table") == 0) &&
5206 (strcmp(tokens[4], "dscp") == 0)) {
5207 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
5212 if (n_tokens >= 7 &&
5213 (strcmp(tokens[2], "table") == 0) &&
5214 (strcmp(tokens[4], "rule") == 0) &&
5215 (strcmp(tokens[5], "read") == 0) &&
5216 (strcmp(tokens[6], "ttl") == 0)) {
5217 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
5223 if (strcmp(tokens[0], "thread") == 0) {
5224 if (n_tokens >= 5 &&
5225 (strcmp(tokens[4], "enable") == 0)) {
5226 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
5231 if (n_tokens >= 5 &&
5232 (strcmp(tokens[4], "disable") == 0)) {
5233 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
5239 if (strcmp(tokens[0], "flowapi") == 0) {
5240 cmd_softnic_flowapi_map(softnic, tokens, n_tokens, out,
5245 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5249 softnic_cli_script_process(struct pmd_internals *softnic,
5250 const char *file_name,
5251 size_t msg_in_len_max,
5252 size_t msg_out_len_max)
5254 char *msg_in = NULL, *msg_out = NULL;
5257 /* Check input arguments */
5258 if (file_name == NULL ||
5259 (strlen(file_name) == 0) ||
5260 msg_in_len_max == 0 ||
5261 msg_out_len_max == 0)
5264 msg_in = malloc(msg_in_len_max + 1);
5265 msg_out = malloc(msg_out_len_max + 1);
5266 if (msg_in == NULL ||
5273 /* Open input file */
5274 f = fopen(file_name, "r");
5283 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5286 printf("%s", msg_in);
5289 softnic_cli_process(msg_in,
5294 if (strlen(msg_out))
5295 printf("%s", msg_out);
5306 cli_rule_file_process(const char *file_name,
5307 size_t line_len_max,
5308 struct softnic_table_rule_match *m,
5309 struct softnic_table_rule_action *a,
5311 uint32_t *line_number,
5317 uint32_t rule_id, line_id;
5320 /* Check input arguments */
5321 if (file_name == NULL ||
5322 (strlen(file_name) == 0) ||
5323 line_len_max == 0) {
5328 /* Memory allocation */
5329 line = malloc(line_len_max + 1);
5336 f = fopen(file_name, "r");
5344 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
5345 char *tokens[CMD_MAX_TOKENS];
5346 uint32_t n_tokens, n_tokens_parsed, t0;
5348 /* Read next line from file. */
5349 if (fgets(line, line_len_max + 1, f) == NULL)
5353 if (is_comment(line))
5357 n_tokens = RTE_DIM(tokens);
5358 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
5370 n_tokens_parsed = parse_match(tokens + t0,
5375 if (n_tokens_parsed == 0) {
5379 t0 += n_tokens_parsed;
5382 n_tokens_parsed = parse_table_action(tokens + t0,
5387 if (n_tokens_parsed == 0) {
5391 t0 += n_tokens_parsed;
5393 /* Line completed. */
5394 if (t0 < n_tokens) {
5399 /* Increment rule count */
5410 *line_number = line_id;