4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/queue.h>
37 #include <netinet/in.h>
39 #include <rte_common.h>
40 #include <rte_hexdump.h>
41 #include <rte_malloc.h>
42 #include <cmdline_rdline.h>
43 #include <cmdline_parse.h>
44 #include <cmdline_parse_num.h>
45 #include <cmdline_parse_string.h>
46 #include <cmdline_parse_ipaddr.h>
47 #include <cmdline_parse_etheraddr.h>
50 #include "pipeline_common_fe.h"
51 #include "pipeline_flow_classification.h"
52 #include "hash_func.h"
59 uint16_t ethertype_svlan;
61 uint16_t ethertype_cvlan;
63 } __attribute__((__packed__));
65 struct pkt_key_ipv4_5tuple {
73 } __attribute__((__packed__));
75 struct pkt_key_ipv6_5tuple {
76 uint16_t payload_length;
83 } __attribute__((__packed__));
86 app_pipeline_fc_key_convert(struct pipeline_fc_key *key_in,
90 uint8_t buffer[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
91 void *key_buffer = (key_out) ? key_out : buffer;
93 switch (key_in->type) {
96 struct pkt_key_qinq *qinq = key_buffer;
98 qinq->ethertype_svlan = 0;
99 qinq->svlan = rte_bswap16(key_in->key.qinq.svlan);
100 qinq->ethertype_cvlan = 0;
101 qinq->cvlan = rte_bswap16(key_in->key.qinq.cvlan);
104 *signature = (uint32_t) hash_default_key8(qinq, 8, 0);
108 case FLOW_KEY_IPV4_5TUPLE:
110 struct pkt_key_ipv4_5tuple *ipv4 = key_buffer;
113 ipv4->proto = key_in->key.ipv4_5tuple.proto;
115 ipv4->ip_src = rte_bswap32(key_in->key.ipv4_5tuple.ip_src);
116 ipv4->ip_dst = rte_bswap32(key_in->key.ipv4_5tuple.ip_dst);
117 ipv4->port_src = rte_bswap16(key_in->key.ipv4_5tuple.port_src);
118 ipv4->port_dst = rte_bswap16(key_in->key.ipv4_5tuple.port_dst);
121 *signature = (uint32_t) hash_default_key16(ipv4, 16, 0);
125 case FLOW_KEY_IPV6_5TUPLE:
127 struct pkt_key_ipv6_5tuple *ipv6 = key_buffer;
130 ipv6->payload_length = 0;
131 ipv6->proto = key_in->key.ipv6_5tuple.proto;
133 memcpy(&ipv6->ip_src, &key_in->key.ipv6_5tuple.ip_src, 16);
134 memcpy(&ipv6->ip_dst, &key_in->key.ipv6_5tuple.ip_dst, 16);
135 ipv6->port_src = rte_bswap16(key_in->key.ipv6_5tuple.port_src);
136 ipv6->port_dst = rte_bswap16(key_in->key.ipv6_5tuple.port_dst);
139 *signature = (uint32_t) hash_default_key64(ipv6, 64, 0);
149 * Flow classification pipeline
152 struct app_pipeline_fc_flow {
153 struct pipeline_fc_key key;
159 TAILQ_ENTRY(app_pipeline_fc_flow) node;
162 #define N_BUCKETS 65536
164 struct app_pipeline_fc {
167 uint32_t n_ports_out;
170 TAILQ_HEAD(, app_pipeline_fc_flow) flows[N_BUCKETS];
174 uint32_t default_flow_present;
175 uint32_t default_flow_port_id;
176 void *default_flow_entry_ptr;
179 static struct app_pipeline_fc_flow *
180 app_pipeline_fc_flow_find(struct app_pipeline_fc *p,
181 struct pipeline_fc_key *key)
183 struct app_pipeline_fc_flow *f;
184 uint32_t signature, bucket_id;
186 app_pipeline_fc_key_convert(key, NULL, &signature);
187 bucket_id = signature & (N_BUCKETS - 1);
189 TAILQ_FOREACH(f, &p->flows[bucket_id], node)
190 if ((signature == f->signature) &&
193 sizeof(struct pipeline_fc_key)) == 0))
200 app_pipeline_fc_init(struct pipeline_params *params,
201 __rte_unused void *arg)
203 struct app_pipeline_fc *p;
206 /* Check input arguments */
207 if ((params == NULL) ||
208 (params->n_ports_in == 0) ||
209 (params->n_ports_out == 0))
212 /* Memory allocation */
213 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_fc));
214 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
219 p->n_ports_in = params->n_ports_in;
220 p->n_ports_out = params->n_ports_out;
222 for (i = 0; i < N_BUCKETS; i++)
223 TAILQ_INIT(&p->flows[i]);
230 app_pipeline_fc_free(void *pipeline)
232 struct app_pipeline_fc *p = pipeline;
235 /* Check input arguments */
240 for (i = 0; i < N_BUCKETS; i++)
241 while (!TAILQ_EMPTY(&p->flows[i])) {
242 struct app_pipeline_fc_flow *flow;
244 flow = TAILQ_FIRST(&p->flows[i]);
245 TAILQ_REMOVE(&p->flows[i], flow, node);
254 app_pipeline_fc_key_check(struct pipeline_fc_key *key)
259 uint16_t svlan = key->key.qinq.svlan;
260 uint16_t cvlan = key->key.qinq.cvlan;
262 if ((svlan & 0xF000) ||
269 case FLOW_KEY_IPV4_5TUPLE:
272 case FLOW_KEY_IPV6_5TUPLE:
281 app_pipeline_fc_add(struct app_params *app,
282 uint32_t pipeline_id,
283 struct pipeline_fc_key *key,
287 struct app_pipeline_fc *p;
288 struct app_pipeline_fc_flow *flow;
290 struct pipeline_fc_add_msg_req *req;
291 struct pipeline_fc_add_msg_rsp *rsp;
296 /* Check input arguments */
301 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
305 if (port_id >= p->n_ports_out)
308 if (app_pipeline_fc_key_check(key) != 0)
311 /* Find existing flow or allocate new flow */
312 flow = app_pipeline_fc_flow_find(p, key);
313 new_flow = (flow == NULL);
315 flow = rte_malloc(NULL, sizeof(*flow), RTE_CACHE_LINE_SIZE);
321 /* Allocate and write request */
322 req = app_msg_alloc(app);
326 req->type = PIPELINE_MSG_REQ_CUSTOM;
327 req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD;
328 app_pipeline_fc_key_convert(key, req->key, &signature);
329 req->port_id = port_id;
330 req->flow_id = flow_id;
332 /* Send request and wait for response */
333 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
340 /* Read response and write flow */
342 (rsp->entry_ptr == NULL) ||
343 ((new_flow == 0) && (rsp->key_found == 0)) ||
344 ((new_flow == 1) && (rsp->key_found == 1))) {
345 app_msg_free(app, rsp);
351 memset(&flow->key, 0, sizeof(flow->key));
352 memcpy(&flow->key, key, sizeof(flow->key));
353 flow->port_id = port_id;
354 flow->flow_id = flow_id;
355 flow->signature = signature;
356 flow->entry_ptr = rsp->entry_ptr;
360 uint32_t bucket_id = signature & (N_BUCKETS - 1);
362 TAILQ_INSERT_TAIL(&p->flows[bucket_id], flow, node);
367 app_msg_free(app, rsp);
373 app_pipeline_fc_add_bulk(struct app_params *app,
374 uint32_t pipeline_id,
375 struct pipeline_fc_key *key,
380 struct app_pipeline_fc *p;
381 struct pipeline_fc_add_bulk_msg_req *req;
382 struct pipeline_fc_add_bulk_msg_rsp *rsp;
384 struct app_pipeline_fc_flow **flow;
387 struct pipeline_fc_add_bulk_flow_req *flow_req;
388 struct pipeline_fc_add_bulk_flow_rsp *flow_rsp;
393 /* Check input arguments */
401 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
405 for (i = 0; i < n_keys; i++)
406 if (port_id[i] >= p->n_ports_out)
409 for (i = 0; i < n_keys; i++)
410 if (app_pipeline_fc_key_check(&key[i]) != 0)
413 /* Memory allocation */
414 flow = rte_malloc(NULL,
415 n_keys * sizeof(struct app_pipeline_fc_flow *),
416 RTE_CACHE_LINE_SIZE);
420 signature = rte_malloc(NULL,
421 n_keys * sizeof(uint32_t),
422 RTE_CACHE_LINE_SIZE);
423 if (signature == NULL) {
428 new_flow = rte_malloc(
430 n_keys * sizeof(int),
431 RTE_CACHE_LINE_SIZE);
432 if (new_flow == NULL) {
438 flow_req = rte_malloc(NULL,
439 n_keys * sizeof(struct pipeline_fc_add_bulk_flow_req),
440 RTE_CACHE_LINE_SIZE);
441 if (flow_req == NULL) {
448 flow_rsp = rte_malloc(NULL,
449 n_keys * sizeof(struct pipeline_fc_add_bulk_flow_rsp),
450 RTE_CACHE_LINE_SIZE);
451 if (flow_rsp == NULL) {
459 /* Find existing flow or allocate new flow */
460 for (i = 0; i < n_keys; i++) {
461 flow[i] = app_pipeline_fc_flow_find(p, &key[i]);
462 new_flow[i] = (flow[i] == NULL);
463 if (flow[i] == NULL) {
464 flow[i] = rte_zmalloc(NULL,
465 sizeof(struct app_pipeline_fc_flow),
466 RTE_CACHE_LINE_SIZE);
468 if (flow[i] == NULL) {
471 for (j = 0; j < i; j++)
485 /* Allocate and write request */
486 req = app_msg_alloc(app);
488 for (i = 0; i < n_keys; i++)
500 for (i = 0; i < n_keys; i++) {
501 app_pipeline_fc_key_convert(&key[i],
504 flow_req[i].port_id = port_id[i];
505 flow_req[i].flow_id = flow_id[i];
508 req->type = PIPELINE_MSG_REQ_CUSTOM;
509 req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD_BULK;
512 req->n_keys = n_keys;
514 /* Send request and wait for response */
515 rsp = app_msg_send_recv(app, pipeline_id, req, 10000);
517 for (i = 0; i < n_keys; i++)
532 for (i = 0; i < rsp->n_keys; i++)
533 if ((flow_rsp[i].entry_ptr == NULL) ||
534 ((new_flow[i] == 0) && (flow_rsp[i].key_found == 0)) ||
535 ((new_flow[i] == 1) && (flow_rsp[i].key_found == 1)))
538 if (rsp->n_keys < n_keys)
542 for (i = 0; i < rsp->n_keys; i++) {
543 memcpy(&flow[i]->key, &key[i], sizeof(flow[i]->key));
544 flow[i]->port_id = port_id[i];
545 flow[i]->flow_id = flow_id[i];
546 flow[i]->signature = signature[i];
547 flow[i]->entry_ptr = flow_rsp[i].entry_ptr;
550 uint32_t bucket_id = signature[i] & (N_BUCKETS - 1);
552 TAILQ_INSERT_TAIL(&p->flows[bucket_id], flow[i], node);
558 app_msg_free(app, rsp);
560 for (i = rsp->n_keys; i < n_keys; i++)
574 app_pipeline_fc_del(struct app_params *app,
575 uint32_t pipeline_id,
576 struct pipeline_fc_key *key)
578 struct app_pipeline_fc *p;
579 struct app_pipeline_fc_flow *flow;
581 struct pipeline_fc_del_msg_req *req;
582 struct pipeline_fc_del_msg_rsp *rsp;
584 uint32_t signature, bucket_id;
586 /* Check input arguments */
591 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
595 if (app_pipeline_fc_key_check(key) != 0)
599 flow = app_pipeline_fc_flow_find(p, key);
603 /* Allocate and write request */
604 req = app_msg_alloc(app);
608 req->type = PIPELINE_MSG_REQ_CUSTOM;
609 req->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL;
610 app_pipeline_fc_key_convert(key, req->key, &signature);
612 /* Send request and wait for response */
613 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
618 if (rsp->status || !rsp->key_found) {
619 app_msg_free(app, rsp);
624 bucket_id = signature & (N_BUCKETS - 1);
625 TAILQ_REMOVE(&p->flows[bucket_id], flow, node);
630 app_msg_free(app, rsp);
636 app_pipeline_fc_add_default(struct app_params *app,
637 uint32_t pipeline_id,
640 struct app_pipeline_fc *p;
642 struct pipeline_fc_add_default_msg_req *req;
643 struct pipeline_fc_add_default_msg_rsp *rsp;
645 /* Check input arguments */
649 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
653 if (port_id >= p->n_ports_out)
656 /* Allocate and write request */
657 req = app_msg_alloc(app);
661 req->type = PIPELINE_MSG_REQ_CUSTOM;
662 req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT;
663 req->port_id = port_id;
665 /* Send request and wait for response */
666 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
670 /* Read response and write flow */
671 if (rsp->status || (rsp->entry_ptr == NULL)) {
672 app_msg_free(app, rsp);
676 p->default_flow_port_id = port_id;
677 p->default_flow_entry_ptr = rsp->entry_ptr;
680 p->default_flow_present = 1;
683 app_msg_free(app, rsp);
689 app_pipeline_fc_del_default(struct app_params *app,
690 uint32_t pipeline_id)
692 struct app_pipeline_fc *p;
694 struct pipeline_fc_del_default_msg_req *req;
695 struct pipeline_fc_del_default_msg_rsp *rsp;
697 /* Check input arguments */
701 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
705 /* Allocate and write request */
706 req = app_msg_alloc(app);
710 req->type = PIPELINE_MSG_REQ_CUSTOM;
711 req->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT;
713 /* Send request and wait for response */
714 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
720 app_msg_free(app, rsp);
725 p->default_flow_present = 0;
728 app_msg_free(app, rsp);
738 print_fc_qinq_flow(struct app_pipeline_fc_flow *flow)
740 printf("(SVLAN = %" PRIu32 ", "
741 "CVLAN = %" PRIu32 ") => "
742 "Port = %" PRIu32 ", "
743 "Flow ID = %" PRIu32 ", "
744 "(signature = 0x%08" PRIx32 ", "
747 flow->key.key.qinq.svlan,
748 flow->key.key.qinq.cvlan,
756 print_fc_ipv4_5tuple_flow(struct app_pipeline_fc_flow *flow)
758 printf("(SA = %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ", "
759 "DA = %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ", "
762 "Proto = %" PRIu32 ") => "
763 "Port = %" PRIu32 ", "
764 "Flow ID = %" PRIu32 " "
765 "(signature = 0x%08" PRIx32 ", "
768 (flow->key.key.ipv4_5tuple.ip_src >> 24) & 0xFF,
769 (flow->key.key.ipv4_5tuple.ip_src >> 16) & 0xFF,
770 (flow->key.key.ipv4_5tuple.ip_src >> 8) & 0xFF,
771 flow->key.key.ipv4_5tuple.ip_src & 0xFF,
773 (flow->key.key.ipv4_5tuple.ip_dst >> 24) & 0xFF,
774 (flow->key.key.ipv4_5tuple.ip_dst >> 16) & 0xFF,
775 (flow->key.key.ipv4_5tuple.ip_dst >> 8) & 0xFF,
776 flow->key.key.ipv4_5tuple.ip_dst & 0xFF,
778 flow->key.key.ipv4_5tuple.port_src,
779 flow->key.key.ipv4_5tuple.port_dst,
781 flow->key.key.ipv4_5tuple.proto,
790 print_fc_ipv6_5tuple_flow(struct app_pipeline_fc_flow *flow) {
791 printf("(SA = %02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
792 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
793 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
794 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32 ", "
795 "DA = %02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
796 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
797 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
798 ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32 ", "
801 "Proto = %" PRIu32 " "
802 "=> Port = %" PRIu32 ", "
803 "Flow ID = %" PRIu32 " "
804 "(signature = 0x%08" PRIx32 ", "
807 flow->key.key.ipv6_5tuple.ip_src[0],
808 flow->key.key.ipv6_5tuple.ip_src[1],
809 flow->key.key.ipv6_5tuple.ip_src[2],
810 flow->key.key.ipv6_5tuple.ip_src[3],
811 flow->key.key.ipv6_5tuple.ip_src[4],
812 flow->key.key.ipv6_5tuple.ip_src[5],
813 flow->key.key.ipv6_5tuple.ip_src[6],
814 flow->key.key.ipv6_5tuple.ip_src[7],
815 flow->key.key.ipv6_5tuple.ip_src[8],
816 flow->key.key.ipv6_5tuple.ip_src[9],
817 flow->key.key.ipv6_5tuple.ip_src[10],
818 flow->key.key.ipv6_5tuple.ip_src[11],
819 flow->key.key.ipv6_5tuple.ip_src[12],
820 flow->key.key.ipv6_5tuple.ip_src[13],
821 flow->key.key.ipv6_5tuple.ip_src[14],
822 flow->key.key.ipv6_5tuple.ip_src[15],
824 flow->key.key.ipv6_5tuple.ip_dst[0],
825 flow->key.key.ipv6_5tuple.ip_dst[1],
826 flow->key.key.ipv6_5tuple.ip_dst[2],
827 flow->key.key.ipv6_5tuple.ip_dst[3],
828 flow->key.key.ipv6_5tuple.ip_dst[4],
829 flow->key.key.ipv6_5tuple.ip_dst[5],
830 flow->key.key.ipv6_5tuple.ip_dst[6],
831 flow->key.key.ipv6_5tuple.ip_dst[7],
832 flow->key.key.ipv6_5tuple.ip_dst[8],
833 flow->key.key.ipv6_5tuple.ip_dst[9],
834 flow->key.key.ipv6_5tuple.ip_dst[10],
835 flow->key.key.ipv6_5tuple.ip_dst[11],
836 flow->key.key.ipv6_5tuple.ip_dst[12],
837 flow->key.key.ipv6_5tuple.ip_dst[13],
838 flow->key.key.ipv6_5tuple.ip_dst[14],
839 flow->key.key.ipv6_5tuple.ip_dst[15],
841 flow->key.key.ipv6_5tuple.port_src,
842 flow->key.key.ipv6_5tuple.port_dst,
844 flow->key.key.ipv6_5tuple.proto,
853 print_fc_flow(struct app_pipeline_fc_flow *flow)
855 switch (flow->key.type) {
857 print_fc_qinq_flow(flow);
860 case FLOW_KEY_IPV4_5TUPLE:
861 print_fc_ipv4_5tuple_flow(flow);
864 case FLOW_KEY_IPV6_5TUPLE:
865 print_fc_ipv6_5tuple_flow(flow);
871 app_pipeline_fc_ls(struct app_params *app,
872 uint32_t pipeline_id)
874 struct app_pipeline_fc *p;
875 struct app_pipeline_fc_flow *flow;
878 /* Check input arguments */
882 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
886 for (i = 0; i < N_BUCKETS; i++)
887 TAILQ_FOREACH(flow, &p->flows[i], node)
890 if (p->default_flow_present)
891 printf("Default flow: port %" PRIu32 " (entry ptr = %p)\n",
892 p->default_flow_port_id,
893 p->default_flow_entry_ptr);
895 printf("Default: DROP\n");
904 struct cmd_fc_add_qinq_result {
905 cmdline_fixed_string_t p_string;
906 uint32_t pipeline_id;
907 cmdline_fixed_string_t flow_string;
908 cmdline_fixed_string_t add_string;
909 cmdline_fixed_string_t qinq_string;
912 cmdline_fixed_string_t port_string;
914 cmdline_fixed_string_t flowid_string;
919 cmd_fc_add_qinq_parsed(
921 __rte_unused struct cmdline *cl,
924 struct cmd_fc_add_qinq_result *params = parsed_result;
925 struct app_params *app = data;
926 struct pipeline_fc_key key;
929 memset(&key, 0, sizeof(key));
930 key.type = FLOW_KEY_QINQ;
931 key.key.qinq.svlan = params->svlan;
932 key.key.qinq.cvlan = params->cvlan;
934 status = app_pipeline_fc_add(app,
940 printf("Command failed\n");
943 cmdline_parse_token_string_t cmd_fc_add_qinq_p_string =
944 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, p_string, "p");
946 cmdline_parse_token_num_t cmd_fc_add_qinq_pipeline_id =
947 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, pipeline_id,
950 cmdline_parse_token_string_t cmd_fc_add_qinq_flow_string =
951 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, flow_string,
954 cmdline_parse_token_string_t cmd_fc_add_qinq_add_string =
955 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, add_string,
958 cmdline_parse_token_string_t cmd_fc_add_qinq_qinq_string =
959 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, qinq_string,
962 cmdline_parse_token_num_t cmd_fc_add_qinq_svlan =
963 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, svlan, UINT16);
965 cmdline_parse_token_num_t cmd_fc_add_qinq_cvlan =
966 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, cvlan, UINT16);
968 cmdline_parse_token_string_t cmd_fc_add_qinq_port_string =
969 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, port_string,
972 cmdline_parse_token_num_t cmd_fc_add_qinq_port =
973 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, port, UINT32);
975 cmdline_parse_token_string_t cmd_fc_add_qinq_flowid_string =
976 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, flowid_string,
979 cmdline_parse_token_num_t cmd_fc_add_qinq_flow_id =
980 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, flow_id, UINT32);
982 cmdline_parse_inst_t cmd_fc_add_qinq = {
983 .f = cmd_fc_add_qinq_parsed,
985 .help_str = "Flow add (Q-in-Q)",
987 (void *) &cmd_fc_add_qinq_p_string,
988 (void *) &cmd_fc_add_qinq_pipeline_id,
989 (void *) &cmd_fc_add_qinq_flow_string,
990 (void *) &cmd_fc_add_qinq_add_string,
991 (void *) &cmd_fc_add_qinq_qinq_string,
992 (void *) &cmd_fc_add_qinq_svlan,
993 (void *) &cmd_fc_add_qinq_cvlan,
994 (void *) &cmd_fc_add_qinq_port_string,
995 (void *) &cmd_fc_add_qinq_port,
996 (void *) &cmd_fc_add_qinq_flowid_string,
997 (void *) &cmd_fc_add_qinq_flow_id,
1006 struct cmd_fc_add_qinq_all_result {
1007 cmdline_fixed_string_t p_string;
1008 uint32_t pipeline_id;
1009 cmdline_fixed_string_t flow_string;
1010 cmdline_fixed_string_t add_string;
1011 cmdline_fixed_string_t qinq_string;
1012 cmdline_fixed_string_t all_string;
1017 #ifndef N_FLOWS_BULK
1018 #define N_FLOWS_BULK 4096
1022 cmd_fc_add_qinq_all_parsed(
1023 void *parsed_result,
1024 __rte_unused struct cmdline *cl,
1027 struct cmd_fc_add_qinq_all_result *params = parsed_result;
1028 struct app_params *app = data;
1029 struct pipeline_fc_key *key;
1034 /* Check input arguments */
1035 if (params->n_flows == 0) {
1036 printf("Invalid number of flows\n");
1040 if (params->n_ports == 0) {
1041 printf("Invalid number of output ports\n");
1045 /* Memory allocation */
1046 key = rte_zmalloc(NULL,
1047 N_FLOWS_BULK * sizeof(*key),
1048 RTE_CACHE_LINE_SIZE);
1050 printf("Memory allocation failed\n");
1054 port_id = rte_malloc(NULL,
1055 N_FLOWS_BULK * sizeof(*port_id),
1056 RTE_CACHE_LINE_SIZE);
1057 if (port_id == NULL) {
1059 printf("Memory allocation failed\n");
1063 flow_id = rte_malloc(NULL,
1064 N_FLOWS_BULK * sizeof(*flow_id),
1065 RTE_CACHE_LINE_SIZE);
1066 if (flow_id == NULL) {
1069 printf("Memory allocation failed\n");
1074 for (id = 0; id < params->n_flows; id++) {
1075 uint32_t pos = id & (N_FLOWS_BULK - 1);
1077 key[pos].type = FLOW_KEY_QINQ;
1078 key[pos].key.qinq.svlan = id >> 12;
1079 key[pos].key.qinq.cvlan = id & 0xFFF;
1081 port_id[pos] = id % params->n_ports;
1084 if ((pos == N_FLOWS_BULK - 1) ||
1085 (id == params->n_flows - 1)) {
1088 status = app_pipeline_fc_add_bulk(app,
1089 params->pipeline_id,
1096 printf("Command failed\n");
1109 cmdline_parse_token_string_t cmd_fc_add_qinq_all_p_string =
1110 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_all_result, p_string,
1113 cmdline_parse_token_num_t cmd_fc_add_qinq_all_pipeline_id =
1114 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_all_result, pipeline_id,
1117 cmdline_parse_token_string_t cmd_fc_add_qinq_all_flow_string =
1118 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_all_result, flow_string,
1121 cmdline_parse_token_string_t cmd_fc_add_qinq_all_add_string =
1122 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_all_result, add_string,
1125 cmdline_parse_token_string_t cmd_fc_add_qinq_all_qinq_string =
1126 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_all_result, qinq_string,
1129 cmdline_parse_token_string_t cmd_fc_add_qinq_all_all_string =
1130 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_all_result, all_string,
1133 cmdline_parse_token_num_t cmd_fc_add_qinq_all_n_flows =
1134 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_all_result, n_flows,
1137 cmdline_parse_token_num_t cmd_fc_add_qinq_all_n_ports =
1138 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_all_result, n_ports,
1141 cmdline_parse_inst_t cmd_fc_add_qinq_all = {
1142 .f = cmd_fc_add_qinq_all_parsed,
1144 .help_str = "Flow add all (Q-in-Q)",
1146 (void *) &cmd_fc_add_qinq_all_p_string,
1147 (void *) &cmd_fc_add_qinq_all_pipeline_id,
1148 (void *) &cmd_fc_add_qinq_all_flow_string,
1149 (void *) &cmd_fc_add_qinq_all_add_string,
1150 (void *) &cmd_fc_add_qinq_all_qinq_string,
1151 (void *) &cmd_fc_add_qinq_all_all_string,
1152 (void *) &cmd_fc_add_qinq_all_n_flows,
1153 (void *) &cmd_fc_add_qinq_all_n_ports,
1159 * flow add ipv4_5tuple
1162 struct cmd_fc_add_ipv4_5tuple_result {
1163 cmdline_fixed_string_t p_string;
1164 uint32_t pipeline_id;
1165 cmdline_fixed_string_t flow_string;
1166 cmdline_fixed_string_t add_string;
1167 cmdline_fixed_string_t ipv4_5tuple_string;
1168 cmdline_ipaddr_t ip_src;
1169 cmdline_ipaddr_t ip_dst;
1173 cmdline_fixed_string_t port_string;
1175 cmdline_fixed_string_t flowid_string;
1180 cmd_fc_add_ipv4_5tuple_parsed(
1181 void *parsed_result,
1182 __rte_unused struct cmdline *cl,
1185 struct cmd_fc_add_ipv4_5tuple_result *params = parsed_result;
1186 struct app_params *app = data;
1187 struct pipeline_fc_key key;
1190 memset(&key, 0, sizeof(key));
1191 key.type = FLOW_KEY_IPV4_5TUPLE;
1192 key.key.ipv4_5tuple.ip_src = rte_bswap32(
1193 params->ip_src.addr.ipv4.s_addr);
1194 key.key.ipv4_5tuple.ip_dst = rte_bswap32(
1195 params->ip_dst.addr.ipv4.s_addr);
1196 key.key.ipv4_5tuple.port_src = params->port_src;
1197 key.key.ipv4_5tuple.port_dst = params->port_dst;
1198 key.key.ipv4_5tuple.proto = params->proto;
1200 status = app_pipeline_fc_add(app,
1201 params->pipeline_id,
1206 printf("Command failed\n");
1209 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_p_string =
1210 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, p_string,
1213 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_pipeline_id =
1214 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, pipeline_id,
1217 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_flow_string =
1218 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result,
1219 flow_string, "flow");
1221 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_add_string =
1222 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result,
1225 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_ipv4_5tuple_string =
1226 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result,
1227 ipv4_5tuple_string, "ipv4_5tuple");
1229 cmdline_parse_token_ipaddr_t cmd_fc_add_ipv4_5tuple_ip_src =
1230 TOKEN_IPV4_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, ip_src);
1232 cmdline_parse_token_ipaddr_t cmd_fc_add_ipv4_5tuple_ip_dst =
1233 TOKEN_IPV4_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, ip_dst);
1235 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port_src =
1236 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_src,
1239 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port_dst =
1240 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_dst,
1243 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_proto =
1244 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, proto,
1247 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_port_string =
1248 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_string,
1251 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port =
1252 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port,
1255 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_flowid_string =
1256 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result,
1257 flowid_string, "flowid");
1259 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_flow_id =
1260 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, flow_id,
1263 cmdline_parse_inst_t cmd_fc_add_ipv4_5tuple = {
1264 .f = cmd_fc_add_ipv4_5tuple_parsed,
1266 .help_str = "Flow add (IPv4 5-tuple)",
1268 (void *) &cmd_fc_add_ipv4_5tuple_p_string,
1269 (void *) &cmd_fc_add_ipv4_5tuple_pipeline_id,
1270 (void *) &cmd_fc_add_ipv4_5tuple_flow_string,
1271 (void *) &cmd_fc_add_ipv4_5tuple_add_string,
1272 (void *) &cmd_fc_add_ipv4_5tuple_ipv4_5tuple_string,
1273 (void *) &cmd_fc_add_ipv4_5tuple_ip_src,
1274 (void *) &cmd_fc_add_ipv4_5tuple_ip_dst,
1275 (void *) &cmd_fc_add_ipv4_5tuple_port_src,
1276 (void *) &cmd_fc_add_ipv4_5tuple_port_dst,
1277 (void *) &cmd_fc_add_ipv4_5tuple_proto,
1278 (void *) &cmd_fc_add_ipv4_5tuple_port_string,
1279 (void *) &cmd_fc_add_ipv4_5tuple_port,
1280 (void *) &cmd_fc_add_ipv4_5tuple_flowid_string,
1281 (void *) &cmd_fc_add_ipv4_5tuple_flow_id,
1287 * flow add ipv4_5tuple all
1290 struct cmd_fc_add_ipv4_5tuple_all_result {
1291 cmdline_fixed_string_t p_string;
1292 uint32_t pipeline_id;
1293 cmdline_fixed_string_t flow_string;
1294 cmdline_fixed_string_t add_string;
1295 cmdline_fixed_string_t ipv4_5tuple_string;
1296 cmdline_fixed_string_t all_string;
1302 cmd_fc_add_ipv4_5tuple_all_parsed(
1303 void *parsed_result,
1304 __rte_unused struct cmdline *cl,
1307 struct cmd_fc_add_ipv4_5tuple_all_result *params = parsed_result;
1308 struct app_params *app = data;
1309 struct pipeline_fc_key *key;
1314 /* Check input parameters */
1315 if (params->n_flows == 0) {
1316 printf("Invalid number of flows\n");
1320 if (params->n_ports == 0) {
1321 printf("Invalid number of ports\n");
1325 /* Memory allocation */
1326 key = rte_zmalloc(NULL,
1327 N_FLOWS_BULK * sizeof(*key),
1328 RTE_CACHE_LINE_SIZE);
1330 printf("Memory allocation failed\n");
1334 port_id = rte_malloc(NULL,
1335 N_FLOWS_BULK * sizeof(*port_id),
1336 RTE_CACHE_LINE_SIZE);
1337 if (port_id == NULL) {
1339 printf("Memory allocation failed\n");
1343 flow_id = rte_malloc(NULL,
1344 N_FLOWS_BULK * sizeof(*flow_id),
1345 RTE_CACHE_LINE_SIZE);
1346 if (flow_id == NULL) {
1349 printf("Memory allocation failed\n");
1354 for (id = 0; id < params->n_flows; id++) {
1355 uint32_t pos = id & (N_FLOWS_BULK - 1);
1357 key[pos].type = FLOW_KEY_IPV4_5TUPLE;
1358 key[pos].key.ipv4_5tuple.ip_src = 0;
1359 key[pos].key.ipv4_5tuple.ip_dst = id;
1360 key[pos].key.ipv4_5tuple.port_src = 0;
1361 key[pos].key.ipv4_5tuple.port_dst = 0;
1362 key[pos].key.ipv4_5tuple.proto = 6;
1364 port_id[pos] = id % params->n_ports;
1367 if ((pos == N_FLOWS_BULK - 1) ||
1368 (id == params->n_flows - 1)) {
1371 status = app_pipeline_fc_add_bulk(app,
1372 params->pipeline_id,
1379 printf("Command failed\n");
1392 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_all_p_string =
1393 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1396 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_all_pipeline_id =
1397 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1398 pipeline_id, UINT32);
1400 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_all_flow_string =
1401 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1402 flow_string, "flow");
1404 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_all_add_string =
1405 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1408 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_all_ipv4_5tuple_string =
1409 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1410 ipv4_5tuple_string, "ipv4_5tuple");
1412 cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_all_all_string =
1413 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1416 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_all_n_flows =
1417 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1420 cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_all_n_ports =
1421 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_all_result,
1424 cmdline_parse_inst_t cmd_fc_add_ipv4_5tuple_all = {
1425 .f = cmd_fc_add_ipv4_5tuple_all_parsed,
1427 .help_str = "Flow add all (IPv4 5-tuple)",
1429 (void *) &cmd_fc_add_ipv4_5tuple_all_p_string,
1430 (void *) &cmd_fc_add_ipv4_5tuple_all_pipeline_id,
1431 (void *) &cmd_fc_add_ipv4_5tuple_all_flow_string,
1432 (void *) &cmd_fc_add_ipv4_5tuple_all_add_string,
1433 (void *) &cmd_fc_add_ipv4_5tuple_all_ipv4_5tuple_string,
1434 (void *) &cmd_fc_add_ipv4_5tuple_all_all_string,
1435 (void *) &cmd_fc_add_ipv4_5tuple_all_n_flows,
1436 (void *) &cmd_fc_add_ipv4_5tuple_all_n_ports,
1442 * flow add ipv6_5tuple
1445 struct cmd_fc_add_ipv6_5tuple_result {
1446 cmdline_fixed_string_t p_string;
1447 uint32_t pipeline_id;
1448 cmdline_fixed_string_t flow_string;
1449 cmdline_fixed_string_t add_string;
1450 cmdline_fixed_string_t ipv6_5tuple_string;
1451 cmdline_ipaddr_t ip_src;
1452 cmdline_ipaddr_t ip_dst;
1456 cmdline_fixed_string_t port_string;
1458 cmdline_fixed_string_t flowid_string;
1463 cmd_fc_add_ipv6_5tuple_parsed(
1464 void *parsed_result,
1465 __rte_unused struct cmdline *cl,
1468 struct cmd_fc_add_ipv6_5tuple_result *params = parsed_result;
1469 struct app_params *app = data;
1470 struct pipeline_fc_key key;
1473 memset(&key, 0, sizeof(key));
1474 key.type = FLOW_KEY_IPV6_5TUPLE;
1475 memcpy(key.key.ipv6_5tuple.ip_src,
1476 params->ip_src.addr.ipv6.s6_addr,
1478 memcpy(key.key.ipv6_5tuple.ip_dst,
1479 params->ip_dst.addr.ipv6.s6_addr,
1481 key.key.ipv6_5tuple.port_src = params->port_src;
1482 key.key.ipv6_5tuple.port_dst = params->port_dst;
1483 key.key.ipv6_5tuple.proto = params->proto;
1485 status = app_pipeline_fc_add(app,
1486 params->pipeline_id,
1491 printf("Command failed\n");
1494 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_p_string =
1495 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1498 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_pipeline_id =
1499 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, pipeline_id,
1502 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_flow_string =
1503 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1504 flow_string, "flow");
1506 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_add_string =
1507 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1510 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_ipv6_5tuple_string =
1511 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1512 ipv6_5tuple_string, "ipv6_5tuple");
1514 cmdline_parse_token_ipaddr_t cmd_fc_add_ipv6_5tuple_ip_src =
1515 TOKEN_IPV6_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, ip_src);
1517 cmdline_parse_token_ipaddr_t cmd_fc_add_ipv6_5tuple_ip_dst =
1518 TOKEN_IPV6_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, ip_dst);
1520 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port_src =
1521 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port_src,
1524 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port_dst =
1525 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port_dst,
1528 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_proto =
1529 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, proto,
1532 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_port_string =
1533 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1534 port_string, "port");
1536 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port =
1537 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port,
1540 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_flowid_string =
1541 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result,
1542 flowid_string, "flowid");
1544 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_flow_id =
1545 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, flow_id,
1548 cmdline_parse_inst_t cmd_fc_add_ipv6_5tuple = {
1549 .f = cmd_fc_add_ipv6_5tuple_parsed,
1551 .help_str = "Flow add (IPv6 5-tuple)",
1553 (void *) &cmd_fc_add_ipv6_5tuple_p_string,
1554 (void *) &cmd_fc_add_ipv6_5tuple_pipeline_id,
1555 (void *) &cmd_fc_add_ipv6_5tuple_flow_string,
1556 (void *) &cmd_fc_add_ipv6_5tuple_add_string,
1557 (void *) &cmd_fc_add_ipv6_5tuple_ipv6_5tuple_string,
1558 (void *) &cmd_fc_add_ipv6_5tuple_ip_src,
1559 (void *) &cmd_fc_add_ipv6_5tuple_ip_dst,
1560 (void *) &cmd_fc_add_ipv6_5tuple_port_src,
1561 (void *) &cmd_fc_add_ipv6_5tuple_port_dst,
1562 (void *) &cmd_fc_add_ipv6_5tuple_proto,
1563 (void *) &cmd_fc_add_ipv6_5tuple_port_string,
1564 (void *) &cmd_fc_add_ipv6_5tuple_port,
1565 (void *) &cmd_fc_add_ipv6_5tuple_flowid_string,
1566 (void *) &cmd_fc_add_ipv6_5tuple_flow_id,
1572 * flow add ipv6_5tuple all
1575 struct cmd_fc_add_ipv6_5tuple_all_result {
1576 cmdline_fixed_string_t p_string;
1577 uint32_t pipeline_id;
1578 cmdline_fixed_string_t flow_string;
1579 cmdline_fixed_string_t add_string;
1580 cmdline_fixed_string_t ipv6_5tuple_string;
1581 cmdline_fixed_string_t all_string;
1587 cmd_fc_add_ipv6_5tuple_all_parsed(
1588 void *parsed_result,
1589 __rte_unused struct cmdline *cl,
1592 struct cmd_fc_add_ipv6_5tuple_all_result *params = parsed_result;
1593 struct app_params *app = data;
1594 struct pipeline_fc_key *key;
1599 /* Check input parameters */
1600 if (params->n_flows == 0) {
1601 printf("Invalid number of flows\n");
1605 if (params->n_ports == 0) {
1606 printf("Invalid number of ports\n");
1610 /* Memory allocation */
1611 key = rte_zmalloc(NULL,
1612 N_FLOWS_BULK * sizeof(*key),
1613 RTE_CACHE_LINE_SIZE);
1615 printf("Memory allocation failed\n");
1619 port_id = rte_malloc(NULL,
1620 N_FLOWS_BULK * sizeof(*port_id),
1621 RTE_CACHE_LINE_SIZE);
1622 if (port_id == NULL) {
1624 printf("Memory allocation failed\n");
1628 flow_id = rte_malloc(NULL,
1629 N_FLOWS_BULK * sizeof(*flow_id),
1630 RTE_CACHE_LINE_SIZE);
1631 if (flow_id == NULL) {
1634 printf("Memory allocation failed\n");
1639 for (id = 0; id < params->n_flows; id++) {
1640 uint32_t pos = id & (N_FLOWS_BULK - 1);
1643 key[pos].type = FLOW_KEY_IPV6_5TUPLE;
1644 x = (uint32_t *) key[pos].key.ipv6_5tuple.ip_dst;
1645 *x = rte_bswap32(id);
1646 key[pos].key.ipv6_5tuple.proto = 6;
1648 port_id[pos] = id % params->n_ports;
1651 if ((pos == N_FLOWS_BULK - 1) ||
1652 (id == params->n_flows - 1)) {
1655 status = app_pipeline_fc_add_bulk(app,
1656 params->pipeline_id,
1663 printf("Command failed\n");
1676 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_all_p_string =
1677 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1680 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_all_pipeline_id =
1681 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1682 pipeline_id, UINT32);
1684 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_all_flow_string =
1685 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1686 flow_string, "flow");
1688 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_all_add_string =
1689 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1692 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_all_ipv6_5tuple_string =
1693 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1694 ipv6_5tuple_string, "ipv6_5tuple");
1696 cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_all_all_string =
1697 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1700 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_all_n_flows =
1701 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1704 cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_all_n_ports =
1705 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_all_result,
1708 cmdline_parse_inst_t cmd_fc_add_ipv6_5tuple_all = {
1709 .f = cmd_fc_add_ipv6_5tuple_all_parsed,
1711 .help_str = "Flow add all (ipv6 5-tuple)",
1713 (void *) &cmd_fc_add_ipv6_5tuple_all_p_string,
1714 (void *) &cmd_fc_add_ipv6_5tuple_all_pipeline_id,
1715 (void *) &cmd_fc_add_ipv6_5tuple_all_flow_string,
1716 (void *) &cmd_fc_add_ipv6_5tuple_all_add_string,
1717 (void *) &cmd_fc_add_ipv6_5tuple_all_ipv6_5tuple_string,
1718 (void *) &cmd_fc_add_ipv6_5tuple_all_all_string,
1719 (void *) &cmd_fc_add_ipv6_5tuple_all_n_flows,
1720 (void *) &cmd_fc_add_ipv6_5tuple_all_n_ports,
1728 struct cmd_fc_del_qinq_result {
1729 cmdline_fixed_string_t p_string;
1730 uint32_t pipeline_id;
1731 cmdline_fixed_string_t flow_string;
1732 cmdline_fixed_string_t del_string;
1733 cmdline_fixed_string_t qinq_string;
1739 cmd_fc_del_qinq_parsed(
1740 void *parsed_result,
1741 __rte_unused struct cmdline *cl,
1744 struct cmd_fc_del_qinq_result *params = parsed_result;
1745 struct app_params *app = data;
1746 struct pipeline_fc_key key;
1749 memset(&key, 0, sizeof(key));
1750 key.type = FLOW_KEY_QINQ;
1751 key.key.qinq.svlan = params->svlan;
1752 key.key.qinq.cvlan = params->cvlan;
1753 status = app_pipeline_fc_del(app, params->pipeline_id, &key);
1756 printf("Command failed\n");
1759 cmdline_parse_token_string_t cmd_fc_del_qinq_p_string =
1760 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, p_string, "p");
1762 cmdline_parse_token_num_t cmd_fc_del_qinq_pipeline_id =
1763 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, pipeline_id,
1766 cmdline_parse_token_string_t cmd_fc_del_qinq_flow_string =
1767 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, flow_string,
1770 cmdline_parse_token_string_t cmd_fc_del_qinq_del_string =
1771 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, del_string,
1774 cmdline_parse_token_string_t cmd_fc_del_qinq_qinq_string =
1775 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, qinq_string,
1778 cmdline_parse_token_num_t cmd_fc_del_qinq_svlan =
1779 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, svlan, UINT16);
1781 cmdline_parse_token_num_t cmd_fc_del_qinq_cvlan =
1782 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, cvlan, UINT16);
1784 cmdline_parse_inst_t cmd_fc_del_qinq = {
1785 .f = cmd_fc_del_qinq_parsed,
1787 .help_str = "Flow delete (Q-in-Q)",
1789 (void *) &cmd_fc_del_qinq_p_string,
1790 (void *) &cmd_fc_del_qinq_pipeline_id,
1791 (void *) &cmd_fc_del_qinq_flow_string,
1792 (void *) &cmd_fc_del_qinq_del_string,
1793 (void *) &cmd_fc_del_qinq_qinq_string,
1794 (void *) &cmd_fc_del_qinq_svlan,
1795 (void *) &cmd_fc_del_qinq_cvlan,
1801 * flow del ipv4_5tuple
1804 struct cmd_fc_del_ipv4_5tuple_result {
1805 cmdline_fixed_string_t p_string;
1806 uint32_t pipeline_id;
1807 cmdline_fixed_string_t flow_string;
1808 cmdline_fixed_string_t del_string;
1809 cmdline_fixed_string_t ipv4_5tuple_string;
1810 cmdline_ipaddr_t ip_src;
1811 cmdline_ipaddr_t ip_dst;
1818 cmd_fc_del_ipv4_5tuple_parsed(
1819 void *parsed_result,
1820 __rte_unused struct cmdline *cl,
1823 struct cmd_fc_del_ipv4_5tuple_result *params = parsed_result;
1824 struct app_params *app = data;
1825 struct pipeline_fc_key key;
1828 memset(&key, 0, sizeof(key));
1829 key.type = FLOW_KEY_IPV4_5TUPLE;
1830 key.key.ipv4_5tuple.ip_src = rte_bswap32(
1831 params->ip_src.addr.ipv4.s_addr);
1832 key.key.ipv4_5tuple.ip_dst = rte_bswap32(
1833 params->ip_dst.addr.ipv4.s_addr);
1834 key.key.ipv4_5tuple.port_src = params->port_src;
1835 key.key.ipv4_5tuple.port_dst = params->port_dst;
1836 key.key.ipv4_5tuple.proto = params->proto;
1838 status = app_pipeline_fc_del(app, params->pipeline_id, &key);
1840 printf("Command failed\n");
1843 cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_p_string =
1844 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1847 cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_pipeline_id =
1848 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1849 pipeline_id, UINT32);
1851 cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_flow_string =
1852 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1853 flow_string, "flow");
1855 cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_del_string =
1856 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1859 cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_ipv4_5tuple_string =
1860 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1861 ipv4_5tuple_string, "ipv4_5tuple");
1863 cmdline_parse_token_ipaddr_t cmd_fc_del_ipv4_5tuple_ip_src =
1864 TOKEN_IPV4_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1867 cmdline_parse_token_ipaddr_t cmd_fc_del_ipv4_5tuple_ip_dst =
1868 TOKEN_IPV4_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, ip_dst);
1870 cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_port_src =
1871 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1874 cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_port_dst =
1875 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1878 cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_proto =
1879 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result,
1882 cmdline_parse_inst_t cmd_fc_del_ipv4_5tuple = {
1883 .f = cmd_fc_del_ipv4_5tuple_parsed,
1885 .help_str = "Flow delete (IPv4 5-tuple)",
1887 (void *) &cmd_fc_del_ipv4_5tuple_p_string,
1888 (void *) &cmd_fc_del_ipv4_5tuple_pipeline_id,
1889 (void *) &cmd_fc_del_ipv4_5tuple_flow_string,
1890 (void *) &cmd_fc_del_ipv4_5tuple_del_string,
1891 (void *) &cmd_fc_del_ipv4_5tuple_ipv4_5tuple_string,
1892 (void *) &cmd_fc_del_ipv4_5tuple_ip_src,
1893 (void *) &cmd_fc_del_ipv4_5tuple_ip_dst,
1894 (void *) &cmd_fc_del_ipv4_5tuple_port_src,
1895 (void *) &cmd_fc_del_ipv4_5tuple_port_dst,
1896 (void *) &cmd_fc_del_ipv4_5tuple_proto,
1902 * flow del ipv6_5tuple
1905 struct cmd_fc_del_ipv6_5tuple_result {
1906 cmdline_fixed_string_t p_string;
1907 uint32_t pipeline_id;
1908 cmdline_fixed_string_t flow_string;
1909 cmdline_fixed_string_t del_string;
1910 cmdline_fixed_string_t ipv6_5tuple_string;
1911 cmdline_ipaddr_t ip_src;
1912 cmdline_ipaddr_t ip_dst;
1919 cmd_fc_del_ipv6_5tuple_parsed(
1920 void *parsed_result,
1921 __rte_unused struct cmdline *cl,
1924 struct cmd_fc_del_ipv6_5tuple_result *params = parsed_result;
1925 struct app_params *app = data;
1926 struct pipeline_fc_key key;
1929 memset(&key, 0, sizeof(key));
1930 key.type = FLOW_KEY_IPV6_5TUPLE;
1931 memcpy(key.key.ipv6_5tuple.ip_src,
1932 params->ip_src.addr.ipv6.s6_addr,
1934 memcpy(key.key.ipv6_5tuple.ip_dst,
1935 params->ip_dst.addr.ipv6.s6_addr,
1937 key.key.ipv6_5tuple.port_src = params->port_src;
1938 key.key.ipv6_5tuple.port_dst = params->port_dst;
1939 key.key.ipv6_5tuple.proto = params->proto;
1941 status = app_pipeline_fc_del(app, params->pipeline_id, &key);
1943 printf("Command failed\n");
1946 cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_p_string =
1947 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result,
1950 cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_pipeline_id =
1951 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result,
1952 pipeline_id, UINT32);
1954 cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_flow_string =
1955 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result,
1956 flow_string, "flow");
1958 cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_del_string =
1959 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result,
1962 cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_ipv6_5tuple_string =
1963 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result,
1964 ipv6_5tuple_string, "ipv6_5tuple");
1966 cmdline_parse_token_ipaddr_t cmd_fc_del_ipv6_5tuple_ip_src =
1967 TOKEN_IPV6_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, ip_src);
1969 cmdline_parse_token_ipaddr_t cmd_fc_del_ipv6_5tuple_ip_dst =
1970 TOKEN_IPV6_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, ip_dst);
1972 cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_port_src =
1973 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, port_src,
1976 cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_port_dst =
1977 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, port_dst,
1980 cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_proto =
1981 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, proto,
1984 cmdline_parse_inst_t cmd_fc_del_ipv6_5tuple = {
1985 .f = cmd_fc_del_ipv6_5tuple_parsed,
1987 .help_str = "Flow delete (IPv6 5-tuple)",
1989 (void *) &cmd_fc_del_ipv6_5tuple_p_string,
1990 (void *) &cmd_fc_del_ipv6_5tuple_pipeline_id,
1991 (void *) &cmd_fc_del_ipv6_5tuple_flow_string,
1992 (void *) &cmd_fc_del_ipv6_5tuple_del_string,
1993 (void *) &cmd_fc_del_ipv6_5tuple_ipv6_5tuple_string,
1994 (void *) &cmd_fc_del_ipv6_5tuple_ip_src,
1995 (void *) &cmd_fc_del_ipv6_5tuple_ip_dst,
1996 (void *) &cmd_fc_del_ipv6_5tuple_port_src,
1997 (void *) &cmd_fc_del_ipv6_5tuple_port_dst,
1998 (void *) &cmd_fc_del_ipv6_5tuple_proto,
2007 struct cmd_fc_add_default_result {
2008 cmdline_fixed_string_t p_string;
2009 uint32_t pipeline_id;
2010 cmdline_fixed_string_t flow_string;
2011 cmdline_fixed_string_t add_string;
2012 cmdline_fixed_string_t default_string;
2017 cmd_fc_add_default_parsed(
2018 void *parsed_result,
2019 __rte_unused struct cmdline *cl,
2022 struct cmd_fc_add_default_result *params = parsed_result;
2023 struct app_params *app = data;
2026 status = app_pipeline_fc_add_default(app, params->pipeline_id,
2030 printf("Command failed\n");
2033 cmdline_parse_token_string_t cmd_fc_add_default_p_string =
2034 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_result, p_string,
2037 cmdline_parse_token_num_t cmd_fc_add_default_pipeline_id =
2038 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_result, pipeline_id,
2041 cmdline_parse_token_string_t cmd_fc_add_default_flow_string =
2042 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_result, flow_string,
2045 cmdline_parse_token_string_t cmd_fc_add_default_add_string =
2046 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_result, add_string,
2049 cmdline_parse_token_string_t cmd_fc_add_default_default_string =
2050 TOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_result,
2051 default_string, "default");
2053 cmdline_parse_token_num_t cmd_fc_add_default_port =
2054 TOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_result, port, UINT32);
2056 cmdline_parse_inst_t cmd_fc_add_default = {
2057 .f = cmd_fc_add_default_parsed,
2059 .help_str = "Flow add default",
2061 (void *) &cmd_fc_add_default_p_string,
2062 (void *) &cmd_fc_add_default_pipeline_id,
2063 (void *) &cmd_fc_add_default_flow_string,
2064 (void *) &cmd_fc_add_default_add_string,
2065 (void *) &cmd_fc_add_default_default_string,
2066 (void *) &cmd_fc_add_default_port,
2075 struct cmd_fc_del_default_result {
2076 cmdline_fixed_string_t p_string;
2077 uint32_t pipeline_id;
2078 cmdline_fixed_string_t flow_string;
2079 cmdline_fixed_string_t del_string;
2080 cmdline_fixed_string_t default_string;
2084 cmd_fc_del_default_parsed(
2085 void *parsed_result,
2086 __rte_unused struct cmdline *cl,
2089 struct cmd_fc_del_default_result *params = parsed_result;
2090 struct app_params *app = data;
2093 status = app_pipeline_fc_del_default(app, params->pipeline_id);
2095 printf("Command failed\n");
2098 cmdline_parse_token_string_t cmd_fc_del_default_p_string =
2099 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_result, p_string,
2102 cmdline_parse_token_num_t cmd_fc_del_default_pipeline_id =
2103 TOKEN_NUM_INITIALIZER(struct cmd_fc_del_default_result, pipeline_id,
2106 cmdline_parse_token_string_t cmd_fc_del_default_flow_string =
2107 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_result, flow_string,
2110 cmdline_parse_token_string_t cmd_fc_del_default_del_string =
2111 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_result, del_string,
2114 cmdline_parse_token_string_t cmd_fc_del_default_default_string =
2115 TOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_result,
2116 default_string, "default");
2118 cmdline_parse_inst_t cmd_fc_del_default = {
2119 .f = cmd_fc_del_default_parsed,
2121 .help_str = "Flow delete default",
2123 (void *) &cmd_fc_del_default_p_string,
2124 (void *) &cmd_fc_del_default_pipeline_id,
2125 (void *) &cmd_fc_del_default_flow_string,
2126 (void *) &cmd_fc_del_default_del_string,
2127 (void *) &cmd_fc_del_default_default_string,
2136 struct cmd_fc_ls_result {
2137 cmdline_fixed_string_t p_string;
2138 uint32_t pipeline_id;
2139 cmdline_fixed_string_t flow_string;
2140 cmdline_fixed_string_t ls_string;
2145 void *parsed_result,
2146 __attribute__((unused)) struct cmdline *cl,
2149 struct cmd_fc_ls_result *params = parsed_result;
2150 struct app_params *app = data;
2153 status = app_pipeline_fc_ls(app, params->pipeline_id);
2155 printf("Command failed\n");
2158 cmdline_parse_token_string_t cmd_fc_ls_p_string =
2159 TOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result, p_string, "p");
2161 cmdline_parse_token_num_t cmd_fc_ls_pipeline_id =
2162 TOKEN_NUM_INITIALIZER(struct cmd_fc_ls_result, pipeline_id, UINT32);
2164 cmdline_parse_token_string_t cmd_fc_ls_flow_string =
2165 TOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result,
2166 flow_string, "flow");
2168 cmdline_parse_token_string_t cmd_fc_ls_ls_string =
2169 TOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result, ls_string,
2172 cmdline_parse_inst_t cmd_fc_ls = {
2173 .f = cmd_fc_ls_parsed,
2175 .help_str = "Flow list",
2177 (void *) &cmd_fc_ls_p_string,
2178 (void *) &cmd_fc_ls_pipeline_id,
2179 (void *) &cmd_fc_ls_flow_string,
2180 (void *) &cmd_fc_ls_ls_string,
2185 static cmdline_parse_ctx_t pipeline_cmds[] = {
2186 (cmdline_parse_inst_t *) &cmd_fc_add_qinq,
2187 (cmdline_parse_inst_t *) &cmd_fc_add_ipv4_5tuple,
2188 (cmdline_parse_inst_t *) &cmd_fc_add_ipv6_5tuple,
2190 (cmdline_parse_inst_t *) &cmd_fc_del_qinq,
2191 (cmdline_parse_inst_t *) &cmd_fc_del_ipv4_5tuple,
2192 (cmdline_parse_inst_t *) &cmd_fc_del_ipv6_5tuple,
2194 (cmdline_parse_inst_t *) &cmd_fc_add_default,
2195 (cmdline_parse_inst_t *) &cmd_fc_del_default,
2197 (cmdline_parse_inst_t *) &cmd_fc_add_qinq_all,
2198 (cmdline_parse_inst_t *) &cmd_fc_add_ipv4_5tuple_all,
2199 (cmdline_parse_inst_t *) &cmd_fc_add_ipv6_5tuple_all,
2201 (cmdline_parse_inst_t *) &cmd_fc_ls,
2205 static struct pipeline_fe_ops pipeline_flow_classification_fe_ops = {
2206 .f_init = app_pipeline_fc_init,
2207 .f_free = app_pipeline_fc_free,
2208 .cmds = pipeline_cmds,
2211 struct pipeline_type pipeline_flow_classification = {
2212 .name = "FLOW_CLASSIFICATION",
2213 .be_ops = &pipeline_flow_classification_be_ops,
2214 .fe_ops = &pipeline_flow_classification_fe_ops,