4 * Copyright(c) 2010-2016 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 <rte_common.h>
37 #include <rte_malloc.h>
38 #include <rte_byteorder.h>
39 #include <rte_table_stub.h>
40 #include <rte_table_hash.h>
41 #include <rte_pipeline.h>
43 #include "pipeline_passthrough_be.h"
44 #include "pipeline_actions_common.h"
46 #include "hash_func.h"
48 struct pipeline_passthrough {
50 struct pipeline_passthrough_params params;
51 rte_table_hash_op_hash f_hash;
52 } __rte_cache_aligned;
54 static pipeline_msg_req_handler handlers[] = {
55 [PIPELINE_MSG_REQ_PING] =
56 pipeline_msg_req_ping_handler,
57 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
58 pipeline_msg_req_stats_port_in_handler,
59 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
60 pipeline_msg_req_stats_port_out_handler,
61 [PIPELINE_MSG_REQ_STATS_TABLE] =
62 pipeline_msg_req_stats_table_handler,
63 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
64 pipeline_msg_req_port_in_enable_handler,
65 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
66 pipeline_msg_req_port_in_disable_handler,
67 [PIPELINE_MSG_REQ_CUSTOM] =
68 pipeline_msg_req_invalid_handler,
71 static inline __attribute__((always_inline)) void
76 uint32_t hash_enabled,
78 uint32_t port_out_pow2)
80 struct pipeline_passthrough *p = arg;
82 uint64_t *dma_dst = RTE_MBUF_METADATA_UINT64_PTR(pkt,
83 p->params.dma_dst_offset);
84 uint64_t *dma_src = RTE_MBUF_METADATA_UINT64_PTR(pkt,
85 p->params.dma_src_offset);
86 uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
87 uint32_t *dma_hash = RTE_MBUF_METADATA_UINT32_PTR(pkt,
88 p->params.dma_hash_offset);
91 /* Read (dma_src), compute (dma_dst), write (dma_dst) */
92 for (i = 0; i < (dma_size / 8); i++)
93 dma_dst[i] = dma_src[i] & dma_mask[i];
95 /* Read (dma_dst), compute (hash), write (hash) */
97 uint32_t hash = p->f_hash(dma_dst, dma_size, 0);
105 = hash & (p->p.n_ports_out - 1);
108 = hash % p->p.n_ports_out;
110 rte_pipeline_port_out_packet_insert(p->p.p,
116 static inline __attribute__((always_inline)) void
118 struct rte_mbuf **pkts,
121 uint32_t hash_enabled,
123 uint32_t port_out_pow2)
125 struct pipeline_passthrough *p = arg;
127 uint64_t *dma_dst0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
128 p->params.dma_dst_offset);
129 uint64_t *dma_dst1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
130 p->params.dma_dst_offset);
131 uint64_t *dma_dst2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
132 p->params.dma_dst_offset);
133 uint64_t *dma_dst3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
134 p->params.dma_dst_offset);
136 uint64_t *dma_src0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
137 p->params.dma_src_offset);
138 uint64_t *dma_src1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
139 p->params.dma_src_offset);
140 uint64_t *dma_src2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
141 p->params.dma_src_offset);
142 uint64_t *dma_src3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
143 p->params.dma_src_offset);
145 uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
147 uint32_t *dma_hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkts[0],
148 p->params.dma_hash_offset);
149 uint32_t *dma_hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkts[1],
150 p->params.dma_hash_offset);
151 uint32_t *dma_hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkts[2],
152 p->params.dma_hash_offset);
153 uint32_t *dma_hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkts[3],
154 p->params.dma_hash_offset);
158 /* Read (dma_src), compute (dma_dst), write (dma_dst) */
159 for (i = 0; i < (dma_size / 8); i++) {
160 dma_dst0[i] = dma_src0[i] & dma_mask[i];
161 dma_dst1[i] = dma_src1[i] & dma_mask[i];
162 dma_dst2[i] = dma_src2[i] & dma_mask[i];
163 dma_dst3[i] = dma_src3[i] & dma_mask[i];
166 /* Read (dma_dst), compute (hash), write (hash) */
168 uint32_t hash0 = p->f_hash(dma_dst0, dma_size, 0);
169 uint32_t hash1 = p->f_hash(dma_dst1, dma_size, 0);
170 uint32_t hash2 = p->f_hash(dma_dst2, dma_size, 0);
171 uint32_t hash3 = p->f_hash(dma_dst3, dma_size, 0);
179 uint32_t port_out0, port_out1, port_out2, port_out3;
183 = hash0 & (p->p.n_ports_out - 1);
185 = hash1 & (p->p.n_ports_out - 1);
187 = hash2 & (p->p.n_ports_out - 1);
189 = hash3 & (p->p.n_ports_out - 1);
192 = hash0 % p->p.n_ports_out;
194 = hash1 % p->p.n_ports_out;
196 = hash2 % p->p.n_ports_out;
198 = hash3 % p->p.n_ports_out;
200 rte_pipeline_port_out_packet_insert(p->p.p,
202 rte_pipeline_port_out_packet_insert(p->p.p,
204 rte_pipeline_port_out_packet_insert(p->p.p,
206 rte_pipeline_port_out_packet_insert(p->p.p,
212 #define PKT_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
214 pkt_work_size##dma_size##_hash##hash_enabled \
215 ##_lb##lb_hash##_pw##port_pow2( \
216 struct rte_mbuf *pkt, \
219 pkt_work(pkt, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
222 #define PKT4_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
224 pkt4_work_size##dma_size##_hash##hash_enabled \
225 ##_lb##lb_hash##_pw##port_pow2( \
226 struct rte_mbuf **pkts, \
229 pkt4_work(pkts, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
232 #define port_in_ah(dma_size, hash_enabled, lb_hash, port_pow2) \
233 PKT_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
234 PKT4_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
235 PIPELINE_PORT_IN_AH(port_in_ah_size##dma_size##_hash \
236 ##hash_enabled##_lb##lb_hash##_pw##port_pow2, \
237 pkt_work_size##dma_size##_hash##hash_enabled \
238 ##_lb##lb_hash##_pw##port_pow2, \
239 pkt4_work_size##dma_size##_hash##hash_enabled \
240 ##_lb##lb_hash##_pw##port_pow2)
243 #define port_in_ah_lb(dma_size, hash_enabled, lb_hash, port_pow2) \
244 PKT_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
245 PKT4_WORK(dma_size, hash_enabled, lb_hash, port_pow2) \
246 PIPELINE_PORT_IN_AH_HIJACK_ALL( \
247 port_in_ah_size##dma_size##_hash##hash_enabled \
248 ##_lb##lb_hash##_pw##port_pow2, \
249 pkt_work_size##dma_size##_hash##hash_enabled \
250 ##_lb##lb_hash##_pw##port_pow2, \
251 pkt4_work_size##dma_size##_hash##hash_enabled \
252 ##_lb##lb_hash##_pw##port_pow2)
254 /* Port in AH (dma_size, hash_enabled, lb_hash, port_pow2) */
256 port_in_ah(8, 0, 0, 0)
257 port_in_ah(8, 1, 0, 0)
258 port_in_ah_lb(8, 1, 1, 0)
259 port_in_ah_lb(8, 1, 1, 1)
261 port_in_ah(16, 0, 0, 0)
262 port_in_ah(16, 1, 0, 0)
263 port_in_ah_lb(16, 1, 1, 0)
264 port_in_ah_lb(16, 1, 1, 1)
266 port_in_ah(24, 0, 0, 0)
267 port_in_ah(24, 1, 0, 0)
268 port_in_ah_lb(24, 1, 1, 0)
269 port_in_ah_lb(24, 1, 1, 1)
271 port_in_ah(32, 0, 0, 0)
272 port_in_ah(32, 1, 0, 0)
273 port_in_ah_lb(32, 1, 1, 0)
274 port_in_ah_lb(32, 1, 1, 1)
276 port_in_ah(40, 0, 0, 0)
277 port_in_ah(40, 1, 0, 0)
278 port_in_ah_lb(40, 1, 1, 0)
279 port_in_ah_lb(40, 1, 1, 1)
281 port_in_ah(48, 0, 0, 0)
282 port_in_ah(48, 1, 0, 0)
283 port_in_ah_lb(48, 1, 1, 0)
284 port_in_ah_lb(48, 1, 1, 1)
286 port_in_ah(56, 0, 0, 0)
287 port_in_ah(56, 1, 0, 0)
288 port_in_ah_lb(56, 1, 1, 0)
289 port_in_ah_lb(56, 1, 1, 1)
291 port_in_ah(64, 0, 0, 0)
292 port_in_ah(64, 1, 0, 0)
293 port_in_ah_lb(64, 1, 1, 0)
294 port_in_ah_lb(64, 1, 1, 1)
296 static rte_pipeline_port_in_action_handler
297 get_port_in_ah(struct pipeline_passthrough *p)
299 if (p->params.dma_enabled == 0)
302 if (p->params.dma_hash_enabled) {
303 if (p->params.lb_hash_enabled) {
304 if (rte_is_power_of_2(p->p.n_ports_out))
305 switch (p->params.dma_size) {
307 case 8: return port_in_ah_size8_hash1_lb1_pw1;
308 case 16: return port_in_ah_size16_hash1_lb1_pw1;
309 case 24: return port_in_ah_size24_hash1_lb1_pw1;
310 case 32: return port_in_ah_size32_hash1_lb1_pw1;
311 case 40: return port_in_ah_size40_hash1_lb1_pw1;
312 case 48: return port_in_ah_size48_hash1_lb1_pw1;
313 case 56: return port_in_ah_size56_hash1_lb1_pw1;
314 case 64: return port_in_ah_size64_hash1_lb1_pw1;
315 default: return NULL;
318 switch (p->params.dma_size) {
320 case 8: return port_in_ah_size8_hash1_lb1_pw0;
321 case 16: return port_in_ah_size16_hash1_lb1_pw0;
322 case 24: return port_in_ah_size24_hash1_lb1_pw0;
323 case 32: return port_in_ah_size32_hash1_lb1_pw0;
324 case 40: return port_in_ah_size40_hash1_lb1_pw0;
325 case 48: return port_in_ah_size48_hash1_lb1_pw0;
326 case 56: return port_in_ah_size56_hash1_lb1_pw0;
327 case 64: return port_in_ah_size64_hash1_lb1_pw0;
328 default: return NULL;
331 switch (p->params.dma_size) {
333 case 8: return port_in_ah_size8_hash1_lb0_pw0;
334 case 16: return port_in_ah_size16_hash1_lb0_pw0;
335 case 24: return port_in_ah_size24_hash1_lb0_pw0;
336 case 32: return port_in_ah_size32_hash1_lb0_pw0;
337 case 40: return port_in_ah_size40_hash1_lb0_pw0;
338 case 48: return port_in_ah_size48_hash1_lb0_pw0;
339 case 56: return port_in_ah_size56_hash1_lb0_pw0;
340 case 64: return port_in_ah_size64_hash1_lb0_pw0;
341 default: return NULL;
344 switch (p->params.dma_size) {
346 case 8: return port_in_ah_size8_hash0_lb0_pw0;
347 case 16: return port_in_ah_size16_hash0_lb0_pw0;
348 case 24: return port_in_ah_size24_hash0_lb0_pw0;
349 case 32: return port_in_ah_size32_hash0_lb0_pw0;
350 case 40: return port_in_ah_size40_hash0_lb0_pw0;
351 case 48: return port_in_ah_size48_hash0_lb0_pw0;
352 case 56: return port_in_ah_size56_hash0_lb0_pw0;
353 case 64: return port_in_ah_size64_hash0_lb0_pw0;
354 default: return NULL;
359 pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
360 struct pipeline_params *params)
362 uint32_t dma_dst_offset_present = 0;
363 uint32_t dma_src_offset_present = 0;
364 uint32_t dma_src_mask_present = 0;
365 uint32_t dma_size_present = 0;
366 uint32_t dma_hash_offset_present = 0;
367 uint32_t lb_present = 0;
369 char dma_mask_str[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2];
373 p->dma_hash_enabled = 0;
374 p->lb_hash_enabled = 0;
375 memset(p->dma_src_mask, 0xFF, sizeof(p->dma_src_mask));
377 for (i = 0; i < params->n_args; i++) {
378 char *arg_name = params->args_name[i];
379 char *arg_value = params->args_value[i];
382 if (strcmp(arg_name, "dma_dst_offset") == 0) {
385 PIPELINE_PARSE_ERR_DUPLICATE(
386 dma_dst_offset_present == 0, params->name,
388 dma_dst_offset_present = 1;
390 status = parser_read_uint32(&p->dma_dst_offset,
392 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
393 params->name, arg_name, arg_value);
394 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
395 params->name, arg_name, arg_value);
403 if (strcmp(arg_name, "dma_src_offset") == 0) {
406 PIPELINE_PARSE_ERR_DUPLICATE(
407 dma_src_offset_present == 0, params->name,
409 dma_src_offset_present = 1;
411 status = parser_read_uint32(&p->dma_src_offset,
413 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
414 params->name, arg_name, arg_value);
415 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
416 params->name, arg_name, arg_value);
424 if (strcmp(arg_name, "dma_size") == 0) {
427 PIPELINE_PARSE_ERR_DUPLICATE(
428 dma_size_present == 0, params->name,
430 dma_size_present = 1;
432 status = parser_read_uint32(&p->dma_size,
434 PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
435 (p->dma_size != 0) &&
436 ((p->dma_size % 8) == 0)),
437 params->name, arg_name, arg_value);
438 PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
440 PIPELINE_PASSTHROUGH_DMA_SIZE_MAX)),
441 params->name, arg_name, arg_value);
449 if (strcmp(arg_name, "dma_src_mask") == 0) {
450 int mask_str_len = strlen(arg_value);
452 PIPELINE_PARSE_ERR_DUPLICATE(
453 dma_src_mask_present == 0,
454 params->name, arg_name);
455 dma_src_mask_present = 1;
457 PIPELINE_ARG_CHECK((mask_str_len <
458 (PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2)),
459 "Parse error in section \"%s\": entry "
460 "\"%s\" too long", params->name,
463 snprintf(dma_mask_str, mask_str_len + 1,
471 /* dma_hash_offset */
472 if (strcmp(arg_name, "dma_hash_offset") == 0) {
475 PIPELINE_PARSE_ERR_DUPLICATE(
476 dma_hash_offset_present == 0,
477 params->name, arg_name);
478 dma_hash_offset_present = 1;
480 status = parser_read_uint32(&p->dma_hash_offset,
482 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
483 params->name, arg_name, arg_value);
484 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
485 params->name, arg_name, arg_value);
487 p->dma_hash_enabled = 1;
493 /* load_balance mode */
494 if (strcmp(arg_name, "lb") == 0) {
495 PIPELINE_PARSE_ERR_DUPLICATE(
497 params->name, arg_name);
500 if ((strcmp(arg_value, "hash") == 0) ||
501 (strcmp(arg_value, "HASH") == 0))
502 p->lb_hash_enabled = 1;
504 PIPELINE_PARSE_ERR_INV_VAL(0,
513 PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
516 /* Check correlations between arguments */
517 PIPELINE_ARG_CHECK((dma_dst_offset_present == p->dma_enabled),
518 "Parse error in section \"%s\": missing entry "
519 "\"dma_dst_offset\"", params->name);
520 PIPELINE_ARG_CHECK((dma_src_offset_present == p->dma_enabled),
521 "Parse error in section \"%s\": missing entry "
522 "\"dma_src_offset\"", params->name);
523 PIPELINE_ARG_CHECK((dma_size_present == p->dma_enabled),
524 "Parse error in section \"%s\": missing entry "
525 "\"dma_size\"", params->name);
526 PIPELINE_ARG_CHECK((dma_hash_offset_present == p->dma_enabled),
527 "Parse error in section \"%s\": missing entry "
528 "\"dma_hash_offset\"", params->name);
529 PIPELINE_ARG_CHECK((p->lb_hash_enabled <= p->dma_hash_enabled),
530 "Parse error in section \"%s\": missing entry "
531 "\"dma_hash_offset\"", params->name);
533 if (dma_src_mask_present) {
534 uint32_t dma_size = p->dma_size;
537 PIPELINE_ARG_CHECK((strlen(dma_mask_str) ==
538 (dma_size * 2)), "Parse error in section "
539 "\"%s\": dma_src_mask should have exactly %u hex "
540 "digits", params->name, (dma_size * 2));
542 status = parse_hex_string(dma_mask_str, p->dma_src_mask,
545 PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
546 (dma_size == p->dma_size)), params->name,
547 "dma_src_mask", dma_mask_str);
550 if (p->lb_hash_enabled)
551 PIPELINE_ARG_CHECK((params->n_ports_out > 1),
552 "Parse error in section \"%s\": entry \"lb\" not "
553 "allowed for single output port pipeline",
556 PIPELINE_ARG_CHECK(((params->n_ports_in >= params->n_ports_out)
557 && ((params->n_ports_in % params->n_ports_out) == 0)),
558 "Parse error in section \"%s\": n_ports_in needs to be "
559 "a multiple of n_ports_out (lb mode disabled)",
566 static rte_table_hash_op_hash
567 get_hash_function(struct pipeline_passthrough *p)
569 switch (p->params.dma_size) {
571 case 8: return hash_default_key8;
572 case 16: return hash_default_key16;
573 case 24: return hash_default_key24;
574 case 32: return hash_default_key32;
575 case 40: return hash_default_key40;
576 case 48: return hash_default_key48;
577 case 56: return hash_default_key56;
578 case 64: return hash_default_key64;
579 default: return NULL;
584 pipeline_passthrough_init(struct pipeline_params *params,
585 __rte_unused void *arg)
588 struct pipeline_passthrough *p_pt;
591 /* Check input arguments */
592 if ((params == NULL) ||
593 (params->n_ports_in == 0) ||
594 (params->n_ports_out == 0))
597 /* Memory allocation */
598 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_passthrough));
599 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
600 p_pt = (struct pipeline_passthrough *) p;
604 strcpy(p->name, params->name);
605 p->log_level = params->log_level;
607 PLOG(p, HIGH, "Pass-through");
609 /* Parse arguments */
610 if (pipeline_passthrough_parse_args(&p_pt->params, params))
612 p_pt->f_hash = get_hash_function(p_pt);
616 struct rte_pipeline_params pipeline_params = {
617 .name = "PASS-THROUGH",
618 .socket_id = params->socket_id,
622 p->p = rte_pipeline_create(&pipeline_params);
629 p->n_ports_in = params->n_ports_in;
630 p->n_ports_out = params->n_ports_out;
631 p->n_tables = p->n_ports_in;
634 for (i = 0; i < p->n_ports_in; i++) {
635 struct rte_pipeline_port_in_params port_params = {
636 .ops = pipeline_port_in_params_get_ops(
637 ¶ms->port_in[i]),
638 .arg_create = pipeline_port_in_params_convert(
639 ¶ms->port_in[i]),
640 .f_action = get_port_in_ah(p_pt),
642 .burst_size = params->port_in[i].burst_size,
645 int status = rte_pipeline_port_in_create(p->p,
650 rte_pipeline_free(p->p);
657 for (i = 0; i < p->n_ports_out; i++) {
658 struct rte_pipeline_port_out_params port_params = {
659 .ops = pipeline_port_out_params_get_ops(
660 ¶ms->port_out[i]),
661 .arg_create = pipeline_port_out_params_convert(
662 ¶ms->port_out[i]),
667 int status = rte_pipeline_port_out_create(p->p,
672 rte_pipeline_free(p->p);
679 for (i = 0; i < p->n_ports_in; i++) {
680 struct rte_pipeline_table_params table_params = {
681 .ops = &rte_table_stub_ops,
683 .f_action_hit = NULL,
684 .f_action_miss = NULL,
686 .action_data_size = 0,
689 int status = rte_pipeline_table_create(p->p,
694 rte_pipeline_free(p->p);
700 /* Connecting input ports to tables */
701 for (i = 0; i < p->n_ports_in; i++) {
702 int status = rte_pipeline_port_in_connect_to_table(p->p,
707 rte_pipeline_free(p->p);
713 /* Add entries to tables */
714 for (i = 0; i < p->n_ports_in; i++) {
715 uint32_t port_out_id = (p_pt->params.lb_hash_enabled == 0) ?
716 (i / (p->n_ports_in / p->n_ports_out)) :
719 struct rte_pipeline_table_entry default_entry = {
720 .action = RTE_PIPELINE_ACTION_PORT,
721 {.port_id = p->port_out_id[port_out_id]},
724 struct rte_pipeline_table_entry *default_entry_ptr;
726 int status = rte_pipeline_table_default_entry_add(p->p,
732 rte_pipeline_free(p->p);
738 /* Enable input ports */
739 for (i = 0; i < p->n_ports_in; i++) {
740 int status = rte_pipeline_port_in_enable(p->p,
744 rte_pipeline_free(p->p);
750 /* Check pipeline consistency */
751 if (rte_pipeline_check(p->p) < 0) {
752 rte_pipeline_free(p->p);
758 p->n_msgq = params->n_msgq;
759 for (i = 0; i < p->n_msgq; i++)
760 p->msgq_in[i] = params->msgq_in[i];
761 for (i = 0; i < p->n_msgq; i++)
762 p->msgq_out[i] = params->msgq_out[i];
764 /* Message handlers */
765 memcpy(p->handlers, handlers, sizeof(p->handlers));
771 pipeline_passthrough_free(void *pipeline)
773 struct pipeline *p = (struct pipeline *) pipeline;
775 /* Check input arguments */
780 rte_pipeline_free(p->p);
786 pipeline_passthrough_timer(void *pipeline)
788 struct pipeline *p = (struct pipeline *) pipeline;
790 pipeline_msg_req_handle(p);
791 rte_pipeline_flush(p->p);
796 struct pipeline_be_ops pipeline_passthrough_be_ops = {
797 .f_init = pipeline_passthrough_init,
798 .f_free = pipeline_passthrough_free,
800 .f_timer = pipeline_passthrough_timer,