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]
1284 cmd_table_action_profile(struct pmd_internals *softnic,
1290 struct softnic_table_action_profile_params p;
1291 struct softnic_table_action_profile *ap;
1295 memset(&p, 0, sizeof(p));
1298 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1302 if (strcmp(tokens[1], "action") != 0) {
1303 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
1307 if (strcmp(tokens[2], "profile") != 0) {
1308 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1314 if (strcmp(tokens[4], "ipv4") == 0) {
1315 p.common.ip_version = 1;
1316 } else if (strcmp(tokens[4], "ipv6") == 0) {
1317 p.common.ip_version = 0;
1319 snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
1323 if (strcmp(tokens[5], "offset") != 0) {
1324 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1328 if (softnic_parser_read_uint32(&p.common.ip_offset,
1330 snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
1334 if (strcmp(tokens[7], "fwd") != 0) {
1335 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
1339 p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
1342 if (t0 < n_tokens &&
1343 (strcmp(tokens[t0], "balance") == 0)) {
1344 if (n_tokens < t0 + 7) {
1345 snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
1349 if (strcmp(tokens[t0 + 1], "offset") != 0) {
1350 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1354 if (softnic_parser_read_uint32(&p.lb.key_offset,
1355 tokens[t0 + 2]) != 0) {
1356 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1360 if (strcmp(tokens[t0 + 3], "mask") != 0) {
1361 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1365 p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
1366 if (softnic_parse_hex_string(tokens[t0 + 4],
1367 p.lb.key_mask, &p.lb.key_size) != 0) {
1368 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1372 if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
1373 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
1377 if (softnic_parser_read_uint32(&p.lb.out_offset,
1378 tokens[t0 + 6]) != 0) {
1379 snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
1383 p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
1387 if (t0 < n_tokens &&
1388 (strcmp(tokens[t0], "meter") == 0)) {
1389 if (n_tokens < t0 + 6) {
1390 snprintf(out, out_size, MSG_ARG_MISMATCH,
1391 "table action profile meter");
1395 if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
1396 p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
1397 } else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
1398 p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
1400 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1405 if (strcmp(tokens[t0 + 2], "tc") != 0) {
1406 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
1410 if (softnic_parser_read_uint32(&p.mtr.n_tc,
1411 tokens[t0 + 3]) != 0) {
1412 snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
1416 if (strcmp(tokens[t0 + 4], "stats") != 0) {
1417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1421 if (strcmp(tokens[t0 + 5], "none") == 0) {
1422 p.mtr.n_packets_enabled = 0;
1423 p.mtr.n_bytes_enabled = 0;
1424 } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
1425 p.mtr.n_packets_enabled = 1;
1426 p.mtr.n_bytes_enabled = 0;
1427 } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
1428 p.mtr.n_packets_enabled = 0;
1429 p.mtr.n_bytes_enabled = 1;
1430 } else if (strcmp(tokens[t0 + 5], "both") == 0) {
1431 p.mtr.n_packets_enabled = 1;
1432 p.mtr.n_bytes_enabled = 1;
1434 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1435 "none or pkts or bytes or both");
1439 p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
1443 if (t0 < n_tokens &&
1444 (strcmp(tokens[t0], "tm") == 0)) {
1445 if (n_tokens < t0 + 5) {
1446 snprintf(out, out_size, MSG_ARG_MISMATCH,
1447 "table action profile tm");
1451 if (strcmp(tokens[t0 + 1], "spp") != 0) {
1452 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
1456 if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
1457 tokens[t0 + 2]) != 0) {
1458 snprintf(out, out_size, MSG_ARG_INVALID,
1459 "n_subports_per_port");
1463 if (strcmp(tokens[t0 + 3], "pps") != 0) {
1464 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
1468 if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
1469 tokens[t0 + 4]) != 0) {
1470 snprintf(out, out_size, MSG_ARG_INVALID,
1471 "n_pipes_per_subport");
1475 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
1479 if (t0 < n_tokens &&
1480 (strcmp(tokens[t0], "encap") == 0)) {
1481 if (n_tokens < t0 + 2) {
1482 snprintf(out, out_size, MSG_ARG_MISMATCH,
1483 "action profile encap");
1487 if (strcmp(tokens[t0 + 1], "ether") == 0) {
1488 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
1489 } else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
1490 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
1491 } else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
1492 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
1493 } else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
1494 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
1495 } else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
1496 p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
1498 snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
1502 p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
1506 if (t0 < n_tokens &&
1507 (strcmp(tokens[t0], "nat") == 0)) {
1508 if (n_tokens < t0 + 4) {
1509 snprintf(out, out_size, MSG_ARG_MISMATCH,
1510 "table action profile nat");
1514 if (strcmp(tokens[t0 + 1], "src") == 0) {
1515 p.nat.source_nat = 1;
1516 } else if (strcmp(tokens[t0 + 1], "dst") == 0) {
1517 p.nat.source_nat = 0;
1519 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1524 if (strcmp(tokens[t0 + 2], "proto") != 0) {
1525 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
1529 if (strcmp(tokens[t0 + 3], "tcp") == 0) {
1531 } else if (strcmp(tokens[t0 + 3], "udp") == 0) {
1534 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1539 p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
1543 if (t0 < n_tokens &&
1544 (strcmp(tokens[t0], "ttl") == 0)) {
1545 if (n_tokens < t0 + 4) {
1546 snprintf(out, out_size, MSG_ARG_MISMATCH,
1547 "table action profile ttl");
1551 if (strcmp(tokens[t0 + 1], "drop") == 0) {
1553 } else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
1556 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1561 if (strcmp(tokens[t0 + 2], "stats") != 0) {
1562 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
1566 if (strcmp(tokens[t0 + 3], "none") == 0) {
1567 p.ttl.n_packets_enabled = 0;
1568 } else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
1569 p.ttl.n_packets_enabled = 1;
1571 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1576 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
1580 if (t0 < n_tokens &&
1581 (strcmp(tokens[t0], "stats") == 0)) {
1582 if (n_tokens < t0 + 2) {
1583 snprintf(out, out_size, MSG_ARG_MISMATCH,
1584 "table action profile stats");
1588 if (strcmp(tokens[t0 + 1], "pkts") == 0) {
1589 p.stats.n_packets_enabled = 1;
1590 p.stats.n_bytes_enabled = 0;
1591 } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
1592 p.stats.n_packets_enabled = 0;
1593 p.stats.n_bytes_enabled = 1;
1594 } else if (strcmp(tokens[t0 + 1], "both") == 0) {
1595 p.stats.n_packets_enabled = 1;
1596 p.stats.n_bytes_enabled = 1;
1598 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1599 "pkts or bytes or both");
1603 p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
1607 if (t0 < n_tokens &&
1608 (strcmp(tokens[t0], "time") == 0)) {
1609 p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
1613 if (t0 < n_tokens) {
1614 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1618 ap = softnic_table_action_profile_create(softnic, name, &p);
1620 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1626 * pipeline <pipeline_name>
1627 * period <timer_period_ms>
1628 * offset_port_id <offset_port_id>
1631 cmd_pipeline(struct pmd_internals *softnic,
1637 struct pipeline_params p;
1639 struct pipeline *pipeline;
1641 if (n_tokens != 6) {
1642 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1648 if (strcmp(tokens[2], "period") != 0) {
1649 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
1653 if (softnic_parser_read_uint32(&p.timer_period_ms,
1655 snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
1659 if (strcmp(tokens[4], "offset_port_id") != 0) {
1660 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
1664 if (softnic_parser_read_uint32(&p.offset_port_id,
1666 snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
1670 pipeline = softnic_pipeline_create(softnic, name, &p);
1671 if (pipeline == NULL) {
1672 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1678 * pipeline <pipeline_name> port in
1680 * link <link_name> rxq <queue_id>
1682 * | tmgr <tmgr_name>
1683 * | tap <tap_name> mempool <mempool_name> mtu <mtu>
1684 * | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
1685 * [action <port_in_action_profile_name>]
1689 cmd_pipeline_port_in(struct pmd_internals *softnic,
1695 struct softnic_port_in_params p;
1696 char *pipeline_name;
1698 int enabled, status;
1701 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1705 pipeline_name = tokens[1];
1707 if (strcmp(tokens[2], "port") != 0) {
1708 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1712 if (strcmp(tokens[3], "in") != 0) {
1713 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1717 if (strcmp(tokens[4], "bsz") != 0) {
1718 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1722 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1723 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1729 if (strcmp(tokens[t0], "link") == 0) {
1730 if (n_tokens < t0 + 4) {
1731 snprintf(out, out_size, MSG_ARG_MISMATCH,
1732 "pipeline port in link");
1736 p.type = PORT_IN_RXQ;
1738 p.dev_name = tokens[t0 + 1];
1740 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1741 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1745 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1746 tokens[t0 + 3]) != 0) {
1747 snprintf(out, out_size, MSG_ARG_INVALID,
1752 } else if (strcmp(tokens[t0], "swq") == 0) {
1753 if (n_tokens < t0 + 2) {
1754 snprintf(out, out_size, MSG_ARG_MISMATCH,
1755 "pipeline port in swq");
1759 p.type = PORT_IN_SWQ;
1761 p.dev_name = tokens[t0 + 1];
1764 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1765 if (n_tokens < t0 + 2) {
1766 snprintf(out, out_size, MSG_ARG_MISMATCH,
1767 "pipeline port in tmgr");
1771 p.type = PORT_IN_TMGR;
1773 p.dev_name = tokens[t0 + 1];
1776 } else if (strcmp(tokens[t0], "tap") == 0) {
1777 if (n_tokens < t0 + 6) {
1778 snprintf(out, out_size, MSG_ARG_MISMATCH,
1779 "pipeline port in tap");
1783 p.type = PORT_IN_TAP;
1785 p.dev_name = tokens[t0 + 1];
1787 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1788 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1793 p.tap.mempool_name = tokens[t0 + 3];
1795 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1796 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1801 if (softnic_parser_read_uint32(&p.tap.mtu,
1802 tokens[t0 + 5]) != 0) {
1803 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1808 } else if (strcmp(tokens[t0], "source") == 0) {
1809 if (n_tokens < t0 + 6) {
1810 snprintf(out, out_size, MSG_ARG_MISMATCH,
1811 "pipeline port in source");
1815 p.type = PORT_IN_SOURCE;
1819 if (strcmp(tokens[t0 + 1], "mempool") != 0) {
1820 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1825 p.source.mempool_name = tokens[t0 + 2];
1827 if (strcmp(tokens[t0 + 3], "file") != 0) {
1828 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1833 p.source.file_name = tokens[t0 + 4];
1835 if (strcmp(tokens[t0 + 5], "bpp") != 0) {
1836 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1841 if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
1842 tokens[t0 + 6]) != 0) {
1843 snprintf(out, out_size, MSG_ARG_INVALID,
1850 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1854 p.action_profile_name = NULL;
1855 if (n_tokens > t0 &&
1856 (strcmp(tokens[t0], "action") == 0)) {
1857 if (n_tokens < t0 + 2) {
1858 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1862 p.action_profile_name = tokens[t0 + 1];
1868 if (n_tokens > t0 &&
1869 (strcmp(tokens[t0], "disabled") == 0)) {
1875 if (n_tokens != t0) {
1876 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1880 status = softnic_pipeline_port_in_create(softnic,
1885 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1891 * pipeline <pipeline_name> port out
1893 * link <link_name> txq <txq_id>
1895 * | tmgr <tmgr_name>
1897 * | sink [file <file_name> pkts <max_n_pkts>]
1900 cmd_pipeline_port_out(struct pmd_internals *softnic,
1906 struct softnic_port_out_params p;
1907 char *pipeline_name;
1910 memset(&p, 0, sizeof(p));
1913 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1917 pipeline_name = tokens[1];
1919 if (strcmp(tokens[2], "port") != 0) {
1920 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1924 if (strcmp(tokens[3], "out") != 0) {
1925 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1929 if (strcmp(tokens[4], "bsz") != 0) {
1930 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1934 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1935 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1939 if (strcmp(tokens[6], "link") == 0) {
1940 if (n_tokens != 10) {
1941 snprintf(out, out_size, MSG_ARG_MISMATCH,
1942 "pipeline port out link");
1946 p.type = PORT_OUT_TXQ;
1948 p.dev_name = tokens[7];
1950 if (strcmp(tokens[8], "txq") != 0) {
1951 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1955 if (softnic_parser_read_uint16(&p.txq.queue_id,
1957 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1960 } else if (strcmp(tokens[6], "swq") == 0) {
1961 if (n_tokens != 8) {
1962 snprintf(out, out_size, MSG_ARG_MISMATCH,
1963 "pipeline port out swq");
1967 p.type = PORT_OUT_SWQ;
1969 p.dev_name = tokens[7];
1970 } else if (strcmp(tokens[6], "tmgr") == 0) {
1971 if (n_tokens != 8) {
1972 snprintf(out, out_size, MSG_ARG_MISMATCH,
1973 "pipeline port out tmgr");
1977 p.type = PORT_OUT_TMGR;
1979 p.dev_name = tokens[7];
1980 } else if (strcmp(tokens[6], "tap") == 0) {
1981 if (n_tokens != 8) {
1982 snprintf(out, out_size, MSG_ARG_MISMATCH,
1983 "pipeline port out tap");
1987 p.type = PORT_OUT_TAP;
1989 p.dev_name = tokens[7];
1990 } else if (strcmp(tokens[6], "sink") == 0) {
1991 if ((n_tokens != 7) && (n_tokens != 11)) {
1992 snprintf(out, out_size, MSG_ARG_MISMATCH,
1993 "pipeline port out sink");
1997 p.type = PORT_OUT_SINK;
2001 if (n_tokens == 7) {
2002 p.sink.file_name = NULL;
2003 p.sink.max_n_pkts = 0;
2005 if (strcmp(tokens[7], "file") != 0) {
2006 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2011 p.sink.file_name = tokens[8];
2013 if (strcmp(tokens[9], "pkts") != 0) {
2014 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
2018 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
2020 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
2025 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2029 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
2031 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2037 * pipeline <pipeline_name> table
2041 * offset <ip_header_offset>
2044 * offset <key_offset>
2050 * offset <key_offset>
2051 * buckets <n_buckets>
2055 * offset <ip_header_offset>
2058 * [action <table_action_profile_name>]
2061 cmd_pipeline_table(struct pmd_internals *softnic,
2067 uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
2068 struct softnic_table_params p;
2069 char *pipeline_name;
2074 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2078 pipeline_name = tokens[1];
2080 if (strcmp(tokens[2], "table") != 0) {
2081 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2085 if (strcmp(tokens[3], "match") != 0) {
2086 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2091 if (strcmp(tokens[t0], "acl") == 0) {
2092 if (n_tokens < t0 + 6) {
2093 snprintf(out, out_size, MSG_ARG_MISMATCH,
2094 "pipeline table acl");
2098 p.match_type = TABLE_ACL;
2100 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2101 p.match.acl.ip_version = 1;
2102 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2103 p.match.acl.ip_version = 0;
2105 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2110 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2111 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2115 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
2116 tokens[t0 + 3]) != 0) {
2117 snprintf(out, out_size, MSG_ARG_INVALID,
2118 "ip_header_offset");
2122 if (strcmp(tokens[t0 + 4], "size") != 0) {
2123 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2127 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
2128 tokens[t0 + 5]) != 0) {
2129 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2134 } else if (strcmp(tokens[t0], "array") == 0) {
2135 if (n_tokens < t0 + 5) {
2136 snprintf(out, out_size, MSG_ARG_MISMATCH,
2137 "pipeline table array");
2141 p.match_type = TABLE_ARRAY;
2143 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2144 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2148 if (softnic_parser_read_uint32(&p.match.array.key_offset,
2149 tokens[t0 + 2]) != 0) {
2150 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2154 if (strcmp(tokens[t0 + 3], "size") != 0) {
2155 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2159 if (softnic_parser_read_uint32(&p.match.array.n_keys,
2160 tokens[t0 + 4]) != 0) {
2161 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2166 } else if (strcmp(tokens[t0], "hash") == 0) {
2167 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2169 if (n_tokens < t0 + 12) {
2170 snprintf(out, out_size, MSG_ARG_MISMATCH,
2171 "pipeline table hash");
2175 p.match_type = TABLE_HASH;
2177 if (strcmp(tokens[t0 + 1], "ext") == 0) {
2178 p.match.hash.extendable_bucket = 1;
2179 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
2180 p.match.hash.extendable_bucket = 0;
2182 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2187 if (strcmp(tokens[t0 + 2], "key") != 0) {
2188 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2192 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
2193 tokens[t0 + 3]) != 0) ||
2194 p.match.hash.key_size == 0 ||
2195 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
2196 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2200 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2201 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2205 if ((softnic_parse_hex_string(tokens[t0 + 5],
2206 key_mask, &key_mask_size) != 0) ||
2207 key_mask_size != p.match.hash.key_size) {
2208 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2211 p.match.hash.key_mask = key_mask;
2213 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2214 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2218 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
2219 tokens[t0 + 7]) != 0) {
2220 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2224 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2225 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2229 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
2230 tokens[t0 + 9]) != 0) {
2231 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2235 if (strcmp(tokens[t0 + 10], "size") != 0) {
2236 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2240 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
2241 tokens[t0 + 11]) != 0) {
2242 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2247 } else if (strcmp(tokens[t0], "lpm") == 0) {
2248 if (n_tokens < t0 + 6) {
2249 snprintf(out, out_size, MSG_ARG_MISMATCH,
2250 "pipeline table lpm");
2254 p.match_type = TABLE_LPM;
2256 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2257 p.match.lpm.key_size = 4;
2258 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2259 p.match.lpm.key_size = 16;
2261 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2266 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2267 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2271 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
2272 tokens[t0 + 3]) != 0) {
2273 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2277 if (strcmp(tokens[t0 + 4], "size") != 0) {
2278 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2282 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
2283 tokens[t0 + 5]) != 0) {
2284 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2289 } else if (strcmp(tokens[t0], "stub") == 0) {
2290 p.match_type = TABLE_STUB;
2294 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2298 p.action_profile_name = NULL;
2299 if (n_tokens > t0 &&
2300 (strcmp(tokens[t0], "action") == 0)) {
2301 if (n_tokens < t0 + 2) {
2302 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2306 p.action_profile_name = tokens[t0 + 1];
2311 if (n_tokens > t0) {
2312 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2316 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
2318 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2324 * pipeline <pipeline_name> port in <port_id> table <table_id>
2327 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
2333 char *pipeline_name;
2334 uint32_t port_id, table_id;
2337 if (n_tokens != 7) {
2338 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2342 pipeline_name = tokens[1];
2344 if (strcmp(tokens[2], "port") != 0) {
2345 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2349 if (strcmp(tokens[3], "in") != 0) {
2350 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2354 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2355 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2359 if (strcmp(tokens[5], "table") != 0) {
2360 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2364 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
2365 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2369 status = softnic_pipeline_port_in_connect_to_table(softnic,
2374 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2380 * pipeline <pipeline_name> port in <port_id> stats read [clear]
2383 #define MSG_PIPELINE_PORT_IN_STATS \
2384 "Pkts in: %" PRIu64 "\n" \
2385 "Pkts dropped by AH: %" PRIu64 "\n" \
2386 "Pkts dropped by other: %" PRIu64 "\n"
2389 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
2395 struct rte_pipeline_port_in_stats stats;
2396 char *pipeline_name;
2400 if (n_tokens != 7 &&
2402 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2406 pipeline_name = tokens[1];
2408 if (strcmp(tokens[2], "port") != 0) {
2409 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2413 if (strcmp(tokens[3], "in") != 0) {
2414 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2418 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2419 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2423 if (strcmp(tokens[5], "stats") != 0) {
2424 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2428 if (strcmp(tokens[6], "read") != 0) {
2429 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2434 if (n_tokens == 8) {
2435 if (strcmp(tokens[7], "clear") != 0) {
2436 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2443 status = softnic_pipeline_port_in_stats_read(softnic,
2449 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2453 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2454 stats.stats.n_pkts_in,
2455 stats.n_pkts_dropped_by_ah,
2456 stats.stats.n_pkts_drop);
2460 * pipeline <pipeline_name> port in <port_id> enable
2463 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
2469 char *pipeline_name;
2473 if (n_tokens != 6) {
2474 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2478 pipeline_name = tokens[1];
2480 if (strcmp(tokens[2], "port") != 0) {
2481 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2485 if (strcmp(tokens[3], "in") != 0) {
2486 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2490 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2491 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2495 if (strcmp(tokens[5], "enable") != 0) {
2496 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2500 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
2502 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2508 * pipeline <pipeline_name> port in <port_id> disable
2511 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
2517 char *pipeline_name;
2521 if (n_tokens != 6) {
2522 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2526 pipeline_name = tokens[1];
2528 if (strcmp(tokens[2], "port") != 0) {
2529 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2533 if (strcmp(tokens[3], "in") != 0) {
2534 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2538 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2539 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2543 if (strcmp(tokens[5], "disable") != 0) {
2544 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2548 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2550 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2556 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2558 #define MSG_PIPELINE_PORT_OUT_STATS \
2559 "Pkts in: %" PRIu64 "\n" \
2560 "Pkts dropped by AH: %" PRIu64 "\n" \
2561 "Pkts dropped by other: %" PRIu64 "\n"
2564 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2570 struct rte_pipeline_port_out_stats stats;
2571 char *pipeline_name;
2575 if (n_tokens != 7 &&
2577 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2581 pipeline_name = tokens[1];
2583 if (strcmp(tokens[2], "port") != 0) {
2584 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2588 if (strcmp(tokens[3], "out") != 0) {
2589 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2593 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2594 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2598 if (strcmp(tokens[5], "stats") != 0) {
2599 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2603 if (strcmp(tokens[6], "read") != 0) {
2604 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2609 if (n_tokens == 8) {
2610 if (strcmp(tokens[7], "clear") != 0) {
2611 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2618 status = softnic_pipeline_port_out_stats_read(softnic,
2624 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2628 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2629 stats.stats.n_pkts_in,
2630 stats.n_pkts_dropped_by_ah,
2631 stats.stats.n_pkts_drop);
2635 * pipeline <pipeline_name> table <table_id> stats read [clear]
2637 #define MSG_PIPELINE_TABLE_STATS \
2638 "Pkts in: %" PRIu64 "\n" \
2639 "Pkts in with lookup miss: %" PRIu64 "\n" \
2640 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2641 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2642 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2643 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2646 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2652 struct rte_pipeline_table_stats stats;
2653 char *pipeline_name;
2657 if (n_tokens != 6 &&
2659 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2663 pipeline_name = tokens[1];
2665 if (strcmp(tokens[2], "table") != 0) {
2666 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2670 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2671 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2675 if (strcmp(tokens[4], "stats") != 0) {
2676 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2680 if (strcmp(tokens[5], "read") != 0) {
2681 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2686 if (n_tokens == 7) {
2687 if (strcmp(tokens[6], "clear") != 0) {
2688 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2695 status = softnic_pipeline_table_stats_read(softnic,
2701 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2705 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2706 stats.stats.n_pkts_in,
2707 stats.stats.n_pkts_lookup_miss,
2708 stats.n_pkts_dropped_by_lkp_hit_ah,
2709 stats.n_pkts_dropped_lkp_hit,
2710 stats.n_pkts_dropped_by_lkp_miss_ah,
2711 stats.n_pkts_dropped_lkp_miss);
2719 * priority <priority>
2720 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2721 * <sp0> <sp1> <dp0> <dp1> <proto>
2725 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2726 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2727 * | ipv4_addr <addr>
2728 * | ipv6_addr <addr>
2729 * | qinq <svlan> <cvlan>
2731 * ipv4 | ipv6 <addr> <depth>
2733 struct pkt_key_qinq {
2734 uint16_t ethertype_svlan;
2736 uint16_t ethertype_cvlan;
2738 } __attribute__((__packed__));
2740 struct pkt_key_ipv4_5tuple {
2741 uint8_t time_to_live;
2743 uint16_t hdr_checksum;
2748 } __attribute__((__packed__));
2750 struct pkt_key_ipv6_5tuple {
2751 uint16_t payload_length;
2758 } __attribute__((__packed__));
2760 struct pkt_key_ipv4_addr {
2762 } __attribute__((__packed__));
2764 struct pkt_key_ipv6_addr {
2766 } __attribute__((__packed__));
2769 parse_match(char **tokens,
2773 struct softnic_table_rule_match *m)
2775 memset(m, 0, sizeof(*m));
2780 if (strcmp(tokens[0], "match") != 0) {
2781 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2785 if (strcmp(tokens[1], "acl") == 0) {
2786 if (n_tokens < 14) {
2787 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2791 m->match_type = TABLE_ACL;
2793 if (strcmp(tokens[2], "priority") != 0) {
2794 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2798 if (softnic_parser_read_uint32(&m->match.acl.priority,
2800 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2804 if (strcmp(tokens[4], "ipv4") == 0) {
2805 struct in_addr saddr, daddr;
2807 m->match.acl.ip_version = 1;
2809 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2810 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2813 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2815 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2816 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2819 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2820 } else if (strcmp(tokens[4], "ipv6") == 0) {
2821 struct in6_addr saddr, daddr;
2823 m->match.acl.ip_version = 0;
2825 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2826 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2829 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2831 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2832 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2835 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2837 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2842 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2844 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2848 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2850 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2854 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2855 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2859 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2860 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2864 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2865 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2869 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2870 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2874 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2875 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2879 m->match.acl.proto_mask = 0xff;
2884 if (strcmp(tokens[1], "array") == 0) {
2886 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2890 m->match_type = TABLE_ARRAY;
2892 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2893 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2900 if (strcmp(tokens[1], "hash") == 0) {
2902 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2906 m->match_type = TABLE_HASH;
2908 if (strcmp(tokens[2], "raw") == 0) {
2909 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2912 snprintf(out, out_size, MSG_ARG_MISMATCH,
2917 if (softnic_parse_hex_string(tokens[3],
2918 m->match.hash.key, &key_size) != 0) {
2919 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2926 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2927 struct pkt_key_ipv4_5tuple *ipv4 =
2928 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2929 struct in_addr saddr, daddr;
2934 snprintf(out, out_size, MSG_ARG_MISMATCH,
2939 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2940 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2944 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2945 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2949 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2950 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2954 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2955 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2959 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2960 snprintf(out, out_size, MSG_ARG_INVALID,
2965 ipv4->sa = saddr.s_addr;
2966 ipv4->da = daddr.s_addr;
2967 ipv4->sp = rte_cpu_to_be_16(sp);
2968 ipv4->dp = rte_cpu_to_be_16(dp);
2969 ipv4->proto = proto;
2972 } /* hash ipv4_5tuple */
2974 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2975 struct pkt_key_ipv6_5tuple *ipv6 =
2976 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2977 struct in6_addr saddr, daddr;
2982 snprintf(out, out_size, MSG_ARG_MISMATCH,
2987 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2988 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2992 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2993 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2997 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2998 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
3002 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
3003 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3007 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3008 snprintf(out, out_size, MSG_ARG_INVALID,
3013 memcpy(ipv6->sa, saddr.s6_addr, 16);
3014 memcpy(ipv6->da, daddr.s6_addr, 16);
3015 ipv6->sp = rte_cpu_to_be_16(sp);
3016 ipv6->dp = rte_cpu_to_be_16(dp);
3017 ipv6->proto = proto;
3020 } /* hash ipv6_5tuple */
3022 if (strcmp(tokens[2], "ipv4_addr") == 0) {
3023 struct pkt_key_ipv4_addr *ipv4_addr =
3024 (struct pkt_key_ipv4_addr *)m->match.hash.key;
3025 struct in_addr addr;
3028 snprintf(out, out_size, MSG_ARG_MISMATCH,
3033 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3034 snprintf(out, out_size, MSG_ARG_INVALID,
3039 ipv4_addr->addr = addr.s_addr;
3042 } /* hash ipv4_addr */
3044 if (strcmp(tokens[2], "ipv6_addr") == 0) {
3045 struct pkt_key_ipv6_addr *ipv6_addr =
3046 (struct pkt_key_ipv6_addr *)m->match.hash.key;
3047 struct in6_addr addr;
3050 snprintf(out, out_size, MSG_ARG_MISMATCH,
3055 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3056 snprintf(out, out_size, MSG_ARG_INVALID,
3061 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
3064 } /* hash ipv6_5tuple */
3066 if (strcmp(tokens[2], "qinq") == 0) {
3067 struct pkt_key_qinq *qinq =
3068 (struct pkt_key_qinq *)m->match.hash.key;
3069 uint16_t svlan, cvlan;
3072 snprintf(out, out_size, MSG_ARG_MISMATCH,
3077 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
3079 snprintf(out, out_size, MSG_ARG_INVALID,
3084 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3086 snprintf(out, out_size, MSG_ARG_INVALID,
3091 qinq->svlan = rte_cpu_to_be_16(svlan);
3092 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3097 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3101 if (strcmp(tokens[1], "lpm") == 0) {
3103 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3107 m->match_type = TABLE_LPM;
3109 if (strcmp(tokens[2], "ipv4") == 0) {
3110 struct in_addr addr;
3112 m->match.lpm.ip_version = 1;
3114 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3115 snprintf(out, out_size, MSG_ARG_INVALID,
3120 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3121 } else if (strcmp(tokens[2], "ipv6") == 0) {
3122 struct in6_addr addr;
3124 m->match.lpm.ip_version = 0;
3126 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3127 snprintf(out, out_size, MSG_ARG_INVALID,
3132 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3134 snprintf(out, out_size, MSG_ARG_MISMATCH,
3139 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3140 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3147 snprintf(out, out_size, MSG_ARG_MISMATCH,
3148 "acl or array or hash or lpm");
3160 * | table <table_id>
3161 * [balance <out0> ... <out7>]
3163 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3164 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3165 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3166 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3167 * [tm subport <subport_id> pipe <pipe_id>]
3170 * | vlan <da> <sa> <pcp> <dei> <vid>
3171 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3172 * | mpls unicast | multicast
3174 * label0 <label> <tc> <ttl>
3175 * [label1 <label> <tc> <ttl>
3176 * [label2 <label> <tc> <ttl>
3177 * [label3 <label> <tc> <ttl>]]]
3178 * | pppoe <da> <sa> <session_id>]
3179 * [nat ipv4 | ipv6 <addr> <port>]
3185 * <pa> ::= g | y | r | drop
3188 parse_table_action_fwd(char **tokens,
3190 struct softnic_table_rule_action *a)
3192 if (n_tokens == 0 ||
3193 (strcmp(tokens[0], "fwd") != 0))
3199 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3200 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3201 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3205 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3209 softnic_parser_read_uint32(&id, tokens[1]))
3212 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3214 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3218 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3219 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3220 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3224 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3228 softnic_parser_read_uint32(&id, tokens[1]))
3231 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3233 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3241 parse_table_action_balance(char **tokens,
3243 struct softnic_table_rule_action *a)
3247 if (n_tokens == 0 ||
3248 (strcmp(tokens[0], "balance") != 0))
3254 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3257 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3258 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3261 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3262 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3266 parse_policer_action(char *token, enum rte_table_action_policer *a)
3268 if (strcmp(token, "g") == 0) {
3269 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3273 if (strcmp(token, "y") == 0) {
3274 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3278 if (strcmp(token, "r") == 0) {
3279 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3283 if (strcmp(token, "drop") == 0) {
3284 *a = RTE_TABLE_ACTION_POLICER_DROP;
3292 parse_table_action_meter_tc(char **tokens,
3294 struct rte_table_action_mtr_tc_params *mtr)
3297 strcmp(tokens[0], "meter") ||
3298 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3299 strcmp(tokens[2], "policer") ||
3300 strcmp(tokens[3], "g") ||
3301 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
3302 strcmp(tokens[5], "y") ||
3303 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
3304 strcmp(tokens[7], "r") ||
3305 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
3312 parse_table_action_meter(char **tokens,
3314 struct softnic_table_rule_action *a)
3316 if (n_tokens == 0 ||
3317 strcmp(tokens[0], "meter"))
3323 if (n_tokens < 10 ||
3324 strcmp(tokens[0], "tc0") ||
3325 (parse_table_action_meter_tc(tokens + 1,
3327 &a->mtr.mtr[0]) == 0))
3333 if (n_tokens == 0 ||
3334 strcmp(tokens[0], "tc1")) {
3336 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3340 if (n_tokens < 30 ||
3341 (parse_table_action_meter_tc(tokens + 1,
3342 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3343 strcmp(tokens[10], "tc2") ||
3344 (parse_table_action_meter_tc(tokens + 11,
3345 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3346 strcmp(tokens[20], "tc3") ||
3347 (parse_table_action_meter_tc(tokens + 21,
3348 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3351 a->mtr.tc_mask = 0xF;
3352 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3353 return 1 + 10 + 3 * 10;
3357 parse_table_action_tm(char **tokens,
3359 struct softnic_table_rule_action *a)
3361 uint32_t subport_id, pipe_id;
3364 strcmp(tokens[0], "tm") ||
3365 strcmp(tokens[1], "subport") ||
3366 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
3367 strcmp(tokens[3], "pipe") ||
3368 softnic_parser_read_uint32(&pipe_id, tokens[4]))
3371 a->tm.subport_id = subport_id;
3372 a->tm.pipe_id = pipe_id;
3373 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3378 parse_table_action_encap(char **tokens,
3380 struct softnic_table_rule_action *a)
3382 if (n_tokens == 0 ||
3383 strcmp(tokens[0], "encap"))
3390 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3392 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3393 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3396 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3397 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3402 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3403 uint32_t pcp, dei, vid;
3406 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3407 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3408 softnic_parser_read_uint32(&pcp, tokens[3]) ||
3410 softnic_parser_read_uint32(&dei, tokens[4]) ||
3412 softnic_parser_read_uint32(&vid, tokens[5]) ||
3416 a->encap.vlan.vlan.pcp = pcp & 0x7;
3417 a->encap.vlan.vlan.dei = dei & 0x1;
3418 a->encap.vlan.vlan.vid = vid & 0xFFF;
3419 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3420 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3425 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3426 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3427 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3430 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3431 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3432 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
3434 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
3436 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
3437 svlan_vid > 0xFFF ||
3438 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3440 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
3442 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
3446 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3447 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3448 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3449 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3450 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3451 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3452 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3453 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3458 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3459 uint32_t label, tc, ttl;
3464 if (strcmp(tokens[1], "unicast") == 0)
3465 a->encap.mpls.unicast = 1;
3466 else if (strcmp(tokens[1], "multicast") == 0)
3467 a->encap.mpls.unicast = 0;
3471 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3472 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3473 strcmp(tokens[4], "label0") ||
3474 softnic_parser_read_uint32(&label, tokens[5]) ||
3476 softnic_parser_read_uint32(&tc, tokens[6]) ||
3478 softnic_parser_read_uint32(&ttl, tokens[7]) ||
3482 a->encap.mpls.mpls[0].label = label;
3483 a->encap.mpls.mpls[0].tc = tc;
3484 a->encap.mpls.mpls[0].ttl = ttl;
3489 if (n_tokens == 0 ||
3490 strcmp(tokens[0], "label1")) {
3491 a->encap.mpls.mpls_count = 1;
3492 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3493 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3498 softnic_parser_read_uint32(&label, tokens[1]) ||
3500 softnic_parser_read_uint32(&tc, tokens[2]) ||
3502 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3506 a->encap.mpls.mpls[1].label = label;
3507 a->encap.mpls.mpls[1].tc = tc;
3508 a->encap.mpls.mpls[1].ttl = ttl;
3513 if (n_tokens == 0 ||
3514 strcmp(tokens[0], "label2")) {
3515 a->encap.mpls.mpls_count = 2;
3516 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3517 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3522 softnic_parser_read_uint32(&label, tokens[1]) ||
3524 softnic_parser_read_uint32(&tc, tokens[2]) ||
3526 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3530 a->encap.mpls.mpls[2].label = label;
3531 a->encap.mpls.mpls[2].tc = tc;
3532 a->encap.mpls.mpls[2].ttl = ttl;
3537 if (n_tokens == 0 ||
3538 strcmp(tokens[0], "label3")) {
3539 a->encap.mpls.mpls_count = 3;
3540 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3541 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3542 return 1 + 8 + 4 + 4;
3546 softnic_parser_read_uint32(&label, tokens[1]) ||
3548 softnic_parser_read_uint32(&tc, tokens[2]) ||
3550 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3554 a->encap.mpls.mpls[3].label = label;
3555 a->encap.mpls.mpls[3].tc = tc;
3556 a->encap.mpls.mpls[3].ttl = ttl;
3558 a->encap.mpls.mpls_count = 4;
3559 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3560 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3561 return 1 + 8 + 4 + 4 + 4;
3565 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3567 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3568 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3569 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3573 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3574 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3582 parse_table_action_nat(char **tokens,
3584 struct softnic_table_rule_action *a)
3587 strcmp(tokens[0], "nat"))
3590 if (strcmp(tokens[1], "ipv4") == 0) {
3591 struct in_addr addr;
3594 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3595 softnic_parser_read_uint16(&port, tokens[3]))
3598 a->nat.ip_version = 1;
3599 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3601 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3605 if (strcmp(tokens[1], "ipv6") == 0) {
3606 struct in6_addr addr;
3609 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3610 softnic_parser_read_uint16(&port, tokens[3]))
3613 a->nat.ip_version = 0;
3614 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3616 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3624 parse_table_action_ttl(char **tokens,
3626 struct softnic_table_rule_action *a)
3629 strcmp(tokens[0], "ttl"))
3632 if (strcmp(tokens[1], "dec") == 0)
3633 a->ttl.decrement = 1;
3634 else if (strcmp(tokens[1], "keep") == 0)
3635 a->ttl.decrement = 0;
3639 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3644 parse_table_action_stats(char **tokens,
3646 struct softnic_table_rule_action *a)
3649 strcmp(tokens[0], "stats"))
3652 a->stats.n_packets = 0;
3653 a->stats.n_bytes = 0;
3654 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3659 parse_table_action_time(char **tokens,
3661 struct softnic_table_rule_action *a)
3664 strcmp(tokens[0], "time"))
3667 a->time.time = rte_rdtsc();
3668 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3673 parse_table_action(char **tokens,
3677 struct softnic_table_rule_action *a)
3679 uint32_t n_tokens0 = n_tokens;
3681 memset(a, 0, sizeof(*a));
3684 strcmp(tokens[0], "action"))
3690 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3693 n = parse_table_action_fwd(tokens, n_tokens, a);
3695 snprintf(out, out_size, MSG_ARG_INVALID,
3704 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3707 n = parse_table_action_balance(tokens, n_tokens, a);
3709 snprintf(out, out_size, MSG_ARG_INVALID,
3718 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3721 n = parse_table_action_meter(tokens, n_tokens, a);
3723 snprintf(out, out_size, MSG_ARG_INVALID,
3732 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3735 n = parse_table_action_tm(tokens, n_tokens, a);
3737 snprintf(out, out_size, MSG_ARG_INVALID,
3746 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3749 n = parse_table_action_encap(tokens, n_tokens, a);
3751 snprintf(out, out_size, MSG_ARG_INVALID,
3760 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3763 n = parse_table_action_nat(tokens, n_tokens, a);
3765 snprintf(out, out_size, MSG_ARG_INVALID,
3774 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3777 n = parse_table_action_ttl(tokens, n_tokens, a);
3779 snprintf(out, out_size, MSG_ARG_INVALID,
3788 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3791 n = parse_table_action_stats(tokens, n_tokens, a);
3793 snprintf(out, out_size, MSG_ARG_INVALID,
3802 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3805 n = parse_table_action_time(tokens, n_tokens, a);
3807 snprintf(out, out_size, MSG_ARG_INVALID,
3816 if (n_tokens0 - n_tokens == 1) {
3817 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3821 return n_tokens0 - n_tokens;
3825 * pipeline <pipeline_name> table <table_id> rule add
3827 * action <table_action>
3830 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3836 struct softnic_table_rule_match m;
3837 struct softnic_table_rule_action a;
3838 char *pipeline_name;
3840 uint32_t table_id, t0, n_tokens_parsed;
3844 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3848 pipeline_name = tokens[1];
3850 if (strcmp(tokens[2], "table") != 0) {
3851 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3855 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3856 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3860 if (strcmp(tokens[4], "rule") != 0) {
3861 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3865 if (strcmp(tokens[5], "add") != 0) {
3866 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3873 n_tokens_parsed = parse_match(tokens + t0,
3878 if (n_tokens_parsed == 0)
3880 t0 += n_tokens_parsed;
3883 n_tokens_parsed = parse_table_action(tokens + t0,
3888 if (n_tokens_parsed == 0)
3890 t0 += n_tokens_parsed;
3892 if (t0 != n_tokens) {
3893 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3897 status = softnic_pipeline_table_rule_add(softnic,
3904 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3910 * pipeline <pipeline_name> table <table_id> rule add
3918 * | table <table_id>
3921 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3927 struct softnic_table_rule_action action;
3929 char *pipeline_name;
3933 if (n_tokens != 11 &&
3935 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3939 pipeline_name = tokens[1];
3941 if (strcmp(tokens[2], "table") != 0) {
3942 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3946 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3947 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3951 if (strcmp(tokens[4], "rule") != 0) {
3952 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3956 if (strcmp(tokens[5], "add") != 0) {
3957 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3961 if (strcmp(tokens[6], "match") != 0) {
3962 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3966 if (strcmp(tokens[7], "default") != 0) {
3967 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3971 if (strcmp(tokens[8], "action") != 0) {
3972 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3976 if (strcmp(tokens[9], "fwd") != 0) {
3977 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3981 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3983 if (strcmp(tokens[10], "drop") == 0) {
3984 if (n_tokens != 11) {
3985 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3989 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3990 } else if (strcmp(tokens[10], "port") == 0) {
3993 if (n_tokens != 12) {
3994 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3998 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3999 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
4003 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4005 } else if (strcmp(tokens[10], "meta") == 0) {
4006 if (n_tokens != 11) {
4007 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4011 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4012 } else if (strcmp(tokens[10], "table") == 0) {
4015 if (n_tokens != 12) {
4016 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4020 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4021 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4025 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4028 snprintf(out, out_size, MSG_ARG_INVALID,
4029 "drop or port or meta or table");
4033 status = softnic_pipeline_table_rule_add_default(softnic,
4039 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4045 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
4048 * - line format: match <match> action <action>
4051 cli_rule_file_process(const char *file_name,
4052 size_t line_len_max,
4053 struct softnic_table_rule_match *m,
4054 struct softnic_table_rule_action *a,
4056 uint32_t *line_number,
4061 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
4067 struct softnic_table_rule_match *match;
4068 struct softnic_table_rule_action *action;
4070 char *pipeline_name, *file_name;
4071 uint32_t table_id, n_rules, n_rules_parsed, line_number;
4074 if (n_tokens != 9) {
4075 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4079 pipeline_name = tokens[1];
4081 if (strcmp(tokens[2], "table") != 0) {
4082 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4086 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4087 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4091 if (strcmp(tokens[4], "rule") != 0) {
4092 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4096 if (strcmp(tokens[5], "add") != 0) {
4097 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4101 if (strcmp(tokens[6], "bulk") != 0) {
4102 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4106 file_name = tokens[7];
4108 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
4110 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
4114 /* Memory allocation. */
4115 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
4116 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
4117 data = calloc(n_rules, sizeof(void *));
4118 if (match == NULL ||
4121 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
4128 /* Load rule file */
4129 n_rules_parsed = n_rules;
4130 status = cli_rule_file_process(file_name,
4139 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4145 if (n_rules_parsed != n_rules) {
4146 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
4154 status = softnic_pipeline_table_rule_add_bulk(softnic,
4162 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4176 * pipeline <pipeline_name> table <table_id> rule delete
4180 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
4186 struct softnic_table_rule_match m;
4187 char *pipeline_name;
4188 uint32_t table_id, n_tokens_parsed, t0;
4192 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4196 pipeline_name = tokens[1];
4198 if (strcmp(tokens[2], "table") != 0) {
4199 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4203 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4204 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4208 if (strcmp(tokens[4], "rule") != 0) {
4209 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4213 if (strcmp(tokens[5], "delete") != 0) {
4214 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4221 n_tokens_parsed = parse_match(tokens + t0,
4226 if (n_tokens_parsed == 0)
4228 t0 += n_tokens_parsed;
4230 if (n_tokens != t0) {
4231 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4235 status = softnic_pipeline_table_rule_delete(softnic,
4240 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4246 * pipeline <pipeline_name> table <table_id> rule delete
4251 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
4257 char *pipeline_name;
4261 if (n_tokens != 8) {
4262 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4266 pipeline_name = tokens[1];
4268 if (strcmp(tokens[2], "table") != 0) {
4269 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4273 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4274 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4278 if (strcmp(tokens[4], "rule") != 0) {
4279 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4283 if (strcmp(tokens[5], "delete") != 0) {
4284 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4288 if (strcmp(tokens[6], "match") != 0) {
4289 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4293 if (strcmp(tokens[7], "default") != 0) {
4294 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4298 status = softnic_pipeline_table_rule_delete_default(softnic,
4302 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4308 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
4311 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
4313 uint32_t n_tokens __rte_unused,
4317 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4321 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
4322 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
4323 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
4326 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
4332 struct rte_table_action_meter_profile p;
4333 char *pipeline_name;
4334 uint32_t table_id, meter_profile_id;
4338 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4342 pipeline_name = tokens[1];
4344 if (strcmp(tokens[2], "table") != 0) {
4345 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4349 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4350 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4354 if (strcmp(tokens[4], "meter") != 0) {
4355 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4359 if (strcmp(tokens[5], "profile") != 0) {
4360 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4364 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4365 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4369 if (strcmp(tokens[7], "add") != 0) {
4370 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4374 if (strcmp(tokens[8], "srtcm") == 0) {
4375 if (n_tokens != 15) {
4376 snprintf(out, out_size, MSG_ARG_MISMATCH,
4381 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
4383 if (strcmp(tokens[9], "cir") != 0) {
4384 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4388 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
4389 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4393 if (strcmp(tokens[11], "cbs") != 0) {
4394 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4398 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
4399 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4403 if (strcmp(tokens[13], "ebs") != 0) {
4404 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
4408 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
4409 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
4412 } else if (strcmp(tokens[8], "trtcm") == 0) {
4413 if (n_tokens != 17) {
4414 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4418 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
4420 if (strcmp(tokens[9], "cir") != 0) {
4421 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4425 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
4426 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4430 if (strcmp(tokens[11], "pir") != 0) {
4431 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
4435 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
4436 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
4439 if (strcmp(tokens[13], "cbs") != 0) {
4440 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4444 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
4445 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4449 if (strcmp(tokens[15], "pbs") != 0) {
4450 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
4454 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
4455 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
4459 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4463 status = softnic_pipeline_table_mtr_profile_add(softnic,
4469 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4475 * pipeline <pipeline_name> table <table_id>
4476 * meter profile <meter_profile_id> delete
4479 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
4485 char *pipeline_name;
4486 uint32_t table_id, meter_profile_id;
4489 if (n_tokens != 8) {
4490 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4494 pipeline_name = tokens[1];
4496 if (strcmp(tokens[2], "table") != 0) {
4497 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4501 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4502 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4506 if (strcmp(tokens[4], "meter") != 0) {
4507 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4511 if (strcmp(tokens[5], "profile") != 0) {
4512 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4516 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4517 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4521 if (strcmp(tokens[7], "delete") != 0) {
4522 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4526 status = softnic_pipeline_table_mtr_profile_delete(softnic,
4531 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4537 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
4540 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
4542 uint32_t n_tokens __rte_unused,
4546 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4550 * pipeline <pipeline_name> table <table_id> dscp <file_name>
4553 * - exactly 64 lines
4554 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
4557 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4558 const char *file_name,
4559 uint32_t *line_number)
4564 /* Check input arguments */
4565 if (dscp_table == NULL ||
4566 file_name == NULL ||
4567 line_number == NULL) {
4573 /* Open input file */
4574 f = fopen(file_name, "r");
4581 for (dscp = 0, l = 1; ; l++) {
4584 enum rte_meter_color color;
4585 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4587 if (fgets(line, sizeof(line), f) == NULL)
4590 if (is_comment(line))
4593 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
4602 if (dscp >= RTE_DIM(dscp_table->entry) ||
4603 n_tokens != RTE_DIM(tokens) ||
4604 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
4605 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
4606 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
4607 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
4608 (strlen(tokens[2]) != 1)) {
4614 switch (tokens[2][0]) {
4617 color = e_RTE_METER_GREEN;
4622 color = e_RTE_METER_YELLOW;
4627 color = e_RTE_METER_RED;
4636 dscp_table->entry[dscp].tc_id = tc_id;
4637 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4638 dscp_table->entry[dscp].color = color;
4648 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
4654 struct rte_table_action_dscp_table dscp_table;
4655 char *pipeline_name, *file_name;
4656 uint32_t table_id, line_number;
4659 if (n_tokens != 6) {
4660 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4664 pipeline_name = tokens[1];
4666 if (strcmp(tokens[2], "table") != 0) {
4667 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4671 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4672 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4676 if (strcmp(tokens[4], "dscp") != 0) {
4677 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4681 file_name = tokens[5];
4683 status = load_dscp_table(&dscp_table, file_name, &line_number);
4685 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4689 status = softnic_pipeline_table_dscp_table_update(softnic,
4695 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4701 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4704 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4706 uint32_t n_tokens __rte_unused,
4710 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4714 * thread <thread_id> pipeline <pipeline_name> enable
4717 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4723 char *pipeline_name;
4727 if (n_tokens != 5) {
4728 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4732 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4733 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4737 if (strcmp(tokens[2], "pipeline") != 0) {
4738 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4742 pipeline_name = tokens[3];
4744 if (strcmp(tokens[4], "enable") != 0) {
4745 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4749 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4751 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4757 * thread <thread_id> pipeline <pipeline_name> disable
4760 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4766 char *pipeline_name;
4770 if (n_tokens != 5) {
4771 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4775 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4776 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4780 if (strcmp(tokens[2], "pipeline") != 0) {
4781 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4785 pipeline_name = tokens[3];
4787 if (strcmp(tokens[4], "disable") != 0) {
4788 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4792 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4794 snprintf(out, out_size, MSG_CMD_FAIL,
4795 "thread pipeline disable");
4801 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4803 char *tokens[CMD_MAX_TOKENS];
4804 uint32_t n_tokens = RTE_DIM(tokens);
4805 struct pmd_internals *softnic = arg;
4811 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4813 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4820 if (strcmp(tokens[0], "mempool") == 0) {
4821 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4825 if (strcmp(tokens[0], "link") == 0) {
4826 cmd_link(softnic, tokens, n_tokens, out, out_size);
4830 if (strcmp(tokens[0], "swq") == 0) {
4831 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4835 if (strcmp(tokens[0], "tmgr") == 0) {
4836 if (n_tokens == 2) {
4837 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4841 if (n_tokens >= 3 &&
4842 (strcmp(tokens[1], "shaper") == 0) &&
4843 (strcmp(tokens[2], "profile") == 0)) {
4844 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4848 if (n_tokens >= 3 &&
4849 (strcmp(tokens[1], "shared") == 0) &&
4850 (strcmp(tokens[2], "shaper") == 0)) {
4851 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
4855 if (n_tokens >= 2 &&
4856 (strcmp(tokens[1], "node") == 0)) {
4857 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
4861 if (n_tokens >= 2 &&
4862 (strcmp(tokens[1], "hierarchy-default") == 0)) {
4863 cmd_tmgr_hierarchy_default(softnic, tokens, n_tokens, out, out_size);
4867 if (n_tokens >= 3 &&
4868 (strcmp(tokens[1], "hierarchy") == 0) &&
4869 (strcmp(tokens[2], "commit") == 0)) {
4870 cmd_tmgr_hierarchy_commit(softnic, tokens, n_tokens, out, out_size);
4875 if (strcmp(tokens[0], "tap") == 0) {
4876 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4880 if (strcmp(tokens[0], "port") == 0) {
4881 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4885 if (strcmp(tokens[0], "table") == 0) {
4886 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4890 if (strcmp(tokens[0], "pipeline") == 0) {
4891 if (n_tokens >= 3 &&
4892 (strcmp(tokens[2], "period") == 0)) {
4893 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4897 if (n_tokens >= 5 &&
4898 (strcmp(tokens[2], "port") == 0) &&
4899 (strcmp(tokens[3], "in") == 0) &&
4900 (strcmp(tokens[4], "bsz") == 0)) {
4901 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4905 if (n_tokens >= 5 &&
4906 (strcmp(tokens[2], "port") == 0) &&
4907 (strcmp(tokens[3], "out") == 0) &&
4908 (strcmp(tokens[4], "bsz") == 0)) {
4909 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4913 if (n_tokens >= 4 &&
4914 (strcmp(tokens[2], "table") == 0) &&
4915 (strcmp(tokens[3], "match") == 0)) {
4916 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4920 if (n_tokens >= 6 &&
4921 (strcmp(tokens[2], "port") == 0) &&
4922 (strcmp(tokens[3], "in") == 0) &&
4923 (strcmp(tokens[5], "table") == 0)) {
4924 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
4929 if (n_tokens >= 6 &&
4930 (strcmp(tokens[2], "port") == 0) &&
4931 (strcmp(tokens[3], "in") == 0) &&
4932 (strcmp(tokens[5], "stats") == 0)) {
4933 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
4938 if (n_tokens >= 6 &&
4939 (strcmp(tokens[2], "port") == 0) &&
4940 (strcmp(tokens[3], "in") == 0) &&
4941 (strcmp(tokens[5], "enable") == 0)) {
4942 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
4947 if (n_tokens >= 6 &&
4948 (strcmp(tokens[2], "port") == 0) &&
4949 (strcmp(tokens[3], "in") == 0) &&
4950 (strcmp(tokens[5], "disable") == 0)) {
4951 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
4956 if (n_tokens >= 6 &&
4957 (strcmp(tokens[2], "port") == 0) &&
4958 (strcmp(tokens[3], "out") == 0) &&
4959 (strcmp(tokens[5], "stats") == 0)) {
4960 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
4965 if (n_tokens >= 5 &&
4966 (strcmp(tokens[2], "table") == 0) &&
4967 (strcmp(tokens[4], "stats") == 0)) {
4968 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
4973 if (n_tokens >= 7 &&
4974 (strcmp(tokens[2], "table") == 0) &&
4975 (strcmp(tokens[4], "rule") == 0) &&
4976 (strcmp(tokens[5], "add") == 0) &&
4977 (strcmp(tokens[6], "match") == 0)) {
4978 if (n_tokens >= 8 &&
4979 (strcmp(tokens[7], "default") == 0)) {
4980 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
4981 n_tokens, out, out_size);
4985 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
4990 if (n_tokens >= 7 &&
4991 (strcmp(tokens[2], "table") == 0) &&
4992 (strcmp(tokens[4], "rule") == 0) &&
4993 (strcmp(tokens[5], "add") == 0) &&
4994 (strcmp(tokens[6], "bulk") == 0)) {
4995 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
4996 n_tokens, out, out_size);
5000 if (n_tokens >= 7 &&
5001 (strcmp(tokens[2], "table") == 0) &&
5002 (strcmp(tokens[4], "rule") == 0) &&
5003 (strcmp(tokens[5], "delete") == 0) &&
5004 (strcmp(tokens[6], "match") == 0)) {
5005 if (n_tokens >= 8 &&
5006 (strcmp(tokens[7], "default") == 0)) {
5007 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
5008 n_tokens, out, out_size);
5012 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
5017 if (n_tokens >= 7 &&
5018 (strcmp(tokens[2], "table") == 0) &&
5019 (strcmp(tokens[4], "rule") == 0) &&
5020 (strcmp(tokens[5], "read") == 0) &&
5021 (strcmp(tokens[6], "stats") == 0)) {
5022 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
5027 if (n_tokens >= 8 &&
5028 (strcmp(tokens[2], "table") == 0) &&
5029 (strcmp(tokens[4], "meter") == 0) &&
5030 (strcmp(tokens[5], "profile") == 0) &&
5031 (strcmp(tokens[7], "add") == 0)) {
5032 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
5037 if (n_tokens >= 8 &&
5038 (strcmp(tokens[2], "table") == 0) &&
5039 (strcmp(tokens[4], "meter") == 0) &&
5040 (strcmp(tokens[5], "profile") == 0) &&
5041 (strcmp(tokens[7], "delete") == 0)) {
5042 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
5043 n_tokens, out, out_size);
5047 if (n_tokens >= 7 &&
5048 (strcmp(tokens[2], "table") == 0) &&
5049 (strcmp(tokens[4], "rule") == 0) &&
5050 (strcmp(tokens[5], "read") == 0) &&
5051 (strcmp(tokens[6], "meter") == 0)) {
5052 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
5057 if (n_tokens >= 5 &&
5058 (strcmp(tokens[2], "table") == 0) &&
5059 (strcmp(tokens[4], "dscp") == 0)) {
5060 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
5065 if (n_tokens >= 7 &&
5066 (strcmp(tokens[2], "table") == 0) &&
5067 (strcmp(tokens[4], "rule") == 0) &&
5068 (strcmp(tokens[5], "read") == 0) &&
5069 (strcmp(tokens[6], "ttl") == 0)) {
5070 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
5076 if (strcmp(tokens[0], "thread") == 0) {
5077 if (n_tokens >= 5 &&
5078 (strcmp(tokens[4], "enable") == 0)) {
5079 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
5084 if (n_tokens >= 5 &&
5085 (strcmp(tokens[4], "disable") == 0)) {
5086 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
5092 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5096 softnic_cli_script_process(struct pmd_internals *softnic,
5097 const char *file_name,
5098 size_t msg_in_len_max,
5099 size_t msg_out_len_max)
5101 char *msg_in = NULL, *msg_out = NULL;
5104 /* Check input arguments */
5105 if (file_name == NULL ||
5106 (strlen(file_name) == 0) ||
5107 msg_in_len_max == 0 ||
5108 msg_out_len_max == 0)
5111 msg_in = malloc(msg_in_len_max + 1);
5112 msg_out = malloc(msg_out_len_max + 1);
5113 if (msg_in == NULL ||
5120 /* Open input file */
5121 f = fopen(file_name, "r");
5130 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5133 printf("%s", msg_in);
5136 softnic_cli_process(msg_in,
5141 if (strlen(msg_out))
5142 printf("%s", msg_out);
5153 cli_rule_file_process(const char *file_name,
5154 size_t line_len_max,
5155 struct softnic_table_rule_match *m,
5156 struct softnic_table_rule_action *a,
5158 uint32_t *line_number,
5164 uint32_t rule_id, line_id;
5167 /* Check input arguments */
5168 if (file_name == NULL ||
5169 (strlen(file_name) == 0) ||
5170 line_len_max == 0) {
5175 /* Memory allocation */
5176 line = malloc(line_len_max + 1);
5183 f = fopen(file_name, "r");
5191 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
5192 char *tokens[CMD_MAX_TOKENS];
5193 uint32_t n_tokens, n_tokens_parsed, t0;
5195 /* Read next line from file. */
5196 if (fgets(line, line_len_max + 1, f) == NULL)
5200 if (is_comment(line))
5204 n_tokens = RTE_DIM(tokens);
5205 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
5217 n_tokens_parsed = parse_match(tokens + t0,
5222 if (n_tokens_parsed == 0) {
5226 t0 += n_tokens_parsed;
5229 n_tokens_parsed = parse_table_action(tokens + t0,
5234 if (n_tokens_parsed == 0) {
5238 t0 += n_tokens_parsed;
5240 /* Line completed. */
5241 if (t0 < n_tokens) {
5246 /* Increment rule count */
5257 *line_number = line_id;