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;
1700 memset(&p, 0, sizeof(p));
1703 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1707 pipeline_name = tokens[1];
1709 if (strcmp(tokens[2], "port") != 0) {
1710 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1714 if (strcmp(tokens[3], "in") != 0) {
1715 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1719 if (strcmp(tokens[4], "bsz") != 0) {
1720 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1724 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1725 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1731 if (strcmp(tokens[t0], "link") == 0) {
1732 if (n_tokens < t0 + 4) {
1733 snprintf(out, out_size, MSG_ARG_MISMATCH,
1734 "pipeline port in link");
1738 p.type = PORT_IN_RXQ;
1740 strcpy(p.dev_name, tokens[t0 + 1]);
1742 if (strcmp(tokens[t0 + 2], "rxq") != 0) {
1743 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
1747 if (softnic_parser_read_uint16(&p.rxq.queue_id,
1748 tokens[t0 + 3]) != 0) {
1749 snprintf(out, out_size, MSG_ARG_INVALID,
1754 } else if (strcmp(tokens[t0], "swq") == 0) {
1755 if (n_tokens < t0 + 2) {
1756 snprintf(out, out_size, MSG_ARG_MISMATCH,
1757 "pipeline port in swq");
1761 p.type = PORT_IN_SWQ;
1763 strcpy(p.dev_name, tokens[t0 + 1]);
1766 } else if (strcmp(tokens[t0], "tmgr") == 0) {
1767 if (n_tokens < t0 + 2) {
1768 snprintf(out, out_size, MSG_ARG_MISMATCH,
1769 "pipeline port in tmgr");
1773 p.type = PORT_IN_TMGR;
1775 strcpy(p.dev_name, tokens[t0 + 1]);
1778 } else if (strcmp(tokens[t0], "tap") == 0) {
1779 if (n_tokens < t0 + 6) {
1780 snprintf(out, out_size, MSG_ARG_MISMATCH,
1781 "pipeline port in tap");
1785 p.type = PORT_IN_TAP;
1787 strcpy(p.dev_name, tokens[t0 + 1]);
1789 if (strcmp(tokens[t0 + 2], "mempool") != 0) {
1790 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1795 p.tap.mempool_name = tokens[t0 + 3];
1797 if (strcmp(tokens[t0 + 4], "mtu") != 0) {
1798 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1803 if (softnic_parser_read_uint32(&p.tap.mtu,
1804 tokens[t0 + 5]) != 0) {
1805 snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
1810 } else if (strcmp(tokens[t0], "source") == 0) {
1811 if (n_tokens < t0 + 6) {
1812 snprintf(out, out_size, MSG_ARG_MISMATCH,
1813 "pipeline port in source");
1817 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 if (n_tokens > t0 &&
1855 (strcmp(tokens[t0], "action") == 0)) {
1856 if (n_tokens < t0 + 2) {
1857 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1861 strcpy(p.action_profile_name, tokens[t0 + 1]);
1867 if (n_tokens > t0 &&
1868 (strcmp(tokens[t0], "disabled") == 0)) {
1874 if (n_tokens != t0) {
1875 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1879 status = softnic_pipeline_port_in_create(softnic,
1884 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1890 * pipeline <pipeline_name> port out
1892 * link <link_name> txq <txq_id>
1894 * | tmgr <tmgr_name>
1896 * | sink [file <file_name> pkts <max_n_pkts>]
1899 cmd_pipeline_port_out(struct pmd_internals *softnic,
1905 struct softnic_port_out_params p;
1906 char *pipeline_name;
1909 memset(&p, 0, sizeof(p));
1912 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1916 pipeline_name = tokens[1];
1918 if (strcmp(tokens[2], "port") != 0) {
1919 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1923 if (strcmp(tokens[3], "out") != 0) {
1924 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1928 if (strcmp(tokens[4], "bsz") != 0) {
1929 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1933 if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1934 snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1938 if (strcmp(tokens[6], "link") == 0) {
1939 if (n_tokens != 10) {
1940 snprintf(out, out_size, MSG_ARG_MISMATCH,
1941 "pipeline port out link");
1945 p.type = PORT_OUT_TXQ;
1947 strcpy(p.dev_name, tokens[7]);
1949 if (strcmp(tokens[8], "txq") != 0) {
1950 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1954 if (softnic_parser_read_uint16(&p.txq.queue_id,
1956 snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1959 } else if (strcmp(tokens[6], "swq") == 0) {
1960 if (n_tokens != 8) {
1961 snprintf(out, out_size, MSG_ARG_MISMATCH,
1962 "pipeline port out swq");
1966 p.type = PORT_OUT_SWQ;
1968 strcpy(p.dev_name, tokens[7]);
1969 } else if (strcmp(tokens[6], "tmgr") == 0) {
1970 if (n_tokens != 8) {
1971 snprintf(out, out_size, MSG_ARG_MISMATCH,
1972 "pipeline port out tmgr");
1976 p.type = PORT_OUT_TMGR;
1978 strcpy(p.dev_name, tokens[7]);
1979 } else if (strcmp(tokens[6], "tap") == 0) {
1980 if (n_tokens != 8) {
1981 snprintf(out, out_size, MSG_ARG_MISMATCH,
1982 "pipeline port out tap");
1986 p.type = PORT_OUT_TAP;
1988 strcpy(p.dev_name, tokens[7]);
1989 } else if (strcmp(tokens[6], "sink") == 0) {
1990 if ((n_tokens != 7) && (n_tokens != 11)) {
1991 snprintf(out, out_size, MSG_ARG_MISMATCH,
1992 "pipeline port out sink");
1996 p.type = PORT_OUT_SINK;
1998 if (n_tokens == 7) {
1999 p.sink.file_name = NULL;
2000 p.sink.max_n_pkts = 0;
2002 if (strcmp(tokens[7], "file") != 0) {
2003 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2008 p.sink.file_name = tokens[8];
2010 if (strcmp(tokens[9], "pkts") != 0) {
2011 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
2015 if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
2017 snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
2022 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2026 status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
2028 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2034 * pipeline <pipeline_name> table
2038 * offset <ip_header_offset>
2041 * offset <key_offset>
2047 * offset <key_offset>
2048 * buckets <n_buckets>
2052 * offset <ip_header_offset>
2055 * [action <table_action_profile_name>]
2058 cmd_pipeline_table(struct pmd_internals *softnic,
2064 struct softnic_table_params p;
2065 char *pipeline_name;
2069 memset(&p, 0, sizeof(p));
2072 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2076 pipeline_name = tokens[1];
2078 if (strcmp(tokens[2], "table") != 0) {
2079 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2083 if (strcmp(tokens[3], "match") != 0) {
2084 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2089 if (strcmp(tokens[t0], "acl") == 0) {
2090 if (n_tokens < t0 + 6) {
2091 snprintf(out, out_size, MSG_ARG_MISMATCH,
2092 "pipeline table acl");
2096 p.match_type = TABLE_ACL;
2098 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2099 p.match.acl.ip_version = 1;
2100 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2101 p.match.acl.ip_version = 0;
2103 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2108 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2109 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2113 if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
2114 tokens[t0 + 3]) != 0) {
2115 snprintf(out, out_size, MSG_ARG_INVALID,
2116 "ip_header_offset");
2120 if (strcmp(tokens[t0 + 4], "size") != 0) {
2121 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2125 if (softnic_parser_read_uint32(&p.match.acl.n_rules,
2126 tokens[t0 + 5]) != 0) {
2127 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2132 } else if (strcmp(tokens[t0], "array") == 0) {
2133 if (n_tokens < t0 + 5) {
2134 snprintf(out, out_size, MSG_ARG_MISMATCH,
2135 "pipeline table array");
2139 p.match_type = TABLE_ARRAY;
2141 if (strcmp(tokens[t0 + 1], "offset") != 0) {
2142 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2146 if (softnic_parser_read_uint32(&p.match.array.key_offset,
2147 tokens[t0 + 2]) != 0) {
2148 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2152 if (strcmp(tokens[t0 + 3], "size") != 0) {
2153 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2157 if (softnic_parser_read_uint32(&p.match.array.n_keys,
2158 tokens[t0 + 4]) != 0) {
2159 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2164 } else if (strcmp(tokens[t0], "hash") == 0) {
2165 uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
2167 if (n_tokens < t0 + 12) {
2168 snprintf(out, out_size, MSG_ARG_MISMATCH,
2169 "pipeline table hash");
2173 p.match_type = TABLE_HASH;
2175 if (strcmp(tokens[t0 + 1], "ext") == 0) {
2176 p.match.hash.extendable_bucket = 1;
2177 } else if (strcmp(tokens[t0 + 1], "lru") == 0) {
2178 p.match.hash.extendable_bucket = 0;
2180 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2185 if (strcmp(tokens[t0 + 2], "key") != 0) {
2186 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
2190 if ((softnic_parser_read_uint32(&p.match.hash.key_size,
2191 tokens[t0 + 3]) != 0) ||
2192 p.match.hash.key_size == 0 ||
2193 p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
2194 snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
2198 if (strcmp(tokens[t0 + 4], "mask") != 0) {
2199 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
2203 if ((softnic_parse_hex_string(tokens[t0 + 5],
2204 p.match.hash.key_mask, &key_mask_size) != 0) ||
2205 key_mask_size != p.match.hash.key_size) {
2206 snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
2210 if (strcmp(tokens[t0 + 6], "offset") != 0) {
2211 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2215 if (softnic_parser_read_uint32(&p.match.hash.key_offset,
2216 tokens[t0 + 7]) != 0) {
2217 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2221 if (strcmp(tokens[t0 + 8], "buckets") != 0) {
2222 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
2226 if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
2227 tokens[t0 + 9]) != 0) {
2228 snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
2232 if (strcmp(tokens[t0 + 10], "size") != 0) {
2233 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2237 if (softnic_parser_read_uint32(&p.match.hash.n_keys,
2238 tokens[t0 + 11]) != 0) {
2239 snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
2244 } else if (strcmp(tokens[t0], "lpm") == 0) {
2245 if (n_tokens < t0 + 6) {
2246 snprintf(out, out_size, MSG_ARG_MISMATCH,
2247 "pipeline table lpm");
2251 p.match_type = TABLE_LPM;
2253 if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
2254 p.match.lpm.key_size = 4;
2255 } else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
2256 p.match.lpm.key_size = 16;
2258 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2263 if (strcmp(tokens[t0 + 2], "offset") != 0) {
2264 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
2268 if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
2269 tokens[t0 + 3]) != 0) {
2270 snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
2274 if (strcmp(tokens[t0 + 4], "size") != 0) {
2275 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
2279 if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
2280 tokens[t0 + 5]) != 0) {
2281 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
2286 } else if (strcmp(tokens[t0], "stub") == 0) {
2287 p.match_type = TABLE_STUB;
2291 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
2295 if (n_tokens > t0 &&
2296 (strcmp(tokens[t0], "action") == 0)) {
2297 if (n_tokens < t0 + 2) {
2298 snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
2302 strcpy(p.action_profile_name, tokens[t0 + 1]);
2307 if (n_tokens > t0) {
2308 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2312 status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
2314 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2320 * pipeline <pipeline_name> port in <port_id> table <table_id>
2323 cmd_pipeline_port_in_table(struct pmd_internals *softnic,
2329 char *pipeline_name;
2330 uint32_t port_id, table_id;
2333 if (n_tokens != 7) {
2334 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2338 pipeline_name = tokens[1];
2340 if (strcmp(tokens[2], "port") != 0) {
2341 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2345 if (strcmp(tokens[3], "in") != 0) {
2346 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2350 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2351 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2355 if (strcmp(tokens[5], "table") != 0) {
2356 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
2360 if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
2361 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2365 status = softnic_pipeline_port_in_connect_to_table(softnic,
2370 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2376 * pipeline <pipeline_name> port in <port_id> stats read [clear]
2379 #define MSG_PIPELINE_PORT_IN_STATS \
2380 "Pkts in: %" PRIu64 "\n" \
2381 "Pkts dropped by AH: %" PRIu64 "\n" \
2382 "Pkts dropped by other: %" PRIu64 "\n"
2385 cmd_pipeline_port_in_stats(struct pmd_internals *softnic,
2391 struct rte_pipeline_port_in_stats stats;
2392 char *pipeline_name;
2396 if (n_tokens != 7 &&
2398 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2402 pipeline_name = tokens[1];
2404 if (strcmp(tokens[2], "port") != 0) {
2405 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2409 if (strcmp(tokens[3], "in") != 0) {
2410 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2414 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2415 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2419 if (strcmp(tokens[5], "stats") != 0) {
2420 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2424 if (strcmp(tokens[6], "read") != 0) {
2425 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2430 if (n_tokens == 8) {
2431 if (strcmp(tokens[7], "clear") != 0) {
2432 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2439 status = softnic_pipeline_port_in_stats_read(softnic,
2445 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2449 snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
2450 stats.stats.n_pkts_in,
2451 stats.n_pkts_dropped_by_ah,
2452 stats.stats.n_pkts_drop);
2456 * pipeline <pipeline_name> port in <port_id> enable
2459 cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
2465 char *pipeline_name;
2469 if (n_tokens != 6) {
2470 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2474 pipeline_name = tokens[1];
2476 if (strcmp(tokens[2], "port") != 0) {
2477 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2481 if (strcmp(tokens[3], "in") != 0) {
2482 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2486 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2487 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2491 if (strcmp(tokens[5], "enable") != 0) {
2492 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
2496 status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
2498 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2504 * pipeline <pipeline_name> port in <port_id> disable
2507 cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
2513 char *pipeline_name;
2517 if (n_tokens != 6) {
2518 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2522 pipeline_name = tokens[1];
2524 if (strcmp(tokens[2], "port") != 0) {
2525 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2529 if (strcmp(tokens[3], "in") != 0) {
2530 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
2534 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2535 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2539 if (strcmp(tokens[5], "disable") != 0) {
2540 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
2544 status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
2546 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2552 * pipeline <pipeline_name> port out <port_id> stats read [clear]
2554 #define MSG_PIPELINE_PORT_OUT_STATS \
2555 "Pkts in: %" PRIu64 "\n" \
2556 "Pkts dropped by AH: %" PRIu64 "\n" \
2557 "Pkts dropped by other: %" PRIu64 "\n"
2560 cmd_pipeline_port_out_stats(struct pmd_internals *softnic,
2566 struct rte_pipeline_port_out_stats stats;
2567 char *pipeline_name;
2571 if (n_tokens != 7 &&
2573 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2577 pipeline_name = tokens[1];
2579 if (strcmp(tokens[2], "port") != 0) {
2580 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2584 if (strcmp(tokens[3], "out") != 0) {
2585 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
2589 if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
2590 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2594 if (strcmp(tokens[5], "stats") != 0) {
2595 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2599 if (strcmp(tokens[6], "read") != 0) {
2600 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2605 if (n_tokens == 8) {
2606 if (strcmp(tokens[7], "clear") != 0) {
2607 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2614 status = softnic_pipeline_port_out_stats_read(softnic,
2620 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2624 snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
2625 stats.stats.n_pkts_in,
2626 stats.n_pkts_dropped_by_ah,
2627 stats.stats.n_pkts_drop);
2631 * pipeline <pipeline_name> table <table_id> stats read [clear]
2633 #define MSG_PIPELINE_TABLE_STATS \
2634 "Pkts in: %" PRIu64 "\n" \
2635 "Pkts in with lookup miss: %" PRIu64 "\n" \
2636 "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
2637 "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
2638 "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
2639 "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
2642 cmd_pipeline_table_stats(struct pmd_internals *softnic,
2648 struct rte_pipeline_table_stats stats;
2649 char *pipeline_name;
2653 if (n_tokens != 6 &&
2655 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2659 pipeline_name = tokens[1];
2661 if (strcmp(tokens[2], "table") != 0) {
2662 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2666 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
2667 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
2671 if (strcmp(tokens[4], "stats") != 0) {
2672 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2676 if (strcmp(tokens[5], "read") != 0) {
2677 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
2682 if (n_tokens == 7) {
2683 if (strcmp(tokens[6], "clear") != 0) {
2684 snprintf(out, out_size, MSG_ARG_INVALID, "clear");
2691 status = softnic_pipeline_table_stats_read(softnic,
2697 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2701 snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
2702 stats.stats.n_pkts_in,
2703 stats.stats.n_pkts_lookup_miss,
2704 stats.n_pkts_dropped_by_lkp_hit_ah,
2705 stats.n_pkts_dropped_lkp_hit,
2706 stats.n_pkts_dropped_by_lkp_miss_ah,
2707 stats.n_pkts_dropped_lkp_miss);
2715 * priority <priority>
2716 * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
2717 * <sp0> <sp1> <dp0> <dp1> <proto>
2721 * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
2722 * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
2723 * | ipv4_addr <addr>
2724 * | ipv6_addr <addr>
2725 * | qinq <svlan> <cvlan>
2727 * ipv4 | ipv6 <addr> <depth>
2729 struct pkt_key_qinq {
2730 uint16_t ethertype_svlan;
2732 uint16_t ethertype_cvlan;
2734 } __attribute__((__packed__));
2736 struct pkt_key_ipv4_5tuple {
2737 uint8_t time_to_live;
2739 uint16_t hdr_checksum;
2744 } __attribute__((__packed__));
2746 struct pkt_key_ipv6_5tuple {
2747 uint16_t payload_length;
2754 } __attribute__((__packed__));
2756 struct pkt_key_ipv4_addr {
2758 } __attribute__((__packed__));
2760 struct pkt_key_ipv6_addr {
2762 } __attribute__((__packed__));
2765 parse_match(char **tokens,
2769 struct softnic_table_rule_match *m)
2771 memset(m, 0, sizeof(*m));
2776 if (strcmp(tokens[0], "match") != 0) {
2777 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
2781 if (strcmp(tokens[1], "acl") == 0) {
2782 if (n_tokens < 14) {
2783 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2787 m->match_type = TABLE_ACL;
2789 if (strcmp(tokens[2], "priority") != 0) {
2790 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
2794 if (softnic_parser_read_uint32(&m->match.acl.priority,
2796 snprintf(out, out_size, MSG_ARG_INVALID, "priority");
2800 if (strcmp(tokens[4], "ipv4") == 0) {
2801 struct in_addr saddr, daddr;
2803 m->match.acl.ip_version = 1;
2805 if (softnic_parse_ipv4_addr(tokens[5], &saddr) != 0) {
2806 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2809 m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
2811 if (softnic_parse_ipv4_addr(tokens[7], &daddr) != 0) {
2812 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2815 m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
2816 } else if (strcmp(tokens[4], "ipv6") == 0) {
2817 struct in6_addr saddr, daddr;
2819 m->match.acl.ip_version = 0;
2821 if (softnic_parse_ipv6_addr(tokens[5], &saddr) != 0) {
2822 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2825 memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
2827 if (softnic_parse_ipv6_addr(tokens[7], &daddr) != 0) {
2828 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2831 memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
2833 snprintf(out, out_size, MSG_ARG_NOT_FOUND,
2838 if (softnic_parser_read_uint32(&m->match.acl.sa_depth,
2840 snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
2844 if (softnic_parser_read_uint32(&m->match.acl.da_depth,
2846 snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
2850 if (softnic_parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
2851 snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
2855 if (softnic_parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
2856 snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
2860 if (softnic_parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
2861 snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
2865 if (softnic_parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
2866 snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
2870 if (softnic_parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
2871 snprintf(out, out_size, MSG_ARG_INVALID, "proto");
2875 m->match.acl.proto_mask = 0xff;
2880 if (strcmp(tokens[1], "array") == 0) {
2882 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2886 m->match_type = TABLE_ARRAY;
2888 if (softnic_parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
2889 snprintf(out, out_size, MSG_ARG_INVALID, "pos");
2896 if (strcmp(tokens[1], "hash") == 0) {
2898 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2902 m->match_type = TABLE_HASH;
2904 if (strcmp(tokens[2], "raw") == 0) {
2905 uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
2908 snprintf(out, out_size, MSG_ARG_MISMATCH,
2913 if (softnic_parse_hex_string(tokens[3],
2914 m->match.hash.key, &key_size) != 0) {
2915 snprintf(out, out_size, MSG_ARG_INVALID, "key");
2922 if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
2923 struct pkt_key_ipv4_5tuple *ipv4 =
2924 (struct pkt_key_ipv4_5tuple *)m->match.hash.key;
2925 struct in_addr saddr, daddr;
2930 snprintf(out, out_size, MSG_ARG_MISMATCH,
2935 if (softnic_parse_ipv4_addr(tokens[3], &saddr) != 0) {
2936 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2940 if (softnic_parse_ipv4_addr(tokens[4], &daddr) != 0) {
2941 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2945 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2946 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2950 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2951 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
2955 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
2956 snprintf(out, out_size, MSG_ARG_INVALID,
2961 ipv4->sa = saddr.s_addr;
2962 ipv4->da = daddr.s_addr;
2963 ipv4->sp = rte_cpu_to_be_16(sp);
2964 ipv4->dp = rte_cpu_to_be_16(dp);
2965 ipv4->proto = proto;
2968 } /* hash ipv4_5tuple */
2970 if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
2971 struct pkt_key_ipv6_5tuple *ipv6 =
2972 (struct pkt_key_ipv6_5tuple *)m->match.hash.key;
2973 struct in6_addr saddr, daddr;
2978 snprintf(out, out_size, MSG_ARG_MISMATCH,
2983 if (softnic_parse_ipv6_addr(tokens[3], &saddr) != 0) {
2984 snprintf(out, out_size, MSG_ARG_INVALID, "sa");
2988 if (softnic_parse_ipv6_addr(tokens[4], &daddr) != 0) {
2989 snprintf(out, out_size, MSG_ARG_INVALID, "da");
2993 if (softnic_parser_read_uint16(&sp, tokens[5]) != 0) {
2994 snprintf(out, out_size, MSG_ARG_INVALID, "sp");
2998 if (softnic_parser_read_uint16(&dp, tokens[6]) != 0) {
2999 snprintf(out, out_size, MSG_ARG_INVALID, "dp");
3003 if (softnic_parser_read_uint8(&proto, tokens[7]) != 0) {
3004 snprintf(out, out_size, MSG_ARG_INVALID,
3009 memcpy(ipv6->sa, saddr.s6_addr, 16);
3010 memcpy(ipv6->da, daddr.s6_addr, 16);
3011 ipv6->sp = rte_cpu_to_be_16(sp);
3012 ipv6->dp = rte_cpu_to_be_16(dp);
3013 ipv6->proto = proto;
3016 } /* hash ipv6_5tuple */
3018 if (strcmp(tokens[2], "ipv4_addr") == 0) {
3019 struct pkt_key_ipv4_addr *ipv4_addr =
3020 (struct pkt_key_ipv4_addr *)m->match.hash.key;
3021 struct in_addr addr;
3024 snprintf(out, out_size, MSG_ARG_MISMATCH,
3029 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3030 snprintf(out, out_size, MSG_ARG_INVALID,
3035 ipv4_addr->addr = addr.s_addr;
3038 } /* hash ipv4_addr */
3040 if (strcmp(tokens[2], "ipv6_addr") == 0) {
3041 struct pkt_key_ipv6_addr *ipv6_addr =
3042 (struct pkt_key_ipv6_addr *)m->match.hash.key;
3043 struct in6_addr addr;
3046 snprintf(out, out_size, MSG_ARG_MISMATCH,
3051 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3052 snprintf(out, out_size, MSG_ARG_INVALID,
3057 memcpy(ipv6_addr->addr, addr.s6_addr, 16);
3060 } /* hash ipv6_5tuple */
3062 if (strcmp(tokens[2], "qinq") == 0) {
3063 struct pkt_key_qinq *qinq =
3064 (struct pkt_key_qinq *)m->match.hash.key;
3065 uint16_t svlan, cvlan;
3068 snprintf(out, out_size, MSG_ARG_MISMATCH,
3073 if ((softnic_parser_read_uint16(&svlan, tokens[3]) != 0) ||
3075 snprintf(out, out_size, MSG_ARG_INVALID,
3080 if ((softnic_parser_read_uint16(&cvlan, tokens[4]) != 0) ||
3082 snprintf(out, out_size, MSG_ARG_INVALID,
3087 qinq->svlan = rte_cpu_to_be_16(svlan);
3088 qinq->cvlan = rte_cpu_to_be_16(cvlan);
3093 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3097 if (strcmp(tokens[1], "lpm") == 0) {
3099 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3103 m->match_type = TABLE_LPM;
3105 if (strcmp(tokens[2], "ipv4") == 0) {
3106 struct in_addr addr;
3108 m->match.lpm.ip_version = 1;
3110 if (softnic_parse_ipv4_addr(tokens[3], &addr) != 0) {
3111 snprintf(out, out_size, MSG_ARG_INVALID,
3116 m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3117 } else if (strcmp(tokens[2], "ipv6") == 0) {
3118 struct in6_addr addr;
3120 m->match.lpm.ip_version = 0;
3122 if (softnic_parse_ipv6_addr(tokens[3], &addr) != 0) {
3123 snprintf(out, out_size, MSG_ARG_INVALID,
3128 memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
3130 snprintf(out, out_size, MSG_ARG_MISMATCH,
3135 if (softnic_parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
3136 snprintf(out, out_size, MSG_ARG_INVALID, "depth");
3143 snprintf(out, out_size, MSG_ARG_MISMATCH,
3144 "acl or array or hash or lpm");
3156 * | table <table_id>
3157 * [balance <out0> ... <out7>]
3159 * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3160 * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3161 * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
3162 * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
3163 * [tm subport <subport_id> pipe <pipe_id>]
3166 * | vlan <da> <sa> <pcp> <dei> <vid>
3167 * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
3168 * | mpls unicast | multicast
3170 * label0 <label> <tc> <ttl>
3171 * [label1 <label> <tc> <ttl>
3172 * [label2 <label> <tc> <ttl>
3173 * [label3 <label> <tc> <ttl>]]]
3174 * | pppoe <da> <sa> <session_id>]
3175 * [nat ipv4 | ipv6 <addr> <port>]
3181 * <pa> ::= g | y | r | drop
3184 parse_table_action_fwd(char **tokens,
3186 struct softnic_table_rule_action *a)
3188 if (n_tokens == 0 ||
3189 (strcmp(tokens[0], "fwd") != 0))
3195 if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
3196 a->fwd.action = RTE_PIPELINE_ACTION_DROP;
3197 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3201 if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
3205 softnic_parser_read_uint32(&id, tokens[1]))
3208 a->fwd.action = RTE_PIPELINE_ACTION_PORT;
3210 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3214 if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
3215 a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
3216 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3220 if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
3224 softnic_parser_read_uint32(&id, tokens[1]))
3227 a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
3229 a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
3237 parse_table_action_balance(char **tokens,
3239 struct softnic_table_rule_action *a)
3243 if (n_tokens == 0 ||
3244 (strcmp(tokens[0], "balance") != 0))
3250 if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
3253 for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
3254 if (softnic_parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
3257 a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
3258 return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
3262 parse_policer_action(char *token, enum rte_table_action_policer *a)
3264 if (strcmp(token, "g") == 0) {
3265 *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
3269 if (strcmp(token, "y") == 0) {
3270 *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
3274 if (strcmp(token, "r") == 0) {
3275 *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
3279 if (strcmp(token, "drop") == 0) {
3280 *a = RTE_TABLE_ACTION_POLICER_DROP;
3288 parse_table_action_meter_tc(char **tokens,
3290 struct rte_table_action_mtr_tc_params *mtr)
3293 strcmp(tokens[0], "meter") ||
3294 softnic_parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
3295 strcmp(tokens[2], "policer") ||
3296 strcmp(tokens[3], "g") ||
3297 parse_policer_action(tokens[4], &mtr->policer[e_RTE_METER_GREEN]) ||
3298 strcmp(tokens[5], "y") ||
3299 parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
3300 strcmp(tokens[7], "r") ||
3301 parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_RED]))
3308 parse_table_action_meter(char **tokens,
3310 struct softnic_table_rule_action *a)
3312 if (n_tokens == 0 ||
3313 strcmp(tokens[0], "meter"))
3319 if (n_tokens < 10 ||
3320 strcmp(tokens[0], "tc0") ||
3321 (parse_table_action_meter_tc(tokens + 1,
3323 &a->mtr.mtr[0]) == 0))
3329 if (n_tokens == 0 ||
3330 strcmp(tokens[0], "tc1")) {
3332 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3336 if (n_tokens < 30 ||
3337 (parse_table_action_meter_tc(tokens + 1,
3338 n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
3339 strcmp(tokens[10], "tc2") ||
3340 (parse_table_action_meter_tc(tokens + 11,
3341 n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
3342 strcmp(tokens[20], "tc3") ||
3343 (parse_table_action_meter_tc(tokens + 21,
3344 n_tokens - 21, &a->mtr.mtr[3]) == 0))
3347 a->mtr.tc_mask = 0xF;
3348 a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
3349 return 1 + 10 + 3 * 10;
3353 parse_table_action_tm(char **tokens,
3355 struct softnic_table_rule_action *a)
3357 uint32_t subport_id, pipe_id;
3360 strcmp(tokens[0], "tm") ||
3361 strcmp(tokens[1], "subport") ||
3362 softnic_parser_read_uint32(&subport_id, tokens[2]) ||
3363 strcmp(tokens[3], "pipe") ||
3364 softnic_parser_read_uint32(&pipe_id, tokens[4]))
3367 a->tm.subport_id = subport_id;
3368 a->tm.pipe_id = pipe_id;
3369 a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
3374 parse_table_action_encap(char **tokens,
3376 struct softnic_table_rule_action *a)
3378 if (n_tokens == 0 ||
3379 strcmp(tokens[0], "encap"))
3386 if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
3388 softnic_parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
3389 softnic_parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
3392 a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
3393 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3398 if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
3399 uint32_t pcp, dei, vid;
3402 softnic_parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
3403 softnic_parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
3404 softnic_parser_read_uint32(&pcp, tokens[3]) ||
3406 softnic_parser_read_uint32(&dei, tokens[4]) ||
3408 softnic_parser_read_uint32(&vid, tokens[5]) ||
3412 a->encap.vlan.vlan.pcp = pcp & 0x7;
3413 a->encap.vlan.vlan.dei = dei & 0x1;
3414 a->encap.vlan.vlan.vid = vid & 0xFFF;
3415 a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
3416 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3421 if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
3422 uint32_t svlan_pcp, svlan_dei, svlan_vid;
3423 uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
3426 softnic_parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
3427 softnic_parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
3428 softnic_parser_read_uint32(&svlan_pcp, tokens[3]) ||
3430 softnic_parser_read_uint32(&svlan_dei, tokens[4]) ||
3432 softnic_parser_read_uint32(&svlan_vid, tokens[5]) ||
3433 svlan_vid > 0xFFF ||
3434 softnic_parser_read_uint32(&cvlan_pcp, tokens[6]) ||
3436 softnic_parser_read_uint32(&cvlan_dei, tokens[7]) ||
3438 softnic_parser_read_uint32(&cvlan_vid, tokens[8]) ||
3442 a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
3443 a->encap.qinq.svlan.dei = svlan_dei & 0x1;
3444 a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
3445 a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
3446 a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
3447 a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
3448 a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
3449 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3454 if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
3455 uint32_t label, tc, ttl;
3460 if (strcmp(tokens[1], "unicast") == 0)
3461 a->encap.mpls.unicast = 1;
3462 else if (strcmp(tokens[1], "multicast") == 0)
3463 a->encap.mpls.unicast = 0;
3467 if (softnic_parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
3468 softnic_parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
3469 strcmp(tokens[4], "label0") ||
3470 softnic_parser_read_uint32(&label, tokens[5]) ||
3472 softnic_parser_read_uint32(&tc, tokens[6]) ||
3474 softnic_parser_read_uint32(&ttl, tokens[7]) ||
3478 a->encap.mpls.mpls[0].label = label;
3479 a->encap.mpls.mpls[0].tc = tc;
3480 a->encap.mpls.mpls[0].ttl = ttl;
3485 if (n_tokens == 0 ||
3486 strcmp(tokens[0], "label1")) {
3487 a->encap.mpls.mpls_count = 1;
3488 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3489 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3494 softnic_parser_read_uint32(&label, tokens[1]) ||
3496 softnic_parser_read_uint32(&tc, tokens[2]) ||
3498 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3502 a->encap.mpls.mpls[1].label = label;
3503 a->encap.mpls.mpls[1].tc = tc;
3504 a->encap.mpls.mpls[1].ttl = ttl;
3509 if (n_tokens == 0 ||
3510 strcmp(tokens[0], "label2")) {
3511 a->encap.mpls.mpls_count = 2;
3512 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3513 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3518 softnic_parser_read_uint32(&label, tokens[1]) ||
3520 softnic_parser_read_uint32(&tc, tokens[2]) ||
3522 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3526 a->encap.mpls.mpls[2].label = label;
3527 a->encap.mpls.mpls[2].tc = tc;
3528 a->encap.mpls.mpls[2].ttl = ttl;
3533 if (n_tokens == 0 ||
3534 strcmp(tokens[0], "label3")) {
3535 a->encap.mpls.mpls_count = 3;
3536 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3537 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3538 return 1 + 8 + 4 + 4;
3542 softnic_parser_read_uint32(&label, tokens[1]) ||
3544 softnic_parser_read_uint32(&tc, tokens[2]) ||
3546 softnic_parser_read_uint32(&ttl, tokens[3]) ||
3550 a->encap.mpls.mpls[3].label = label;
3551 a->encap.mpls.mpls[3].tc = tc;
3552 a->encap.mpls.mpls[3].ttl = ttl;
3554 a->encap.mpls.mpls_count = 4;
3555 a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
3556 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3557 return 1 + 8 + 4 + 4 + 4;
3561 if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
3563 softnic_parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
3564 softnic_parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
3565 softnic_parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
3569 a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
3570 a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
3578 parse_table_action_nat(char **tokens,
3580 struct softnic_table_rule_action *a)
3583 strcmp(tokens[0], "nat"))
3586 if (strcmp(tokens[1], "ipv4") == 0) {
3587 struct in_addr addr;
3590 if (softnic_parse_ipv4_addr(tokens[2], &addr) ||
3591 softnic_parser_read_uint16(&port, tokens[3]))
3594 a->nat.ip_version = 1;
3595 a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
3597 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3601 if (strcmp(tokens[1], "ipv6") == 0) {
3602 struct in6_addr addr;
3605 if (softnic_parse_ipv6_addr(tokens[2], &addr) ||
3606 softnic_parser_read_uint16(&port, tokens[3]))
3609 a->nat.ip_version = 0;
3610 memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
3612 a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
3620 parse_table_action_ttl(char **tokens,
3622 struct softnic_table_rule_action *a)
3625 strcmp(tokens[0], "ttl"))
3628 if (strcmp(tokens[1], "dec") == 0)
3629 a->ttl.decrement = 1;
3630 else if (strcmp(tokens[1], "keep") == 0)
3631 a->ttl.decrement = 0;
3635 a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
3640 parse_table_action_stats(char **tokens,
3642 struct softnic_table_rule_action *a)
3645 strcmp(tokens[0], "stats"))
3648 a->stats.n_packets = 0;
3649 a->stats.n_bytes = 0;
3650 a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
3655 parse_table_action_time(char **tokens,
3657 struct softnic_table_rule_action *a)
3660 strcmp(tokens[0], "time"))
3663 a->time.time = rte_rdtsc();
3664 a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
3669 parse_table_action(char **tokens,
3673 struct softnic_table_rule_action *a)
3675 uint32_t n_tokens0 = n_tokens;
3677 memset(a, 0, sizeof(*a));
3680 strcmp(tokens[0], "action"))
3686 if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
3689 n = parse_table_action_fwd(tokens, n_tokens, a);
3691 snprintf(out, out_size, MSG_ARG_INVALID,
3700 if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
3703 n = parse_table_action_balance(tokens, n_tokens, a);
3705 snprintf(out, out_size, MSG_ARG_INVALID,
3714 if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
3717 n = parse_table_action_meter(tokens, n_tokens, a);
3719 snprintf(out, out_size, MSG_ARG_INVALID,
3728 if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
3731 n = parse_table_action_tm(tokens, n_tokens, a);
3733 snprintf(out, out_size, MSG_ARG_INVALID,
3742 if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
3745 n = parse_table_action_encap(tokens, n_tokens, a);
3747 snprintf(out, out_size, MSG_ARG_INVALID,
3756 if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
3759 n = parse_table_action_nat(tokens, n_tokens, a);
3761 snprintf(out, out_size, MSG_ARG_INVALID,
3770 if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
3773 n = parse_table_action_ttl(tokens, n_tokens, a);
3775 snprintf(out, out_size, MSG_ARG_INVALID,
3784 if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
3787 n = parse_table_action_stats(tokens, n_tokens, a);
3789 snprintf(out, out_size, MSG_ARG_INVALID,
3798 if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
3801 n = parse_table_action_time(tokens, n_tokens, a);
3803 snprintf(out, out_size, MSG_ARG_INVALID,
3812 if (n_tokens0 - n_tokens == 1) {
3813 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3817 return n_tokens0 - n_tokens;
3821 * pipeline <pipeline_name> table <table_id> rule add
3823 * action <table_action>
3826 cmd_softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
3832 struct softnic_table_rule_match m;
3833 struct softnic_table_rule_action a;
3834 char *pipeline_name;
3836 uint32_t table_id, t0, n_tokens_parsed;
3840 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3844 pipeline_name = tokens[1];
3846 if (strcmp(tokens[2], "table") != 0) {
3847 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3851 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3852 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3856 if (strcmp(tokens[4], "rule") != 0) {
3857 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3861 if (strcmp(tokens[5], "add") != 0) {
3862 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3869 n_tokens_parsed = parse_match(tokens + t0,
3874 if (n_tokens_parsed == 0)
3876 t0 += n_tokens_parsed;
3879 n_tokens_parsed = parse_table_action(tokens + t0,
3884 if (n_tokens_parsed == 0)
3886 t0 += n_tokens_parsed;
3888 if (t0 != n_tokens) {
3889 snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
3893 status = softnic_pipeline_table_rule_add(softnic,
3900 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3906 * pipeline <pipeline_name> table <table_id> rule add
3914 * | table <table_id>
3917 cmd_softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
3923 struct softnic_table_rule_action action;
3925 char *pipeline_name;
3929 if (n_tokens != 11 &&
3931 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3935 pipeline_name = tokens[1];
3937 if (strcmp(tokens[2], "table") != 0) {
3938 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
3942 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
3943 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
3947 if (strcmp(tokens[4], "rule") != 0) {
3948 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
3952 if (strcmp(tokens[5], "add") != 0) {
3953 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
3957 if (strcmp(tokens[6], "match") != 0) {
3958 snprintf(out, out_size, MSG_ARG_INVALID, "match");
3962 if (strcmp(tokens[7], "default") != 0) {
3963 snprintf(out, out_size, MSG_ARG_INVALID, "default");
3967 if (strcmp(tokens[8], "action") != 0) {
3968 snprintf(out, out_size, MSG_ARG_INVALID, "action");
3972 if (strcmp(tokens[9], "fwd") != 0) {
3973 snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
3977 action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
3979 if (strcmp(tokens[10], "drop") == 0) {
3980 if (n_tokens != 11) {
3981 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3985 action.fwd.action = RTE_PIPELINE_ACTION_DROP;
3986 } else if (strcmp(tokens[10], "port") == 0) {
3989 if (n_tokens != 12) {
3990 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3994 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
3995 snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
3999 action.fwd.action = RTE_PIPELINE_ACTION_PORT;
4001 } else if (strcmp(tokens[10], "meta") == 0) {
4002 if (n_tokens != 11) {
4003 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4007 action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
4008 } else if (strcmp(tokens[10], "table") == 0) {
4011 if (n_tokens != 12) {
4012 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4016 if (softnic_parser_read_uint32(&id, tokens[11]) != 0) {
4017 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4021 action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
4024 snprintf(out, out_size, MSG_ARG_INVALID,
4025 "drop or port or meta or table");
4029 status = softnic_pipeline_table_rule_add_default(softnic,
4035 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4041 * pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
4044 * - line format: match <match> action <action>
4047 cli_rule_file_process(const char *file_name,
4048 size_t line_len_max,
4049 struct softnic_table_rule_match *m,
4050 struct softnic_table_rule_action *a,
4052 uint32_t *line_number,
4057 cmd_softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
4063 struct softnic_table_rule_match *match;
4064 struct softnic_table_rule_action *action;
4066 char *pipeline_name, *file_name;
4067 uint32_t table_id, n_rules, n_rules_parsed, line_number;
4070 if (n_tokens != 9) {
4071 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4075 pipeline_name = tokens[1];
4077 if (strcmp(tokens[2], "table") != 0) {
4078 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4082 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4083 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4087 if (strcmp(tokens[4], "rule") != 0) {
4088 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4092 if (strcmp(tokens[5], "add") != 0) {
4093 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4097 if (strcmp(tokens[6], "bulk") != 0) {
4098 snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
4102 file_name = tokens[7];
4104 if ((softnic_parser_read_uint32(&n_rules, tokens[8]) != 0) ||
4106 snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
4110 /* Memory allocation. */
4111 match = calloc(n_rules, sizeof(struct softnic_table_rule_match));
4112 action = calloc(n_rules, sizeof(struct softnic_table_rule_action));
4113 data = calloc(n_rules, sizeof(void *));
4114 if (match == NULL ||
4117 snprintf(out, out_size, MSG_OUT_OF_MEMORY);
4124 /* Load rule file */
4125 n_rules_parsed = n_rules;
4126 status = cli_rule_file_process(file_name,
4135 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4141 if (n_rules_parsed != n_rules) {
4142 snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
4150 status = softnic_pipeline_table_rule_add_bulk(softnic,
4158 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4172 * pipeline <pipeline_name> table <table_id> rule delete
4176 cmd_softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
4182 struct softnic_table_rule_match m;
4183 char *pipeline_name;
4184 uint32_t table_id, n_tokens_parsed, t0;
4188 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4192 pipeline_name = tokens[1];
4194 if (strcmp(tokens[2], "table") != 0) {
4195 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4199 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4200 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4204 if (strcmp(tokens[4], "rule") != 0) {
4205 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4209 if (strcmp(tokens[5], "delete") != 0) {
4210 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4217 n_tokens_parsed = parse_match(tokens + t0,
4222 if (n_tokens_parsed == 0)
4224 t0 += n_tokens_parsed;
4226 if (n_tokens != t0) {
4227 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4231 status = softnic_pipeline_table_rule_delete(softnic,
4236 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4242 * pipeline <pipeline_name> table <table_id> rule delete
4247 cmd_softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
4253 char *pipeline_name;
4257 if (n_tokens != 8) {
4258 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4262 pipeline_name = tokens[1];
4264 if (strcmp(tokens[2], "table") != 0) {
4265 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4269 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4270 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4274 if (strcmp(tokens[4], "rule") != 0) {
4275 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
4279 if (strcmp(tokens[5], "delete") != 0) {
4280 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4284 if (strcmp(tokens[6], "match") != 0) {
4285 snprintf(out, out_size, MSG_ARG_INVALID, "match");
4289 if (strcmp(tokens[7], "default") != 0) {
4290 snprintf(out, out_size, MSG_ARG_INVALID, "default");
4294 status = softnic_pipeline_table_rule_delete_default(softnic,
4298 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4304 * pipeline <pipeline_name> table <table_id> rule read stats [clear]
4307 cmd_softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic __rte_unused,
4309 uint32_t n_tokens __rte_unused,
4313 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4317 * pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
4318 * add srtcm cir <cir> cbs <cbs> ebs <ebs>
4319 * | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
4322 cmd_pipeline_table_meter_profile_add(struct pmd_internals *softnic,
4328 struct rte_table_action_meter_profile p;
4329 char *pipeline_name;
4330 uint32_t table_id, meter_profile_id;
4334 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4338 pipeline_name = tokens[1];
4340 if (strcmp(tokens[2], "table") != 0) {
4341 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4345 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4346 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4350 if (strcmp(tokens[4], "meter") != 0) {
4351 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4355 if (strcmp(tokens[5], "profile") != 0) {
4356 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4360 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4361 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4365 if (strcmp(tokens[7], "add") != 0) {
4366 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
4370 if (strcmp(tokens[8], "srtcm") == 0) {
4371 if (n_tokens != 15) {
4372 snprintf(out, out_size, MSG_ARG_MISMATCH,
4377 p.alg = RTE_TABLE_ACTION_METER_SRTCM;
4379 if (strcmp(tokens[9], "cir") != 0) {
4380 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4384 if (softnic_parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
4385 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4389 if (strcmp(tokens[11], "cbs") != 0) {
4390 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4394 if (softnic_parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
4395 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4399 if (strcmp(tokens[13], "ebs") != 0) {
4400 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
4404 if (softnic_parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
4405 snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
4408 } else if (strcmp(tokens[8], "trtcm") == 0) {
4409 if (n_tokens != 17) {
4410 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4414 p.alg = RTE_TABLE_ACTION_METER_TRTCM;
4416 if (strcmp(tokens[9], "cir") != 0) {
4417 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
4421 if (softnic_parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
4422 snprintf(out, out_size, MSG_ARG_INVALID, "cir");
4426 if (strcmp(tokens[11], "pir") != 0) {
4427 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
4431 if (softnic_parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
4432 snprintf(out, out_size, MSG_ARG_INVALID, "pir");
4435 if (strcmp(tokens[13], "cbs") != 0) {
4436 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
4440 if (softnic_parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
4441 snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
4445 if (strcmp(tokens[15], "pbs") != 0) {
4446 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
4450 if (softnic_parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
4451 snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
4455 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4459 status = softnic_pipeline_table_mtr_profile_add(softnic,
4465 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4471 * pipeline <pipeline_name> table <table_id>
4472 * meter profile <meter_profile_id> delete
4475 cmd_pipeline_table_meter_profile_delete(struct pmd_internals *softnic,
4481 char *pipeline_name;
4482 uint32_t table_id, meter_profile_id;
4485 if (n_tokens != 8) {
4486 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4490 pipeline_name = tokens[1];
4492 if (strcmp(tokens[2], "table") != 0) {
4493 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4497 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4498 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4502 if (strcmp(tokens[4], "meter") != 0) {
4503 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
4507 if (strcmp(tokens[5], "profile") != 0) {
4508 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
4512 if (softnic_parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
4513 snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
4517 if (strcmp(tokens[7], "delete") != 0) {
4518 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
4522 status = softnic_pipeline_table_mtr_profile_delete(softnic,
4527 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4533 * pipeline <pipeline_name> table <table_id> rule read meter [clear]
4536 cmd_pipeline_table_rule_meter_read(struct pmd_internals *softnic __rte_unused,
4538 uint32_t n_tokens __rte_unused,
4542 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4546 * pipeline <pipeline_name> table <table_id> dscp <file_name>
4549 * - exactly 64 lines
4550 * - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
4553 load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
4554 const char *file_name,
4555 uint32_t *line_number)
4560 /* Check input arguments */
4561 if (dscp_table == NULL ||
4562 file_name == NULL ||
4563 line_number == NULL) {
4569 /* Open input file */
4570 f = fopen(file_name, "r");
4577 for (dscp = 0, l = 1; ; l++) {
4580 enum rte_meter_color color;
4581 uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
4583 if (fgets(line, sizeof(line), f) == NULL)
4586 if (is_comment(line))
4589 if (softnic_parse_tokenize_string(line, tokens, &n_tokens)) {
4598 if (dscp >= RTE_DIM(dscp_table->entry) ||
4599 n_tokens != RTE_DIM(tokens) ||
4600 softnic_parser_read_uint32(&tc_id, tokens[0]) ||
4601 tc_id >= RTE_TABLE_ACTION_TC_MAX ||
4602 softnic_parser_read_uint32(&tc_queue_id, tokens[1]) ||
4603 tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX ||
4604 (strlen(tokens[2]) != 1)) {
4610 switch (tokens[2][0]) {
4613 color = e_RTE_METER_GREEN;
4618 color = e_RTE_METER_YELLOW;
4623 color = e_RTE_METER_RED;
4632 dscp_table->entry[dscp].tc_id = tc_id;
4633 dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
4634 dscp_table->entry[dscp].color = color;
4644 cmd_pipeline_table_dscp(struct pmd_internals *softnic,
4650 struct rte_table_action_dscp_table dscp_table;
4651 char *pipeline_name, *file_name;
4652 uint32_t table_id, line_number;
4655 if (n_tokens != 6) {
4656 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4660 pipeline_name = tokens[1];
4662 if (strcmp(tokens[2], "table") != 0) {
4663 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
4667 if (softnic_parser_read_uint32(&table_id, tokens[3]) != 0) {
4668 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4672 if (strcmp(tokens[4], "dscp") != 0) {
4673 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
4677 file_name = tokens[5];
4679 status = load_dscp_table(&dscp_table, file_name, &line_number);
4681 snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
4685 status = softnic_pipeline_table_dscp_table_update(softnic,
4691 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4697 * pipeline <pipeline_name> table <table_id> rule read ttl [clear]
4700 cmd_softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic __rte_unused,
4702 uint32_t n_tokens __rte_unused,
4706 snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
4710 * thread <thread_id> pipeline <pipeline_name> enable
4713 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
4719 char *pipeline_name;
4723 if (n_tokens != 5) {
4724 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4728 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4729 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4733 if (strcmp(tokens[2], "pipeline") != 0) {
4734 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4738 pipeline_name = tokens[3];
4740 if (strcmp(tokens[4], "enable") != 0) {
4741 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
4745 status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
4747 snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
4753 * thread <thread_id> pipeline <pipeline_name> disable
4756 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
4762 char *pipeline_name;
4766 if (n_tokens != 5) {
4767 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4771 if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
4772 snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
4776 if (strcmp(tokens[2], "pipeline") != 0) {
4777 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4781 pipeline_name = tokens[3];
4783 if (strcmp(tokens[4], "disable") != 0) {
4784 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
4788 status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
4790 snprintf(out, out_size, MSG_CMD_FAIL,
4791 "thread pipeline disable");
4800 * pipeline <pipeline_name>
4804 cmd_softnic_flowapi_map(struct pmd_internals *softnic,
4810 char *pipeline_name;
4811 uint32_t group_id, table_id;
4812 int ingress, status;
4814 if (n_tokens != 9) {
4815 snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4819 if (strcmp(tokens[1], "map") != 0) {
4820 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "map");
4824 if (strcmp(tokens[2], "group") != 0) {
4825 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group");
4829 if (softnic_parser_read_uint32(&group_id, tokens[3]) != 0) {
4830 snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
4834 if (strcmp(tokens[4], "ingress") == 0) {
4836 } else if (strcmp(tokens[4], "egress") == 0) {
4839 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ingress | egress");
4843 if (strcmp(tokens[5], "pipeline") != 0) {
4844 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
4848 pipeline_name = tokens[6];
4850 if (strcmp(tokens[7], "table") != 0) {
4851 snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
4855 if (softnic_parser_read_uint32(&table_id, tokens[8]) != 0) {
4856 snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
4860 status = flow_attr_map_set(softnic,
4866 snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
4872 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
4874 char *tokens[CMD_MAX_TOKENS];
4875 uint32_t n_tokens = RTE_DIM(tokens);
4876 struct pmd_internals *softnic = arg;
4882 status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
4884 snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
4891 if (strcmp(tokens[0], "mempool") == 0) {
4892 cmd_mempool(softnic, tokens, n_tokens, out, out_size);
4896 if (strcmp(tokens[0], "link") == 0) {
4897 cmd_link(softnic, tokens, n_tokens, out, out_size);
4901 if (strcmp(tokens[0], "swq") == 0) {
4902 cmd_swq(softnic, tokens, n_tokens, out, out_size);
4906 if (strcmp(tokens[0], "tmgr") == 0) {
4907 if (n_tokens == 2) {
4908 cmd_tmgr(softnic, tokens, n_tokens, out, out_size);
4912 if (n_tokens >= 3 &&
4913 (strcmp(tokens[1], "shaper") == 0) &&
4914 (strcmp(tokens[2], "profile") == 0)) {
4915 cmd_tmgr_shaper_profile(softnic, tokens, n_tokens, out, out_size);
4919 if (n_tokens >= 3 &&
4920 (strcmp(tokens[1], "shared") == 0) &&
4921 (strcmp(tokens[2], "shaper") == 0)) {
4922 cmd_tmgr_shared_shaper(softnic, tokens, n_tokens, out, out_size);
4926 if (n_tokens >= 2 &&
4927 (strcmp(tokens[1], "node") == 0)) {
4928 cmd_tmgr_node(softnic, tokens, n_tokens, out, out_size);
4932 if (n_tokens >= 2 &&
4933 (strcmp(tokens[1], "hierarchy-default") == 0)) {
4934 cmd_tmgr_hierarchy_default(softnic, tokens, n_tokens, out, out_size);
4938 if (n_tokens >= 3 &&
4939 (strcmp(tokens[1], "hierarchy") == 0) &&
4940 (strcmp(tokens[2], "commit") == 0)) {
4941 cmd_tmgr_hierarchy_commit(softnic, tokens, n_tokens, out, out_size);
4946 if (strcmp(tokens[0], "tap") == 0) {
4947 cmd_tap(softnic, tokens, n_tokens, out, out_size);
4951 if (strcmp(tokens[0], "port") == 0) {
4952 cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
4956 if (strcmp(tokens[0], "table") == 0) {
4957 cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
4961 if (strcmp(tokens[0], "pipeline") == 0) {
4962 if (n_tokens >= 3 &&
4963 (strcmp(tokens[2], "period") == 0)) {
4964 cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
4968 if (n_tokens >= 5 &&
4969 (strcmp(tokens[2], "port") == 0) &&
4970 (strcmp(tokens[3], "in") == 0) &&
4971 (strcmp(tokens[4], "bsz") == 0)) {
4972 cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
4976 if (n_tokens >= 5 &&
4977 (strcmp(tokens[2], "port") == 0) &&
4978 (strcmp(tokens[3], "out") == 0) &&
4979 (strcmp(tokens[4], "bsz") == 0)) {
4980 cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
4984 if (n_tokens >= 4 &&
4985 (strcmp(tokens[2], "table") == 0) &&
4986 (strcmp(tokens[3], "match") == 0)) {
4987 cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
4991 if (n_tokens >= 6 &&
4992 (strcmp(tokens[2], "port") == 0) &&
4993 (strcmp(tokens[3], "in") == 0) &&
4994 (strcmp(tokens[5], "table") == 0)) {
4995 cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
5000 if (n_tokens >= 6 &&
5001 (strcmp(tokens[2], "port") == 0) &&
5002 (strcmp(tokens[3], "in") == 0) &&
5003 (strcmp(tokens[5], "stats") == 0)) {
5004 cmd_pipeline_port_in_stats(softnic, tokens, n_tokens,
5009 if (n_tokens >= 6 &&
5010 (strcmp(tokens[2], "port") == 0) &&
5011 (strcmp(tokens[3], "in") == 0) &&
5012 (strcmp(tokens[5], "enable") == 0)) {
5013 cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
5018 if (n_tokens >= 6 &&
5019 (strcmp(tokens[2], "port") == 0) &&
5020 (strcmp(tokens[3], "in") == 0) &&
5021 (strcmp(tokens[5], "disable") == 0)) {
5022 cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
5027 if (n_tokens >= 6 &&
5028 (strcmp(tokens[2], "port") == 0) &&
5029 (strcmp(tokens[3], "out") == 0) &&
5030 (strcmp(tokens[5], "stats") == 0)) {
5031 cmd_pipeline_port_out_stats(softnic, tokens, n_tokens,
5036 if (n_tokens >= 5 &&
5037 (strcmp(tokens[2], "table") == 0) &&
5038 (strcmp(tokens[4], "stats") == 0)) {
5039 cmd_pipeline_table_stats(softnic, tokens, n_tokens,
5044 if (n_tokens >= 7 &&
5045 (strcmp(tokens[2], "table") == 0) &&
5046 (strcmp(tokens[4], "rule") == 0) &&
5047 (strcmp(tokens[5], "add") == 0) &&
5048 (strcmp(tokens[6], "match") == 0)) {
5049 if (n_tokens >= 8 &&
5050 (strcmp(tokens[7], "default") == 0)) {
5051 cmd_softnic_pipeline_table_rule_add_default(softnic, tokens,
5052 n_tokens, out, out_size);
5056 cmd_softnic_pipeline_table_rule_add(softnic, tokens, n_tokens,
5061 if (n_tokens >= 7 &&
5062 (strcmp(tokens[2], "table") == 0) &&
5063 (strcmp(tokens[4], "rule") == 0) &&
5064 (strcmp(tokens[5], "add") == 0) &&
5065 (strcmp(tokens[6], "bulk") == 0)) {
5066 cmd_softnic_pipeline_table_rule_add_bulk(softnic, tokens,
5067 n_tokens, out, out_size);
5071 if (n_tokens >= 7 &&
5072 (strcmp(tokens[2], "table") == 0) &&
5073 (strcmp(tokens[4], "rule") == 0) &&
5074 (strcmp(tokens[5], "delete") == 0) &&
5075 (strcmp(tokens[6], "match") == 0)) {
5076 if (n_tokens >= 8 &&
5077 (strcmp(tokens[7], "default") == 0)) {
5078 cmd_softnic_pipeline_table_rule_delete_default(softnic, tokens,
5079 n_tokens, out, out_size);
5083 cmd_softnic_pipeline_table_rule_delete(softnic, tokens, n_tokens,
5088 if (n_tokens >= 7 &&
5089 (strcmp(tokens[2], "table") == 0) &&
5090 (strcmp(tokens[4], "rule") == 0) &&
5091 (strcmp(tokens[5], "read") == 0) &&
5092 (strcmp(tokens[6], "stats") == 0)) {
5093 cmd_softnic_pipeline_table_rule_stats_read(softnic, tokens, n_tokens,
5098 if (n_tokens >= 8 &&
5099 (strcmp(tokens[2], "table") == 0) &&
5100 (strcmp(tokens[4], "meter") == 0) &&
5101 (strcmp(tokens[5], "profile") == 0) &&
5102 (strcmp(tokens[7], "add") == 0)) {
5103 cmd_pipeline_table_meter_profile_add(softnic, tokens, n_tokens,
5108 if (n_tokens >= 8 &&
5109 (strcmp(tokens[2], "table") == 0) &&
5110 (strcmp(tokens[4], "meter") == 0) &&
5111 (strcmp(tokens[5], "profile") == 0) &&
5112 (strcmp(tokens[7], "delete") == 0)) {
5113 cmd_pipeline_table_meter_profile_delete(softnic, tokens,
5114 n_tokens, out, out_size);
5118 if (n_tokens >= 7 &&
5119 (strcmp(tokens[2], "table") == 0) &&
5120 (strcmp(tokens[4], "rule") == 0) &&
5121 (strcmp(tokens[5], "read") == 0) &&
5122 (strcmp(tokens[6], "meter") == 0)) {
5123 cmd_pipeline_table_rule_meter_read(softnic, tokens, n_tokens,
5128 if (n_tokens >= 5 &&
5129 (strcmp(tokens[2], "table") == 0) &&
5130 (strcmp(tokens[4], "dscp") == 0)) {
5131 cmd_pipeline_table_dscp(softnic, tokens, n_tokens,
5136 if (n_tokens >= 7 &&
5137 (strcmp(tokens[2], "table") == 0) &&
5138 (strcmp(tokens[4], "rule") == 0) &&
5139 (strcmp(tokens[5], "read") == 0) &&
5140 (strcmp(tokens[6], "ttl") == 0)) {
5141 cmd_softnic_pipeline_table_rule_ttl_read(softnic, tokens, n_tokens,
5147 if (strcmp(tokens[0], "thread") == 0) {
5148 if (n_tokens >= 5 &&
5149 (strcmp(tokens[4], "enable") == 0)) {
5150 cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
5155 if (n_tokens >= 5 &&
5156 (strcmp(tokens[4], "disable") == 0)) {
5157 cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
5163 if (strcmp(tokens[0], "flowapi") == 0) {
5164 cmd_softnic_flowapi_map(softnic, tokens, n_tokens, out,
5169 snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
5173 softnic_cli_script_process(struct pmd_internals *softnic,
5174 const char *file_name,
5175 size_t msg_in_len_max,
5176 size_t msg_out_len_max)
5178 char *msg_in = NULL, *msg_out = NULL;
5181 /* Check input arguments */
5182 if (file_name == NULL ||
5183 (strlen(file_name) == 0) ||
5184 msg_in_len_max == 0 ||
5185 msg_out_len_max == 0)
5188 msg_in = malloc(msg_in_len_max + 1);
5189 msg_out = malloc(msg_out_len_max + 1);
5190 if (msg_in == NULL ||
5197 /* Open input file */
5198 f = fopen(file_name, "r");
5207 if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
5210 printf("%s", msg_in);
5213 softnic_cli_process(msg_in,
5218 if (strlen(msg_out))
5219 printf("%s", msg_out);
5230 cli_rule_file_process(const char *file_name,
5231 size_t line_len_max,
5232 struct softnic_table_rule_match *m,
5233 struct softnic_table_rule_action *a,
5235 uint32_t *line_number,
5241 uint32_t rule_id, line_id;
5244 /* Check input arguments */
5245 if (file_name == NULL ||
5246 (strlen(file_name) == 0) ||
5247 line_len_max == 0) {
5252 /* Memory allocation */
5253 line = malloc(line_len_max + 1);
5260 f = fopen(file_name, "r");
5268 for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
5269 char *tokens[CMD_MAX_TOKENS];
5270 uint32_t n_tokens, n_tokens_parsed, t0;
5272 /* Read next line from file. */
5273 if (fgets(line, line_len_max + 1, f) == NULL)
5277 if (is_comment(line))
5281 n_tokens = RTE_DIM(tokens);
5282 status = softnic_parse_tokenize_string(line, tokens, &n_tokens);
5294 n_tokens_parsed = parse_match(tokens + t0,
5299 if (n_tokens_parsed == 0) {
5303 t0 += n_tokens_parsed;
5306 n_tokens_parsed = parse_table_action(tokens + t0,
5311 if (n_tokens_parsed == 0) {
5315 t0 += n_tokens_parsed;
5317 /* Line completed. */
5318 if (t0 < n_tokens) {
5323 /* Increment rule count */
5334 *line_number = line_id;