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]
1285 cmd_table_action_profile(struct pmd_internals *softnic,
1291 struct softnic_table_action_profile_params p;
1292 struct softnic_table_action_profile *ap;
1296 memset(&p, 0, sizeof(p));
1299 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1303 if (strcmp(tokens[1], "action") != 0) {
1304 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1308 if (strcmp(tokens[2], "profile") != 0) {
1309 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1315 if (strcmp(tokens[4], "ipv4") == 0) {
1316 p.common.ip_version = 1;
1317 } else if (strcmp(tokens[4], "ipv6") == 0) {
1318 p.common.ip_version = 0;
1320 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1324 if (strcmp(tokens[5], "offset") != 0) {
1325 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1329 if (softnic_parser_read_uint32(&p.common.ip_offset,
1331 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1335 if (strcmp(tokens[7], "fwd") != 0) {
1336 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1340 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1343 if (t0 < n_tokens &&
1344 (strcmp(tokens[t0], "balance") == 0)) {
1345 if (n_tokens < t0 + 7) {
1346 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1350 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1355 if (softnic_parser_read_uint32(&p.lb.key_offset,
1356 tokens[t0 + 2]) != 0) {
1357 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1361 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1362 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1366 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1367 if (softnic_parse_hex_string(tokens[t0 + 4],
1368 p.lb.key_mask, &p.lb.key_size) != 0) {
1369 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1373 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1374 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1378 if (softnic_parser_read_uint32(&p.lb.out_offset,
1379 tokens[t0 + 6]) != 0) {
1380 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1384 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1388 if (t0 < n_tokens &&
1389 (strcmp(tokens[t0], "meter") == 0)) {
1390 if (n_tokens < t0 + 6) {
1391 snprintf(out, out_size, MSG_ARG_MISMATCH,
1392 "table action profile meter");
1396 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
1397 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1398 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
1399 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1401 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1406 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1407 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1411 if (softnic_parser_read_uint32(&p.mtr.n_tc,
1412 tokens[t0 + 3]) != 0) {
1413 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1417 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1418 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1422 if (strcmp(tokens[t0 + 5], "none") == 0) {
1423 p.mtr.n_packets_enabled = 0;
1424 p.mtr.n_bytes_enabled = 0;
1425 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1426 p.mtr.n_packets_enabled = 1;
1427 p.mtr.n_bytes_enabled = 0;
1428 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1429 p.mtr.n_packets_enabled = 0;
1430 p.mtr.n_bytes_enabled = 1;
1431 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1432 p.mtr.n_packets_enabled = 1;
1433 p.mtr.n_bytes_enabled = 1;
1435 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1436 "none or pkts or bytes or both");
1440 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1444 if (t0 < n_tokens &&
1445 (strcmp(tokens[t0], "tm") == 0)) {
1446 if (n_tokens < t0 + 5) {
1447 snprintf(out, out_size, MSG_ARG_MISMATCH,
1448 "table action profile tm");
1452 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1453 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1457 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
1458 tokens[t0 + 2]) != 0) {
1459 snprintf(out, out_size, MSG_ARG_INVALID,
1460 "n_subports_per_port");
1464 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1465 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1469 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
1470 tokens[t0 + 4]) != 0) {
1471 snprintf(out, out_size, MSG_ARG_INVALID,
1472 "n_pipes_per_subport");
1476 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1480 if (t0 < n_tokens &&
1481 (strcmp(tokens[t0], "encap") == 0)) {
1482 if (n_tokens < t0 + 2) {
1483 snprintf(out, out_size, MSG_ARG_MISMATCH,
1484 "action profile encap");
1488 if (strcmp(tokens[t0 + 1], "ether") == 0) {
1489 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1490 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
1491 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1492 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
1493 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1494 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
1495 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1496 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
1497 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1499 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1503 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1507 if (t0 < n_tokens &&
1508 (strcmp(tokens[t0], "nat") == 0)) {
1509 if (n_tokens < t0 + 4) {
1510 snprintf(out, out_size, MSG_ARG_MISMATCH,
1511 "table action profile nat");
1515 if (strcmp(tokens[t0 + 1], "src") == 0) {
1516 p.nat.source_nat = 1;
1517 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
1518 p.nat.source_nat = 0;
1520 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1525 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1526 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1530 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
1532 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
1535 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1540 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1544 if (t0 < n_tokens &&
1545 (strcmp(tokens[t0], "ttl") == 0)) {
1546 if (n_tokens < t0 + 4) {
1547 snprintf(out, out_size, MSG_ARG_MISMATCH,
1548 "table action profile ttl");
1552 if (strcmp(tokens[t0 + 1], "drop") == 0) {
1554 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
1557 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1562 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1563 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1567 if (strcmp(tokens[t0 + 3], "none") == 0) {
1568 p.ttl.n_packets_enabled = 0;
1569 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
1570 p.ttl.n_packets_enabled = 1;
1572 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1577 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1581 if (t0 < n_tokens &&
1582 (strcmp(tokens[t0], "stats") == 0)) {
1583 if (n_tokens < t0 + 2) {
1584 snprintf(out, out_size, MSG_ARG_MISMATCH,
1585 "table action profile stats");
1589 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1590 p.stats.n_packets_enabled = 1;
1591 p.stats.n_bytes_enabled = 0;
1592 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1593 p.stats.n_packets_enabled = 0;
1594 p.stats.n_bytes_enabled = 1;
1595 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1596 p.stats.n_packets_enabled = 1;
1597 p.stats.n_bytes_enabled = 1;
1599 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1600 "pkts or bytes or both");
1604 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1608 if (t0 < n_tokens &&
1609 (strcmp(tokens[t0], "time") == 0)) {
1610 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1614 if (t0 < n_tokens &&
1615 (strcmp(tokens[t0], "tag") == 0)) {
1616 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
1620 if (t0 < n_tokens) {
1621 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1625 ap = softnic_table_action_profile_create(softnic, name, &p);
1627 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1633 * pipeline <pipeline_name>
1634 * period <timer_period_ms>
1635 * offset_port_id <offset_port_id>
1638 cmd_pipeline(struct pmd_internals *softnic,
1644 struct pipeline_params p;
1646 struct pipeline *pipeline;
1648 if (n_tokens != 6) {
1649 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1655 if (strcmp(tokens[2], "period") != 0) {
1656 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1660 if (softnic_parser_read_uint32(&p.timer_period_ms,
1662 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1666 if (strcmp(tokens[4], "offset_port_id") != 0) {
1667 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1671 if (softnic_parser_read_uint32(&p.offset_port_id,
1673 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1677 pipeline = softnic_pipeline_create(softnic, name, &p);
1678 if (pipeline == NULL) {
1679 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1685 * pipeline <pipeline_name> port in
1687 * link <link_name> rxq <queue_id>
1689 * | tmgr <tmgr_name>
1690 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
1691 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
1692 * [action <port_in_action_profile_name>]
1696 cmd_pipeline_port_in(struct pmd_internals *softnic,
1702 struct softnic_port_in_params p;
1703 char *pipeline_name;
1705 int enabled, status;
1707 memset(&p, 0, sizeof(p));
1710 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1714 pipeline_name = tokens[1];
1716 if (strcmp(tokens[2], "port") != 0) {
1717 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1721 if (strcmp(tokens[3], "in") != 0) {
1722 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1726 if (strcmp(tokens[4], "bsz") != 0) {
1727 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1731 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1732 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1738 if (strcmp(tokens[t0], "link") == 0) {
1739 if (n_tokens < t0 + 4) {
1740 snprintf(out, out_size, MSG_ARG_MISMATCH,
1741 "pipeline port in link");
1745 p.type = PORT_IN_RXQ;
1747 strcpy(p.dev_name, tokens[t0 + 1]);
1749 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1750 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1754 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1755 tokens[t0 + 3]) != 0) {
1756 snprintf(out, out_size, MSG_ARG_INVALID,
1761 } else if (strcmp(tokens[t0], "swq") == 0) {
1762 if (n_tokens < t0 + 2) {
1763 snprintf(out, out_size, MSG_ARG_MISMATCH,
1764 "pipeline port in swq");
1768 p.type = PORT_IN_SWQ;
1770 strcpy(p.dev_name, tokens[t0 + 1]);
1773 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1774 if (n_tokens < t0 + 2) {
1775 snprintf(out, out_size, MSG_ARG_MISMATCH,
1776 "pipeline port in tmgr");
1780 p.type = PORT_IN_TMGR;
1782 strcpy(p.dev_name, tokens[t0 + 1]);
1785 } else if (strcmp(tokens[t0], "tap") == 0) {
1786 if (n_tokens < t0 + 6) {
1787 snprintf(out, out_size, MSG_ARG_MISMATCH,
1788 "pipeline port in tap");
1792 p.type = PORT_IN_TAP;
1794 strcpy(p.dev_name, tokens[t0 + 1]);
1796 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1797 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1802 p.tap.mempool_name = tokens[t0 + 3];
1804 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1805 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1810 if (softnic_parser_read_uint32(&p.tap.mtu,
1811 tokens[t0 + 5]) != 0) {
1812 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1817 } else if (strcmp(tokens[t0], "source") == 0) {
1818 if (n_tokens < t0 + 6) {
1819 snprintf(out, out_size, MSG_ARG_MISMATCH,
1820 "pipeline port in source");
1824 p.type = PORT_IN_SOURCE;
1826 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1827 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1832 p.source.mempool_name = tokens[t0 + 2];
1834 if (strcmp(tokens[t0 + 3], "file") != 0) {
1835 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1840 p.source.file_name = tokens[t0 + 4];
1842 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1843 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1848 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1849 tokens[t0 + 6]) != 0) {
1850 snprintf(out, out_size, MSG_ARG_INVALID,
1857 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1861 if (n_tokens > t0 &&
1862 (strcmp(tokens[t0], "action") == 0)) {
1863 if (n_tokens < t0 + 2) {
1864 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1868 strcpy(p.action_profile_name, tokens[t0 + 1]);
1874 if (n_tokens > t0 &&
1875 (strcmp(tokens[t0], "disabled") == 0)) {
1881 if (n_tokens != t0) {
1882 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1886 status = softnic_pipeline_port_in_create(softnic,
1891 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1897 * pipeline <pipeline_name> port out
1899 * link <link_name> txq <txq_id>
1901 * | tmgr <tmgr_name>
1903 * | sink [file <file_name> pkts <max_n_pkts>]
1906 cmd_pipeline_port_out(struct pmd_internals *softnic,
1912 struct softnic_port_out_params p;
1913 char *pipeline_name;
1916 memset(&p, 0, sizeof(p));
1919 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1923 pipeline_name = tokens[1];
1925 if (strcmp(tokens[2], "port") != 0) {
1926 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1930 if (strcmp(tokens[3], "out") != 0) {
1931 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1935 if (strcmp(tokens[4], "bsz") != 0) {
1936 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1940 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1941 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1945 if (strcmp(tokens[6], "link") == 0) {
1946 if (n_tokens != 10) {
1947 snprintf(out, out_size, MSG_ARG_MISMATCH,
1948 "pipeline port out link");
1952 p.type = PORT_OUT_TXQ;
1954 strcpy(p.dev_name, tokens[7]);
1956 if (strcmp(tokens[8], "txq") != 0) {
1957 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1961 if (softnic_parser_read_uint16(&p.txq.queue_id,
1963 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1966 } else if (strcmp(tokens[6], "swq") == 0) {
1967 if (n_tokens != 8) {
1968 snprintf(out, out_size, MSG_ARG_MISMATCH,
1969 "pipeline port out swq");
1973 p.type = PORT_OUT_SWQ;
1975 strcpy(p.dev_name, tokens[7]);
1976 } else if (strcmp(tokens[6], "tmgr") == 0) {
1977 if (n_tokens != 8) {
1978 snprintf(out, out_size, MSG_ARG_MISMATCH,
1979 "pipeline port out tmgr");
1983 p.type = PORT_OUT_TMGR;
1985 strcpy(p.dev_name, tokens[7]);
1986 } else if (strcmp(tokens[6], "tap") == 0) {
1987 if (n_tokens != 8) {
1988 snprintf(out, out_size, MSG_ARG_MISMATCH,
1989 "pipeline port out tap");
1993 p.type = PORT_OUT_TAP;
1995 strcpy(p.dev_name, tokens[7]);
1996 } else if (strcmp(tokens[6], "sink") == 0) {
1997 if ((n_tokens != 7) && (n_tokens != 11)) {
1998 snprintf(out, out_size, MSG_ARG_MISMATCH,
1999 "pipeline port out sink");
2003 p.type = PORT_OUT_SINK;
2005 if (n_tokens == 7) {
2006 p.sink.file_name = NULL;
2007 p.sink.max_n_pkts = 0;
2009 if (strcmp(tokens[7], "file") != 0) {
2010 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2015 p.sink.file_name = tokens[8];
2017 if (strcmp(tokens[9], "pkts") != 0) {
2018 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
2022 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
2024 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
2029 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2033 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
2035 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2041 * pipeline <pipeline_name> table
2045 * offset <ip_header_offset>
2048 * offset <key_offset>
2054 * offset <key_offset>
2055 * buckets <n_buckets>
2059 * offset <ip_header_offset>
2062 * [action <table_action_profile_name>]
2065 cmd_pipeline_table(struct pmd_internals *softnic,
2071 struct softnic_table_params p;
2072 char *pipeline_name;
2076 memset(&p, 0, sizeof(p));
2079 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2083 pipeline_name = tokens[1];
2085 if (strcmp(tokens[2], "table") != 0) {
2086 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2090 if (strcmp(tokens[3], "match") != 0) {
2091 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2096 if (strcmp(tokens[t0], "acl") == 0) {
2097 if (n_tokens < t0 + 6) {
2098 snprintf(out, out_size, MSG_ARG_MISMATCH,
2099 "pipeline table acl");
2103 p.match_type = TABLE_ACL;
2105 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2106 p.match.acl.ip_version = 1;
2107 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2108 p.match.acl.ip_version = 0;
2110 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2115 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2116 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2120 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
2121 tokens[t0 + 3]) != 0) {
2122 snprintf(out, out_size, MSG_ARG_INVALID,
2123 "ip_header_offset");
2127 if (strcmp(tokens[t0 + 4], "size") != 0) {
2128 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2132 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
2133 tokens[t0 + 5]) != 0) {
2134 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2139 } else if (strcmp(tokens[t0], "array") == 0) {
2140 if (n_tokens < t0 + 5) {
2141 snprintf(out, out_size, MSG_ARG_MISMATCH,
2142 "pipeline table array");
2146 p.match_type = TABLE_ARRAY;
2148 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2149 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2153 if (softnic_parser_read_uint32(&p.match.array.key_offset,
2154 tokens[t0 + 2]) != 0) {
2155 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2159 if (strcmp(tokens[t0 + 3], "size") != 0) {
2160 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2164 if (softnic_parser_read_uint32(&p.match.array.n_keys,
2165 tokens[t0 + 4]) != 0) {
2166 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2171 } else if (strcmp(tokens[t0], "hash") == 0) {
2172 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2174 if (n_tokens < t0 + 12) {
2175 snprintf(out, out_size, MSG_ARG_MISMATCH,
2176 "pipeline table hash");
2180 p.match_type = TABLE_HASH;
2182 if (strcmp(tokens[t0 + 1], "ext") == 0) {
2183 p.match.hash.extendable_bucket = 1;
2184 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
2185 p.match.hash.extendable_bucket = 0;
2187 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2192 if (strcmp(tokens[t0 + 2], "key") != 0) {
2193 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2197 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
2198 tokens[t0 + 3]) != 0) ||
2199 p.match.hash.key_size == 0 ||
2200 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
2201 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2205 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2206 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2210 if ((softnic_parse_hex_string(tokens[t0 + 5],
2211 p.match.hash.key_mask, &key_mask_size) != 0) ||
2212 key_mask_size != p.match.hash.key_size) {
2213 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2217 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2218 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2222 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
2223 tokens[t0 + 7]) != 0) {
2224 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2228 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2229 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2233 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
2234 tokens[t0 + 9]) != 0) {
2235 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2239 if (strcmp(tokens[t0 + 10], "size") != 0) {
2240 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2244 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
2245 tokens[t0 + 11]) != 0) {
2246 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2251 } else if (strcmp(tokens[t0], "lpm") == 0) {
2252 if (n_tokens < t0 + 6) {
2253 snprintf(out, out_size, MSG_ARG_MISMATCH,
2254 "pipeline table lpm");
2258 p.match_type = TABLE_LPM;
2260 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2261 p.match.lpm.key_size = 4;
2262 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2263 p.match.lpm.key_size = 16;
2265 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2270 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2271 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2275 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
2276 tokens[t0 + 3]) != 0) {
2277 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2281 if (strcmp(tokens[t0 + 4], "size") != 0) {
2282 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2286 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
2287 tokens[t0 + 5]) != 0) {
2288 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2293 } else if (strcmp(tokens[t0], "stub") == 0) {
2294 p.match_type = TABLE_STUB;
2298 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2302 if (n_tokens > t0 &&
2303 (strcmp(tokens[t0], "action") == 0)) {
2304 if (n_tokens < t0 + 2) {
2305 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2309 strcpy(p.action_profile_name, tokens[t0 + 1]);
2314 if (n_tokens > t0) {
2315 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2319 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
2321 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2327 * pipeline <pipeline_name> port in <port_id> table <table_id>
2330 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
2336 char *pipeline_name;
2337 uint32_t port_id, table_id;
2340 if (n_tokens != 7) {
2341 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2345 pipeline_name = tokens[1];
2347 if (strcmp(tokens[2], "port") != 0) {
2348 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2352 if (strcmp(tokens[3], "in") != 0) {
2353 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2357 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2358 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2362 if (strcmp(tokens[5], "table") != 0) {
2363 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2367 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
2368 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2372 status = softnic_pipeline_port_in_connect_to_table(softnic,
2377 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2383 * pipeline <pipeline_name> port in <port_id> stats read [clear]
2386 #define MSG_PIPELINE_PORT_IN_STATS \
2387 "Pkts in: %" PRIu64 "\n" \
2388 "Pkts dropped by AH: %" PRIu64 "\n" \
2389 "Pkts dropped by other: %" PRIu64 "\n"
2392 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
2398 struct rte_pipeline_port_in_stats stats;
2399 char *pipeline_name;
2403 if (n_tokens != 7 &&
2405 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2409 pipeline_name = tokens[1];
2411 if (strcmp(tokens[2], "port") != 0) {
2412 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2416 if (strcmp(tokens[3], "in") != 0) {
2417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2421 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2422 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2426 if (strcmp(tokens[5], "stats") != 0) {
2427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2431 if (strcmp(tokens[6], "read") != 0) {
2432 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2437 if (n_tokens == 8) {
2438 if (strcmp(tokens[7], "clear") != 0) {
2439 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2446 status = softnic_pipeline_port_in_stats_read(softnic,
2452 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2456 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2457 stats.stats.n_pkts_in,
2458 stats.n_pkts_dropped_by_ah,
2459 stats.stats.n_pkts_drop);
2463 * pipeline <pipeline_name> port in <port_id> enable
2466 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
2472 char *pipeline_name;
2476 if (n_tokens != 6) {
2477 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2481 pipeline_name = tokens[1];
2483 if (strcmp(tokens[2], "port") != 0) {
2484 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2488 if (strcmp(tokens[3], "in") != 0) {
2489 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2493 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2494 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2498 if (strcmp(tokens[5], "enable") != 0) {
2499 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2503 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
2505 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2511 * pipeline <pipeline_name> port in <port_id> disable
2514 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
2520 char *pipeline_name;
2524 if (n_tokens != 6) {
2525 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2529 pipeline_name = tokens[1];
2531 if (strcmp(tokens[2], "port") != 0) {
2532 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2536 if (strcmp(tokens[3], "in") != 0) {
2537 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2541 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2542 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2546 if (strcmp(tokens[5], "disable") != 0) {
2547 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2551 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2553 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2559 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2561 #define MSG_PIPELINE_PORT_OUT_STATS \
2562 "Pkts in: %" PRIu64 "\n" \
2563 "Pkts dropped by AH: %" PRIu64 "\n" \
2564 "Pkts dropped by other: %" PRIu64 "\n"
2567 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2573 struct rte_pipeline_port_out_stats stats;
2574 char *pipeline_name;
2578 if (n_tokens != 7 &&
2580 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2584 pipeline_name = tokens[1];
2586 if (strcmp(tokens[2], "port") != 0) {
2587 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2591 if (strcmp(tokens[3], "out") != 0) {
2592 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2596 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2597 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2601 if (strcmp(tokens[5], "stats") != 0) {
2602 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2606 if (strcmp(tokens[6], "read") != 0) {
2607 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2612 if (n_tokens == 8) {
2613 if (strcmp(tokens[7], "clear") != 0) {
2614 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2621 status = softnic_pipeline_port_out_stats_read(softnic,
2627 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2631 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2632 stats.stats.n_pkts_in,
2633 stats.n_pkts_dropped_by_ah,
2634 stats.stats.n_pkts_drop);
2638 * pipeline <pipeline_name> table <table_id> stats read [clear]
2640 #define MSG_PIPELINE_TABLE_STATS \
2641 "Pkts in: %" PRIu64 "\n" \
2642 "Pkts in with lookup miss: %" PRIu64 "\n" \
2643 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2644 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2645 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2646 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2649 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2655 struct rte_pipeline_table_stats stats;
2656 char *pipeline_name;
2660 if (n_tokens != 6 &&
2662 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2666 pipeline_name = tokens[1];
2668 if (strcmp(tokens[2], "table") != 0) {
2669 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2673 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2674 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2678 if (strcmp(tokens[4], "stats") != 0) {
2679 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2683 if (strcmp(tokens[5], "read") != 0) {
2684 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2689 if (n_tokens == 7) {
2690 if (strcmp(tokens[6], "clear") != 0) {
2691 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2698 status = softnic_pipeline_table_stats_read(softnic,
2704 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2708 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2709 stats.stats.n_pkts_in,
2710 stats.stats.n_pkts_lookup_miss,
2711 stats.n_pkts_dropped_by_lkp_hit_ah,
2712 stats.n_pkts_dropped_lkp_hit,
2713 stats.n_pkts_dropped_by_lkp_miss_ah,
2714 stats.n_pkts_dropped_lkp_miss);
2722 * priority <priority>
2723 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2724 * <sp0> <sp1> <dp0> <dp1> <proto>
2728 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2729 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2730 * | ipv4_addr <addr>
2731 * | ipv6_addr <addr>
2732 * | qinq <svlan> <cvlan>
2734 * ipv4 | ipv6 <addr> <depth>
2736 struct pkt_key_qinq {
2737 uint16_t ethertype_svlan;
2739 uint16_t ethertype_cvlan;
2741 } __attribute__((__packed__));
2743 struct pkt_key_ipv4_5tuple {
2744 uint8_t time_to_live;
2746 uint16_t hdr_checksum;
2751 } __attribute__((__packed__));
2753 struct pkt_key_ipv6_5tuple {
2754 uint16_t payload_length;
2761 } __attribute__((__packed__));
2763 struct pkt_key_ipv4_addr {
2765 } __attribute__((__packed__));
2767 struct pkt_key_ipv6_addr {
2769 } __attribute__((__packed__));
2772 parse_match(char **tokens,
2776 struct softnic_table_rule_match *m)
2778 memset(m, 0, sizeof(*m));
2783 if (strcmp(tokens[0], "match") != 0) {
2784 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2788 if (strcmp(tokens[1], "acl") == 0) {
2789 if (n_tokens < 14) {
2790 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2794 m->match_type = TABLE_ACL;
2796 if (strcmp(tokens[2], "priority") != 0) {
2797 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2801 if (softnic_parser_read_uint32(&m->match.acl.priority,
2803 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2807 if (strcmp(tokens[4], "ipv4") == 0) {
2808 struct in_addr saddr, daddr;
2810 m->match.acl.ip_version = 1;
2812 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2813 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2816 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2818 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2819 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2822 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2823 } else if (strcmp(tokens[4], "ipv6") == 0) {
2824 struct in6_addr saddr, daddr;
2826 m->match.acl.ip_version = 0;
2828 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2829 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2832 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2834 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2835 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2838 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2840 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2845 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2847 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2851 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2853 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2857 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2858 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2862 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2863 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2867 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2868 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2872 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2873 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2877 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2878 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2882 m->match.acl.proto_mask = 0xff;
2887 if (strcmp(tokens[1], "array") == 0) {
2889 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2893 m->match_type = TABLE_ARRAY;
2895 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2896 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2903 if (strcmp(tokens[1], "hash") == 0) {
2905 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2909 m->match_type = TABLE_HASH;
2911 if (strcmp(tokens[2], "raw") == 0) {
2912 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2915 snprintf(out, out_size, MSG_ARG_MISMATCH,
2920 if (softnic_parse_hex_string(tokens[3],
2921 m->match.hash.key, &key_size) != 0) {
2922 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2929 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2930 struct pkt_key_ipv4_5tuple *ipv4 =
2931 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2932 struct in_addr saddr, daddr;
2937 snprintf(out, out_size, MSG_ARG_MISMATCH,
2942 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2943 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2947 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2948 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2952 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2953 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2957 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2958 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2962 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2963 snprintf(out, out_size, MSG_ARG_INVALID,
2968 ipv4->sa = saddr.s_addr;
2969 ipv4->da = daddr.s_addr;
2970 ipv4->sp = rte_cpu_to_be_16(sp);
2971 ipv4->dp = rte_cpu_to_be_16(dp);
2972 ipv4->proto = proto;
2975 } /* hash ipv4_5tuple */
2977 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2978 struct pkt_key_ipv6_5tuple *ipv6 =
2979 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2980 struct in6_addr saddr, daddr;
2985 snprintf(out, out_size, MSG_ARG_MISMATCH,
2990 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2991 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2995 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2996 snprintf(out, out_size, MSG_ARG_INVALID, "da");
3000 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
3001 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
3005 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
3006 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3010 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3011 snprintf(out, out_size, MSG_ARG_INVALID,
3016 memcpy(ipv6->sa, saddr.s6_addr, 16);
3017 memcpy(ipv6->da, daddr.s6_addr, 16);
3018 ipv6->sp = rte_cpu_to_be_16(sp);
3019 ipv6->dp = rte_cpu_to_be_16(dp);
3020 ipv6->proto = proto;
3023 } /* hash ipv6_5tuple */
3025 if (strcmp(tokens[2], "ipv4_addr") == 0) {
3026 struct pkt_key_ipv4_addr *ipv4_addr =
3027 (struct pkt_key_ipv4_addr *)m->match.hash.key;
3028 struct in_addr addr;
3031 snprintf(out, out_size, MSG_ARG_MISMATCH,
3036 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3037 snprintf(out, out_size, MSG_ARG_INVALID,
3042 ipv4_addr->addr = addr.s_addr;
3045 } /* hash ipv4_addr */
3047 if (strcmp(tokens[2], "ipv6_addr") == 0) {
3048 struct pkt_key_ipv6_addr *ipv6_addr =
3049 (struct pkt_key_ipv6_addr *)m->match.hash.key;
3050 struct in6_addr addr;
3053 snprintf(out, out_size, MSG_ARG_MISMATCH,
3058 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3059 snprintf(out, out_size, MSG_ARG_INVALID,
3064 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
3067 } /* hash ipv6_5tuple */
3069 if (strcmp(tokens[2], "qinq") == 0) {
3070 struct pkt_key_qinq *qinq =
3071 (struct pkt_key_qinq *)m->match.hash.key;
3072 uint16_t svlan, cvlan;
3075 snprintf(out, out_size, MSG_ARG_MISMATCH,
3080 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
3082 snprintf(out, out_size, MSG_ARG_INVALID,
3087 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3089 snprintf(out, out_size, MSG_ARG_INVALID,
3094 qinq->svlan = rte_cpu_to_be_16(svlan);
3095 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3100 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3104 if (strcmp(tokens[1], "lpm") == 0) {
3106 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3110 m->match_type = TABLE_LPM;
3112 if (strcmp(tokens[2], "ipv4") == 0) {
3113 struct in_addr addr;
3115 m->match.lpm.ip_version = 1;
3117 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3118 snprintf(out, out_size, MSG_ARG_INVALID,
3123 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3124 } else if (strcmp(tokens[2], "ipv6") == 0) {
3125 struct in6_addr addr;
3127 m->match.lpm.ip_version = 0;
3129 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3130 snprintf(out, out_size, MSG_ARG_INVALID,
3135 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3137 snprintf(out, out_size, MSG_ARG_MISMATCH,
3142 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3143 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3150 snprintf(out, out_size, MSG_ARG_MISMATCH,
3151 "acl or array or hash or lpm");
3163 * | table <table_id>
3164 * [balance <out0> ... <out7>]
3166 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3167 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3168 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3169 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3170 * [tm subport <subport_id> pipe <pipe_id>]
3173 * | vlan <da> <sa> <pcp> <dei> <vid>
3174 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3175 * | mpls unicast | multicast
3177 * label0 <label> <tc> <ttl>
3178 * [label1 <label> <tc> <ttl>
3179 * [label2 <label> <tc> <ttl>
3180 * [label3 <label> <tc> <ttl>]]]
3181 * | pppoe <da> <sa> <session_id>]
3182 * [nat ipv4 | ipv6 <addr> <port>]
3189 * <pa> ::= g | y | r | drop
3192 parse_table_action_fwd(char **tokens,
3194 struct softnic_table_rule_action *a)
3196 if (n_tokens == 0 ||
3197 (strcmp(tokens[0], "fwd") != 0))
3203 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3204 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3205 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3209 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3213 softnic_parser_read_uint32(&id, tokens[1]))
3216 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3218 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3222 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3223 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3224 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3228 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3232 softnic_parser_read_uint32(&id, tokens[1]))
3235 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3237 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3245 parse_table_action_balance(char **tokens,
3247 struct softnic_table_rule_action *a)
3251 if (n_tokens == 0 ||
3252 (strcmp(tokens[0], "balance") != 0))
3258 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3261 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3262 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3265 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3266 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3270 parse_policer_action(char *token, enum rte_table_action_policer *a)
3272 if (strcmp(token, "g") == 0) {
3273 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3277 if (strcmp(token, "y") == 0) {
3278 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3282 if (strcmp(token, "r") == 0) {
3283 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3287 if (strcmp(token, "drop") == 0) {
3288 *a = RTE_TABLE_ACTION_POLICER_DROP;
3296 parse_table_action_meter_tc(char **tokens,
3298 struct rte_table_action_mtr_tc_params *mtr)
3301 strcmp(tokens[0], "meter") ||
3302 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3303 strcmp(tokens[2], "policer") ||
3304 strcmp(tokens[3], "g") ||
3305 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
3306 strcmp(tokens[5], "y") ||
3307 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
3308 strcmp(tokens[7], "r") ||
3309 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
3316 parse_table_action_meter(char **tokens,
3318 struct softnic_table_rule_action *a)
3320 if (n_tokens == 0 ||
3321 strcmp(tokens[0], "meter"))
3327 if (n_tokens < 10 ||
3328 strcmp(tokens[0], "tc0") ||
3329 (parse_table_action_meter_tc(tokens + 1,
3331 &a->mtr.mtr[0]) == 0))
3337 if (n_tokens == 0 ||
3338 strcmp(tokens[0], "tc1")) {
3340 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3344 if (n_tokens < 30 ||
3345 (parse_table_action_meter_tc(tokens + 1,
3346 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3347 strcmp(tokens[10], "tc2") ||
3348 (parse_table_action_meter_tc(tokens + 11,
3349 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3350 strcmp(tokens[20], "tc3") ||
3351 (parse_table_action_meter_tc(tokens + 21,
3352 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3355 a->mtr.tc_mask = 0xF;
3356 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3357 return 1 + 10 + 3 * 10;
3361 parse_table_action_tm(char **tokens,
3363 struct softnic_table_rule_action *a)
3365 uint32_t subport_id, pipe_id;
3368 strcmp(tokens[0], "tm") ||
3369 strcmp(tokens[1], "subport") ||
3370 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
3371 strcmp(tokens[3], "pipe") ||
3372 softnic_parser_read_uint32(&pipe_id, tokens[4]))
3375 a->tm.subport_id = subport_id;
3376 a->tm.pipe_id = pipe_id;
3377 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3382 parse_table_action_encap(char **tokens,
3384 struct softnic_table_rule_action *a)
3386 if (n_tokens == 0 ||
3387 strcmp(tokens[0], "encap"))
3394 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3396 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3397 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3400 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3401 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3406 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3407 uint32_t pcp, dei, vid;
3410 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3411 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3412 softnic_parser_read_uint32(&pcp, tokens[3]) ||
3414 softnic_parser_read_uint32(&dei, tokens[4]) ||
3416 softnic_parser_read_uint32(&vid, tokens[5]) ||
3420 a->encap.vlan.vlan.pcp = pcp & 0x7;
3421 a->encap.vlan.vlan.dei = dei & 0x1;
3422 a->encap.vlan.vlan.vid = vid & 0xFFF;
3423 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3424 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3429 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3430 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3431 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3434 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3435 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3436 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
3438 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
3440 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
3441 svlan_vid > 0xFFF ||
3442 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3444 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
3446 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
3450 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3451 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3452 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3453 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3454 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3455 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3456 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3457 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3462 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3463 uint32_t label, tc, ttl;
3468 if (strcmp(tokens[1], "unicast") == 0)
3469 a->encap.mpls.unicast = 1;
3470 else if (strcmp(tokens[1], "multicast") == 0)
3471 a->encap.mpls.unicast = 0;
3475 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3476 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3477 strcmp(tokens[4], "label0") ||
3478 softnic_parser_read_uint32(&label, tokens[5]) ||
3480 softnic_parser_read_uint32(&tc, tokens[6]) ||
3482 softnic_parser_read_uint32(&ttl, tokens[7]) ||
3486 a->encap.mpls.mpls[0].label = label;
3487 a->encap.mpls.mpls[0].tc = tc;
3488 a->encap.mpls.mpls[0].ttl = ttl;
3493 if (n_tokens == 0 ||
3494 strcmp(tokens[0], "label1")) {
3495 a->encap.mpls.mpls_count = 1;
3496 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3497 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3502 softnic_parser_read_uint32(&label, tokens[1]) ||
3504 softnic_parser_read_uint32(&tc, tokens[2]) ||
3506 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3510 a->encap.mpls.mpls[1].label = label;
3511 a->encap.mpls.mpls[1].tc = tc;
3512 a->encap.mpls.mpls[1].ttl = ttl;
3517 if (n_tokens == 0 ||
3518 strcmp(tokens[0], "label2")) {
3519 a->encap.mpls.mpls_count = 2;
3520 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3521 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3526 softnic_parser_read_uint32(&label, tokens[1]) ||
3528 softnic_parser_read_uint32(&tc, tokens[2]) ||
3530 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3534 a->encap.mpls.mpls[2].label = label;
3535 a->encap.mpls.mpls[2].tc = tc;
3536 a->encap.mpls.mpls[2].ttl = ttl;
3541 if (n_tokens == 0 ||
3542 strcmp(tokens[0], "label3")) {
3543 a->encap.mpls.mpls_count = 3;
3544 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3545 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3546 return 1 + 8 + 4 + 4;
3550 softnic_parser_read_uint32(&label, tokens[1]) ||
3552 softnic_parser_read_uint32(&tc, tokens[2]) ||
3554 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3558 a->encap.mpls.mpls[3].label = label;
3559 a->encap.mpls.mpls[3].tc = tc;
3560 a->encap.mpls.mpls[3].ttl = ttl;
3562 a->encap.mpls.mpls_count = 4;
3563 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3564 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3565 return 1 + 8 + 4 + 4 + 4;
3569 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3571 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3572 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3573 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3577 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3578 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3586 parse_table_action_nat(char **tokens,
3588 struct softnic_table_rule_action *a)
3591 strcmp(tokens[0], "nat"))
3594 if (strcmp(tokens[1], "ipv4") == 0) {
3595 struct in_addr addr;
3598 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3599 softnic_parser_read_uint16(&port, tokens[3]))
3602 a->nat.ip_version = 1;
3603 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3605 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3609 if (strcmp(tokens[1], "ipv6") == 0) {
3610 struct in6_addr addr;
3613 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3614 softnic_parser_read_uint16(&port, tokens[3]))
3617 a->nat.ip_version = 0;
3618 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3620 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3628 parse_table_action_ttl(char **tokens,
3630 struct softnic_table_rule_action *a)
3633 strcmp(tokens[0], "ttl"))
3636 if (strcmp(tokens[1], "dec") == 0)
3637 a->ttl.decrement = 1;
3638 else if (strcmp(tokens[1], "keep") == 0)
3639 a->ttl.decrement = 0;
3643 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3648 parse_table_action_stats(char **tokens,
3650 struct softnic_table_rule_action *a)
3653 strcmp(tokens[0], "stats"))
3656 a->stats.n_packets = 0;
3657 a->stats.n_bytes = 0;
3658 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3663 parse_table_action_time(char **tokens,
3665 struct softnic_table_rule_action *a)
3668 strcmp(tokens[0], "time"))
3671 a->time.time = rte_rdtsc();
3672 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3677 parse_table_action_tag(char **tokens,
3679 struct softnic_table_rule_action *a)
3682 strcmp(tokens[0], "tag"))
3685 if (softnic_parser_read_uint32(&a->tag.tag, tokens[1]))
3688 a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
3693 parse_table_action(char **tokens,
3697 struct softnic_table_rule_action *a)
3699 uint32_t n_tokens0 = n_tokens;
3701 memset(a, 0, sizeof(*a));
3704 strcmp(tokens[0], "action"))
3710 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3713 n = parse_table_action_fwd(tokens, n_tokens, a);
3715 snprintf(out, out_size, MSG_ARG_INVALID,
3724 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3727 n = parse_table_action_balance(tokens, n_tokens, a);
3729 snprintf(out, out_size, MSG_ARG_INVALID,
3738 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3741 n = parse_table_action_meter(tokens, n_tokens, a);
3743 snprintf(out, out_size, MSG_ARG_INVALID,
3752 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3755 n = parse_table_action_tm(tokens, n_tokens, a);
3757 snprintf(out, out_size, MSG_ARG_INVALID,
3766 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3769 n = parse_table_action_encap(tokens, n_tokens, a);
3771 snprintf(out, out_size, MSG_ARG_INVALID,
3780 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3783 n = parse_table_action_nat(tokens, n_tokens, a);
3785 snprintf(out, out_size, MSG_ARG_INVALID,
3794 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3797 n = parse_table_action_ttl(tokens, n_tokens, a);
3799 snprintf(out, out_size, MSG_ARG_INVALID,
3808 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3811 n = parse_table_action_stats(tokens, n_tokens, a);
3813 snprintf(out, out_size, MSG_ARG_INVALID,
3822 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3825 n = parse_table_action_time(tokens, n_tokens, a);
3827 snprintf(out, out_size, MSG_ARG_INVALID,
3836 if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
3839 n = parse_table_action_tag(tokens, n_tokens, a);
3841 snprintf(out, out_size, MSG_ARG_INVALID,
3850 if (n_tokens0 - n_tokens == 1) {
3851 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3855 return n_tokens0 - n_tokens;
3859 * pipeline <pipeline_name> table <table_id> rule add
3861 * action <table_action>
3864 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3870 struct softnic_table_rule_match m;
3871 struct softnic_table_rule_action a;
3872 char *pipeline_name;
3874 uint32_t table_id, t0, n_tokens_parsed;
3878 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3882 pipeline_name = tokens[1];
3884 if (strcmp(tokens[2], "table") != 0) {
3885 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3889 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3890 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3894 if (strcmp(tokens[4], "rule") != 0) {
3895 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3899 if (strcmp(tokens[5], "add") != 0) {
3900 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3907 n_tokens_parsed = parse_match(tokens + t0,
3912 if (n_tokens_parsed == 0)
3914 t0 += n_tokens_parsed;
3917 n_tokens_parsed = parse_table_action(tokens + t0,
3922 if (n_tokens_parsed == 0)
3924 t0 += n_tokens_parsed;
3926 if (t0 != n_tokens) {
3927 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3931 status = softnic_pipeline_table_rule_add(softnic,
3938 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3944 * pipeline <pipeline_name> table <table_id> rule add
3952 * | table <table_id>
3955 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3961 struct softnic_table_rule_action action;
3963 char *pipeline_name;
3967 if (n_tokens != 11 &&
3969 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3973 pipeline_name = tokens[1];
3975 if (strcmp(tokens[2], "table") != 0) {
3976 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3980 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3981 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3985 if (strcmp(tokens[4], "rule") != 0) {
3986 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3990 if (strcmp(tokens[5], "add") != 0) {
3991 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3995 if (strcmp(tokens[6], "match") != 0) {
3996 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4000 if (strcmp(tokens[7], "default") != 0) {
4001 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4005 if (strcmp(tokens[8], "action") != 0) {
4006 snprintf(out, out_size, MSG_ARG_INVALID, "action");
4010 if (strcmp(tokens[9], "fwd") != 0) {
4011 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
4015 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
4017 if (strcmp(tokens[10], "drop") == 0) {
4018 if (n_tokens != 11) {
4019 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4023 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
4024 } else if (strcmp(tokens[10], "port") == 0) {
4027 if (n_tokens != 12) {
4028 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4032 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4033 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4037 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4039 } else if (strcmp(tokens[10], "meta") == 0) {
4040 if (n_tokens != 11) {
4041 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4045 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4046 } else if (strcmp(tokens[10], "table") == 0) {
4049 if (n_tokens != 12) {
4050 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4054 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4055 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4059 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4062 snprintf(out, out_size, MSG_ARG_INVALID,
4063 "drop or port or meta or table");
4067 status = softnic_pipeline_table_rule_add_default(softnic,
4073 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4079 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
4082 * - line format: match <match> action <action>
4085 cli_rule_file_process(const char *file_name,
4086 size_t line_len_max,
4087 struct softnic_table_rule_match *m,
4088 struct softnic_table_rule_action *a,
4090 uint32_t *line_number,
4095 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
4101 struct softnic_table_rule_match *match;
4102 struct softnic_table_rule_action *action;
4104 char *pipeline_name, *file_name;
4105 uint32_t table_id, n_rules, n_rules_parsed, line_number;
4108 if (n_tokens != 9) {
4109 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4113 pipeline_name = tokens[1];
4115 if (strcmp(tokens[2], "table") != 0) {
4116 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4120 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4121 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4125 if (strcmp(tokens[4], "rule") != 0) {
4126 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4130 if (strcmp(tokens[5], "add") != 0) {
4131 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4135 if (strcmp(tokens[6], "bulk") != 0) {
4136 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4140 file_name = tokens[7];
4142 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
4144 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
4148 /* Memory allocation. */
4149 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
4150 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
4151 data = calloc(n_rules, sizeof(void *));
4152 if (match == NULL ||
4155 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
4162 /* Load rule file */
4163 n_rules_parsed = n_rules;
4164 status = cli_rule_file_process(file_name,
4173 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4179 if (n_rules_parsed != n_rules) {
4180 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
4188 status = softnic_pipeline_table_rule_add_bulk(softnic,
4196 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4210 * pipeline <pipeline_name> table <table_id> rule delete
4214 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
4220 struct softnic_table_rule_match m;
4221 char *pipeline_name;
4222 uint32_t table_id, n_tokens_parsed, t0;
4226 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4230 pipeline_name = tokens[1];
4232 if (strcmp(tokens[2], "table") != 0) {
4233 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4237 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4238 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4242 if (strcmp(tokens[4], "rule") != 0) {
4243 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4247 if (strcmp(tokens[5], "delete") != 0) {
4248 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4255 n_tokens_parsed = parse_match(tokens + t0,
4260 if (n_tokens_parsed == 0)
4262 t0 += n_tokens_parsed;
4264 if (n_tokens != t0) {
4265 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4269 status = softnic_pipeline_table_rule_delete(softnic,
4274 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4280 * pipeline <pipeline_name> table <table_id> rule delete
4285 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
4291 char *pipeline_name;
4295 if (n_tokens != 8) {
4296 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4300 pipeline_name = tokens[1];
4302 if (strcmp(tokens[2], "table") != 0) {
4303 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4307 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4308 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4312 if (strcmp(tokens[4], "rule") != 0) {
4313 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4317 if (strcmp(tokens[5], "delete") != 0) {
4318 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4322 if (strcmp(tokens[6], "match") != 0) {
4323 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4327 if (strcmp(tokens[7], "default") != 0) {
4328 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4332 status = softnic_pipeline_table_rule_delete_default(softnic,
4336 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4342 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
4345 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
4347 uint32_t n_tokens __rte_unused,
4351 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4355 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
4356 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
4357 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
4360 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
4366 struct rte_table_action_meter_profile p;
4367 char *pipeline_name;
4368 uint32_t table_id, meter_profile_id;
4372 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4376 pipeline_name = tokens[1];
4378 if (strcmp(tokens[2], "table") != 0) {
4379 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4383 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4384 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4388 if (strcmp(tokens[4], "meter") != 0) {
4389 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4393 if (strcmp(tokens[5], "profile") != 0) {
4394 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4398 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4399 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4403 if (strcmp(tokens[7], "add") != 0) {
4404 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4408 if (strcmp(tokens[8], "srtcm") == 0) {
4409 if (n_tokens != 15) {
4410 snprintf(out, out_size, MSG_ARG_MISMATCH,
4415 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
4417 if (strcmp(tokens[9], "cir") != 0) {
4418 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4422 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
4423 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4427 if (strcmp(tokens[11], "cbs") != 0) {
4428 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4432 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
4433 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4437 if (strcmp(tokens[13], "ebs") != 0) {
4438 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
4442 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
4443 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
4446 } else if (strcmp(tokens[8], "trtcm") == 0) {
4447 if (n_tokens != 17) {
4448 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4452 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
4454 if (strcmp(tokens[9], "cir") != 0) {
4455 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4459 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
4460 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4464 if (strcmp(tokens[11], "pir") != 0) {
4465 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
4469 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
4470 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
4473 if (strcmp(tokens[13], "cbs") != 0) {
4474 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4478 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
4479 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4483 if (strcmp(tokens[15], "pbs") != 0) {
4484 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
4488 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
4489 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
4493 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4497 status = softnic_pipeline_table_mtr_profile_add(softnic,
4503 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4509 * pipeline <pipeline_name> table <table_id>
4510 * meter profile <meter_profile_id> delete
4513 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
4519 char *pipeline_name;
4520 uint32_t table_id, meter_profile_id;
4523 if (n_tokens != 8) {
4524 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4528 pipeline_name = tokens[1];
4530 if (strcmp(tokens[2], "table") != 0) {
4531 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4535 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4536 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4540 if (strcmp(tokens[4], "meter") != 0) {
4541 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4545 if (strcmp(tokens[5], "profile") != 0) {
4546 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4550 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4551 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4555 if (strcmp(tokens[7], "delete") != 0) {
4556 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4560 status = softnic_pipeline_table_mtr_profile_delete(softnic,
4565 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4571 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
4574 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
4576 uint32_t n_tokens __rte_unused,
4580 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4584 * pipeline <pipeline_name> table <table_id> dscp <file_name>
4587 * - exactly 64 lines
4588 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
4591 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4592 const char *file_name,
4593 uint32_t *line_number)
4598 /* Check input arguments */
4599 if (dscp_table == NULL ||
4600 file_name == NULL ||
4601 line_number == NULL) {
4607 /* Open input file */
4608 f = fopen(file_name, "r");
4615 for (dscp = 0, l = 1; ; l++) {
4618 enum rte_meter_color color;
4619 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4621 if (fgets(line, sizeof(line), f) == NULL)
4624 if (is_comment(line))
4627 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
4636 if (dscp >= RTE_DIM(dscp_table->entry) ||
4637 n_tokens != RTE_DIM(tokens) ||
4638 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
4639 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
4640 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
4641 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
4642 (strlen(tokens[2]) != 1)) {
4648 switch (tokens[2][0]) {
4651 color = e_RTE_METER_GREEN;
4656 color = e_RTE_METER_YELLOW;
4661 color = e_RTE_METER_RED;
4670 dscp_table->entry[dscp].tc_id = tc_id;
4671 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4672 dscp_table->entry[dscp].color = color;
4682 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
4688 struct rte_table_action_dscp_table dscp_table;
4689 char *pipeline_name, *file_name;
4690 uint32_t table_id, line_number;
4693 if (n_tokens != 6) {
4694 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4698 pipeline_name = tokens[1];
4700 if (strcmp(tokens[2], "table") != 0) {
4701 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4705 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4706 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4710 if (strcmp(tokens[4], "dscp") != 0) {
4711 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4715 file_name = tokens[5];
4717 status = load_dscp_table(&dscp_table, file_name, &line_number);
4719 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4723 status = softnic_pipeline_table_dscp_table_update(softnic,
4729 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4735 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4738 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4740 uint32_t n_tokens __rte_unused,
4744 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4748 * thread <thread_id> pipeline <pipeline_name> enable
4751 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4757 char *pipeline_name;
4761 if (n_tokens != 5) {
4762 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4766 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4767 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4771 if (strcmp(tokens[2], "pipeline") != 0) {
4772 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4776 pipeline_name = tokens[3];
4778 if (strcmp(tokens[4], "enable") != 0) {
4779 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4783 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4785 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4791 * thread <thread_id> pipeline <pipeline_name> disable
4794 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4800 char *pipeline_name;
4804 if (n_tokens != 5) {
4805 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4809 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4810 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4814 if (strcmp(tokens[2], "pipeline") != 0) {
4815 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4819 pipeline_name = tokens[3];
4821 if (strcmp(tokens[4], "disable") != 0) {
4822 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4826 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4828 snprintf(out, out_size, MSG_CMD_FAIL,
4829 "thread pipeline disable");
4838 * pipeline <pipeline_name>
4842 cmd_softnic_flowapi_map(struct pmd_internals *softnic,
4848 char *pipeline_name;
4849 uint32_t group_id, table_id;
4850 int ingress, status;
4852 if (n_tokens != 9) {
4853 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4857 if (strcmp(tokens[1], "map") != 0) {
4858 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "map");
4862 if (strcmp(tokens[2], "group") != 0) {
4863 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group");
4867 if (softnic_parser_read_uint32(&group_id, tokens[3]) != 0) {
4868 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
4872 if (strcmp(tokens[4], "ingress") == 0) {
4874 } else if (strcmp(tokens[4], "egress") == 0) {
4877 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ingress | egress");
4881 if (strcmp(tokens[5], "pipeline") != 0) {
4882 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4886 pipeline_name = tokens[6];
4888 if (strcmp(tokens[7], "table") != 0) {
4889 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4893 if (softnic_parser_read_uint32(&table_id, tokens[8]) != 0) {
4894 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4898 status = flow_attr_map_set(softnic,
4904 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4910 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4912 char *tokens[CMD_MAX_TOKENS];
4913 uint32_t n_tokens = RTE_DIM(tokens);
4914 struct pmd_internals *softnic = arg;
4920 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4922 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4929 if (strcmp(tokens[0], "mempool") == 0) {
4930 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4934 if (strcmp(tokens[0], "link") == 0) {
4935 cmd_link(softnic, tokens, n_tokens, out, out_size);
4939 if (strcmp(tokens[0], "swq") == 0) {
4940 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4944 if (strcmp(tokens[0], "tmgr") == 0) {
4945 if (n_tokens == 2) {
4946 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4950 if (n_tokens >= 3 &&
4951 (strcmp(tokens[1], "shaper") == 0) &&
4952 (strcmp(tokens[2], "profile") == 0)) {
4953 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4957 if (n_tokens >= 3 &&
4958 (strcmp(tokens[1], "shared") == 0) &&
4959 (strcmp(tokens[2], "shaper") == 0)) {
4960 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
4964 if (n_tokens >= 2 &&
4965 (strcmp(tokens[1], "node") == 0)) {
4966 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
4970 if (n_tokens >= 2 &&
4971 (strcmp(tokens[1], "hierarchy-default") == 0)) {
4972 cmd_tmgr_hierarchy_default(softnic, tokens, n_tokens, out, out_size);
4976 if (n_tokens >= 3 &&
4977 (strcmp(tokens[1], "hierarchy") == 0) &&
4978 (strcmp(tokens[2], "commit") == 0)) {
4979 cmd_tmgr_hierarchy_commit(softnic, tokens, n_tokens, out, out_size);
4984 if (strcmp(tokens[0], "tap") == 0) {
4985 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4989 if (strcmp(tokens[0], "port") == 0) {
4990 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4994 if (strcmp(tokens[0], "table") == 0) {
4995 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4999 if (strcmp(tokens[0], "pipeline") == 0) {
5000 if (n_tokens >= 3 &&
5001 (strcmp(tokens[2], "period") == 0)) {
5002 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
5006 if (n_tokens >= 5 &&
5007 (strcmp(tokens[2], "port") == 0) &&
5008 (strcmp(tokens[3], "in") == 0) &&
5009 (strcmp(tokens[4], "bsz") == 0)) {
5010 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
5014 if (n_tokens >= 5 &&
5015 (strcmp(tokens[2], "port") == 0) &&
5016 (strcmp(tokens[3], "out") == 0) &&
5017 (strcmp(tokens[4], "bsz") == 0)) {
5018 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
5022 if (n_tokens >= 4 &&
5023 (strcmp(tokens[2], "table") == 0) &&
5024 (strcmp(tokens[3], "match") == 0)) {
5025 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
5029 if (n_tokens >= 6 &&
5030 (strcmp(tokens[2], "port") == 0) &&
5031 (strcmp(tokens[3], "in") == 0) &&
5032 (strcmp(tokens[5], "table") == 0)) {
5033 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
5038 if (n_tokens >= 6 &&
5039 (strcmp(tokens[2], "port") == 0) &&
5040 (strcmp(tokens[3], "in") == 0) &&
5041 (strcmp(tokens[5], "stats") == 0)) {
5042 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
5047 if (n_tokens >= 6 &&
5048 (strcmp(tokens[2], "port") == 0) &&
5049 (strcmp(tokens[3], "in") == 0) &&
5050 (strcmp(tokens[5], "enable") == 0)) {
5051 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
5056 if (n_tokens >= 6 &&
5057 (strcmp(tokens[2], "port") == 0) &&
5058 (strcmp(tokens[3], "in") == 0) &&
5059 (strcmp(tokens[5], "disable") == 0)) {
5060 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
5065 if (n_tokens >= 6 &&
5066 (strcmp(tokens[2], "port") == 0) &&
5067 (strcmp(tokens[3], "out") == 0) &&
5068 (strcmp(tokens[5], "stats") == 0)) {
5069 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
5074 if (n_tokens >= 5 &&
5075 (strcmp(tokens[2], "table") == 0) &&
5076 (strcmp(tokens[4], "stats") == 0)) {
5077 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
5082 if (n_tokens >= 7 &&
5083 (strcmp(tokens[2], "table") == 0) &&
5084 (strcmp(tokens[4], "rule") == 0) &&
5085 (strcmp(tokens[5], "add") == 0) &&
5086 (strcmp(tokens[6], "match") == 0)) {
5087 if (n_tokens >= 8 &&
5088 (strcmp(tokens[7], "default") == 0)) {
5089 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
5090 n_tokens, out, out_size);
5094 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
5099 if (n_tokens >= 7 &&
5100 (strcmp(tokens[2], "table") == 0) &&
5101 (strcmp(tokens[4], "rule") == 0) &&
5102 (strcmp(tokens[5], "add") == 0) &&
5103 (strcmp(tokens[6], "bulk") == 0)) {
5104 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
5105 n_tokens, out, out_size);
5109 if (n_tokens >= 7 &&
5110 (strcmp(tokens[2], "table") == 0) &&
5111 (strcmp(tokens[4], "rule") == 0) &&
5112 (strcmp(tokens[5], "delete") == 0) &&
5113 (strcmp(tokens[6], "match") == 0)) {
5114 if (n_tokens >= 8 &&
5115 (strcmp(tokens[7], "default") == 0)) {
5116 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
5117 n_tokens, out, out_size);
5121 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
5126 if (n_tokens >= 7 &&
5127 (strcmp(tokens[2], "table") == 0) &&
5128 (strcmp(tokens[4], "rule") == 0) &&
5129 (strcmp(tokens[5], "read") == 0) &&
5130 (strcmp(tokens[6], "stats") == 0)) {
5131 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
5136 if (n_tokens >= 8 &&
5137 (strcmp(tokens[2], "table") == 0) &&
5138 (strcmp(tokens[4], "meter") == 0) &&
5139 (strcmp(tokens[5], "profile") == 0) &&
5140 (strcmp(tokens[7], "add") == 0)) {
5141 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
5146 if (n_tokens >= 8 &&
5147 (strcmp(tokens[2], "table") == 0) &&
5148 (strcmp(tokens[4], "meter") == 0) &&
5149 (strcmp(tokens[5], "profile") == 0) &&
5150 (strcmp(tokens[7], "delete") == 0)) {
5151 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
5152 n_tokens, out, out_size);
5156 if (n_tokens >= 7 &&
5157 (strcmp(tokens[2], "table") == 0) &&
5158 (strcmp(tokens[4], "rule") == 0) &&
5159 (strcmp(tokens[5], "read") == 0) &&
5160 (strcmp(tokens[6], "meter") == 0)) {
5161 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
5166 if (n_tokens >= 5 &&
5167 (strcmp(tokens[2], "table") == 0) &&
5168 (strcmp(tokens[4], "dscp") == 0)) {
5169 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
5174 if (n_tokens >= 7 &&
5175 (strcmp(tokens[2], "table") == 0) &&
5176 (strcmp(tokens[4], "rule") == 0) &&
5177 (strcmp(tokens[5], "read") == 0) &&
5178 (strcmp(tokens[6], "ttl") == 0)) {
5179 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
5185 if (strcmp(tokens[0], "thread") == 0) {
5186 if (n_tokens >= 5 &&
5187 (strcmp(tokens[4], "enable") == 0)) {
5188 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
5193 if (n_tokens >= 5 &&
5194 (strcmp(tokens[4], "disable") == 0)) {
5195 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
5201 if (strcmp(tokens[0], "flowapi") == 0) {
5202 cmd_softnic_flowapi_map(softnic, tokens, n_tokens, out,
5207 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5211 softnic_cli_script_process(struct pmd_internals *softnic,
5212 const char *file_name,
5213 size_t msg_in_len_max,
5214 size_t msg_out_len_max)
5216 char *msg_in = NULL, *msg_out = NULL;
5219 /* Check input arguments */
5220 if (file_name == NULL ||
5221 (strlen(file_name) == 0) ||
5222 msg_in_len_max == 0 ||
5223 msg_out_len_max == 0)
5226 msg_in = malloc(msg_in_len_max + 1);
5227 msg_out = malloc(msg_out_len_max + 1);
5228 if (msg_in == NULL ||
5235 /* Open input file */
5236 f = fopen(file_name, "r");
5245 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5248 printf("%s", msg_in);
5251 softnic_cli_process(msg_in,
5256 if (strlen(msg_out))
5257 printf("%s", msg_out);
5268 cli_rule_file_process(const char *file_name,
5269 size_t line_len_max,
5270 struct softnic_table_rule_match *m,
5271 struct softnic_table_rule_action *a,
5273 uint32_t *line_number,
5279 uint32_t rule_id, line_id;
5282 /* Check input arguments */
5283 if (file_name == NULL ||
5284 (strlen(file_name) == 0) ||
5285 line_len_max == 0) {
5290 /* Memory allocation */
5291 line = malloc(line_len_max + 1);
5298 f = fopen(file_name, "r");
5306 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
5307 char *tokens[CMD_MAX_TOKENS];
5308 uint32_t n_tokens, n_tokens_parsed, t0;
5310 /* Read next line from file. */
5311 if (fgets(line, line_len_max + 1, f) == NULL)
5315 if (is_comment(line))
5319 n_tokens = RTE_DIM(tokens);
5320 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
5332 n_tokens_parsed = parse_match(tokens + t0,
5337 if (n_tokens_parsed == 0) {
5341 t0 += n_tokens_parsed;
5344 n_tokens_parsed = parse_table_action(tokens + t0,
5349 if (n_tokens_parsed == 0) {
5353 t0 += n_tokens_parsed;
5355 /* Line completed. */
5356 if (t0 < n_tokens) {
5361 /* Increment rule count */
5372 *line_number = line_id;