+++ /dev/null
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_byteorder.h>
-#include <rte_string_fns.h>
-#include <rte_table_stub.h>
-#include <rte_table_hash.h>
-#include <rte_pipeline.h>
-
-#include "pipeline_passthrough_be.h"
-#include "pipeline_actions_common.h"
-#include "parser.h"
-#include "hash_func.h"
-
-#define SWAP_DIM (PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX * \
- (PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX / sizeof(uint64_t)))
-
-struct pipeline_passthrough {
- struct pipeline p;
- struct pipeline_passthrough_params params;
- rte_table_hash_op_hash f_hash;
- uint32_t swap_field0_offset[SWAP_DIM];
- uint32_t swap_field1_offset[SWAP_DIM];
- uint64_t swap_field_mask[SWAP_DIM];
- uint32_t swap_n_fields;
-} __rte_cache_aligned;
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_msg_req_invalid_handler,
-};
-
-static __rte_always_inline void
-pkt_work_dma(
- struct rte_mbuf *pkt,
- void *arg,
- uint32_t dma_size,
- uint32_t hash_enabled,
- uint32_t lb_hash,
- uint32_t port_out_pow2)
-{
- struct pipeline_passthrough *p = arg;
-
- uint64_t *dma_dst = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->params.dma_dst_offset);
- uint64_t *dma_src = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->params.dma_src_offset);
- uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
- uint32_t *dma_hash = RTE_MBUF_METADATA_UINT32_PTR(pkt,
- p->params.dma_hash_offset);
- uint32_t i;
-
- /* Read (dma_src), compute (dma_dst), write (dma_dst) */
- for (i = 0; i < (dma_size / 8); i++)
- dma_dst[i] = dma_src[i] & dma_mask[i];
-
- /* Read (dma_dst), compute (hash), write (hash) */
- if (hash_enabled) {
- uint32_t hash = p->f_hash(dma_src, dma_mask, dma_size, 0);
- *dma_hash = hash;
-
- if (lb_hash) {
- uint32_t port_out;
-
- if (port_out_pow2)
- port_out
- = hash & (p->p.n_ports_out - 1);
- else
- port_out
- = hash % p->p.n_ports_out;
-
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out, pkt);
- }
- }
-}
-
-static __rte_always_inline void
-pkt4_work_dma(
- struct rte_mbuf **pkts,
- void *arg,
- uint32_t dma_size,
- uint32_t hash_enabled,
- uint32_t lb_hash,
- uint32_t port_out_pow2)
-{
- struct pipeline_passthrough *p = arg;
-
- uint64_t *dma_dst0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->params.dma_dst_offset);
- uint64_t *dma_dst1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->params.dma_dst_offset);
- uint64_t *dma_dst2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->params.dma_dst_offset);
- uint64_t *dma_dst3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->params.dma_dst_offset);
-
- uint64_t *dma_src0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->params.dma_src_offset);
- uint64_t *dma_src1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->params.dma_src_offset);
- uint64_t *dma_src2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->params.dma_src_offset);
- uint64_t *dma_src3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->params.dma_src_offset);
-
- uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
-
- uint32_t *dma_hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkts[0],
- p->params.dma_hash_offset);
- uint32_t *dma_hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkts[1],
- p->params.dma_hash_offset);
- uint32_t *dma_hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkts[2],
- p->params.dma_hash_offset);
- uint32_t *dma_hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkts[3],
- p->params.dma_hash_offset);
-
- uint32_t i;
-
- /* Read (dma_src), compute (dma_dst), write (dma_dst) */
- for (i = 0; i < (dma_size / 8); i++) {
- dma_dst0[i] = dma_src0[i] & dma_mask[i];
- dma_dst1[i] = dma_src1[i] & dma_mask[i];
- dma_dst2[i] = dma_src2[i] & dma_mask[i];
- dma_dst3[i] = dma_src3[i] & dma_mask[i];
- }
-
- /* Read (dma_dst), compute (hash), write (hash) */
- if (hash_enabled) {
- uint32_t hash0 = p->f_hash(dma_src0, dma_mask, dma_size, 0);
- uint32_t hash1 = p->f_hash(dma_src1, dma_mask, dma_size, 0);
- uint32_t hash2 = p->f_hash(dma_src2, dma_mask, dma_size, 0);
- uint32_t hash3 = p->f_hash(dma_src3, dma_mask, dma_size, 0);
-
- *dma_hash0 = hash0;
- *dma_hash1 = hash1;
- *dma_hash2 = hash2;
- *dma_hash3 = hash3;
-
- if (lb_hash) {
- uint32_t port_out0, port_out1, port_out2, port_out3;
-
- if (port_out_pow2) {
- port_out0
- = hash0 & (p->p.n_ports_out - 1);
- port_out1
- = hash1 & (p->p.n_ports_out - 1);
- port_out2
- = hash2 & (p->p.n_ports_out - 1);
- port_out3
- = hash3 & (p->p.n_ports_out - 1);
- } else {
- port_out0
- = hash0 % p->p.n_ports_out;
- port_out1
- = hash1 % p->p.n_ports_out;
- port_out2
- = hash2 % p->p.n_ports_out;
- port_out3
- = hash3 % p->p.n_ports_out;
- }
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out0, pkts[0]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out1, pkts[1]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out2, pkts[2]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out3, pkts[3]);
- }
- }
-}
-
-static __rte_always_inline void
-pkt_work_swap(
- struct rte_mbuf *pkt,
- void *arg)
-{
- struct pipeline_passthrough *p = arg;
- uint32_t i;
-
- /* Read(field0, field1), compute(field0, field1), write(field0, field1) */
- for (i = 0; i < p->swap_n_fields; i++) {
- uint64_t *field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->swap_field0_offset[i]);
- uint64_t *field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->swap_field1_offset[i]);
- uint64_t mask = p->swap_field_mask[i];
-
- uint64_t field0 = *field0_ptr;
- uint64_t field1 = *field1_ptr;
-
- *field0_ptr = (field0 & (~mask)) + (field1 & mask);
- *field1_ptr = (field0 & mask) + (field1 & (~mask));
- }
-}
-
-static __rte_always_inline void
-pkt4_work_swap(
- struct rte_mbuf **pkts,
- void *arg)
-{
- struct pipeline_passthrough *p = arg;
- uint32_t i;
-
- /* Read(field0, field1), compute(field0, field1), write(field0, field1) */
- for (i = 0; i < p->swap_n_fields; i++) {
- uint64_t *pkt0_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->swap_field0_offset[i]);
- uint64_t *pkt1_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->swap_field0_offset[i]);
- uint64_t *pkt2_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->swap_field0_offset[i]);
- uint64_t *pkt3_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->swap_field0_offset[i]);
-
- uint64_t *pkt0_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->swap_field1_offset[i]);
- uint64_t *pkt1_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->swap_field1_offset[i]);
- uint64_t *pkt2_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->swap_field1_offset[i]);
- uint64_t *pkt3_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->swap_field1_offset[i]);
-
- uint64_t mask = p->swap_field_mask[i];
-
- uint64_t pkt0_field0 = *pkt0_field0_ptr;
- uint64_t pkt1_field0 = *pkt1_field0_ptr;
- uint64_t pkt2_field0 = *pkt2_field0_ptr;
- uint64_t pkt3_field0 = *pkt3_field0_ptr;
-
- uint64_t pkt0_field1 = *pkt0_field1_ptr;
- uint64_t pkt1_field1 = *pkt1_field1_ptr;
- uint64_t pkt2_field1 = *pkt2_field1_ptr;
- uint64_t pkt3_field1 = *pkt3_field1_ptr;
-
- *pkt0_field0_ptr = (pkt0_field0 & (~mask)) + (pkt0_field1 & mask);
- *pkt1_field0_ptr = (pkt1_field0 & (~mask)) + (pkt1_field1 & mask);
- *pkt2_field0_ptr = (pkt2_field0 & (~mask)) + (pkt2_field1 & mask);
- *pkt3_field0_ptr = (pkt3_field0 & (~mask)) + (pkt3_field1 & mask);
-
- *pkt0_field1_ptr = (pkt0_field0 & mask) + (pkt0_field1 & (~mask));
- *pkt1_field1_ptr = (pkt1_field0 & mask) + (pkt1_field1 & (~mask));
- *pkt2_field1_ptr = (pkt2_field0 & mask) + (pkt2_field1 & (~mask));
- *pkt3_field1_ptr = (pkt3_field0 & mask) + (pkt3_field1 & (~mask));
- }
-}
-
-#define PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-static inline void \
-pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2( \
- struct rte_mbuf *pkt, \
- void *arg) \
-{ \
- pkt_work_dma(pkt, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
-}
-
-#define PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-static inline void \
-pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2( \
- struct rte_mbuf **pkts, \
- void *arg) \
-{ \
- pkt4_work_dma(pkts, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
-}
-
-#define port_in_ah_dma(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PIPELINE_PORT_IN_AH(port_in_ah_dma_size##dma_size##_hash \
- ##hash_enabled##_lb##lb_hash##_pw##port_pow2, \
- pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2)
-
-
-#define port_in_ah_lb(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PIPELINE_PORT_IN_AH_HIJACK_ALL( \
- port_in_ah_lb_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2)
-
-PIPELINE_PORT_IN_AH(port_in_ah_swap, pkt_work_swap, pkt4_work_swap)
-
-
-/* Port in AH DMA(dma_size, hash_enabled, lb_hash, port_pow2) */
-
-port_in_ah_dma(8, 0, 0, 0)
-port_in_ah_dma(8, 1, 0, 0)
-port_in_ah_lb(8, 1, 1, 0)
-port_in_ah_lb(8, 1, 1, 1)
-
-port_in_ah_dma(16, 0, 0, 0)
-port_in_ah_dma(16, 1, 0, 0)
-port_in_ah_lb(16, 1, 1, 0)
-port_in_ah_lb(16, 1, 1, 1)
-
-port_in_ah_dma(24, 0, 0, 0)
-port_in_ah_dma(24, 1, 0, 0)
-port_in_ah_lb(24, 1, 1, 0)
-port_in_ah_lb(24, 1, 1, 1)
-
-port_in_ah_dma(32, 0, 0, 0)
-port_in_ah_dma(32, 1, 0, 0)
-port_in_ah_lb(32, 1, 1, 0)
-port_in_ah_lb(32, 1, 1, 1)
-
-port_in_ah_dma(40, 0, 0, 0)
-port_in_ah_dma(40, 1, 0, 0)
-port_in_ah_lb(40, 1, 1, 0)
-port_in_ah_lb(40, 1, 1, 1)
-
-port_in_ah_dma(48, 0, 0, 0)
-port_in_ah_dma(48, 1, 0, 0)
-port_in_ah_lb(48, 1, 1, 0)
-port_in_ah_lb(48, 1, 1, 1)
-
-port_in_ah_dma(56, 0, 0, 0)
-port_in_ah_dma(56, 1, 0, 0)
-port_in_ah_lb(56, 1, 1, 0)
-port_in_ah_lb(56, 1, 1, 1)
-
-port_in_ah_dma(64, 0, 0, 0)
-port_in_ah_dma(64, 1, 0, 0)
-port_in_ah_lb(64, 1, 1, 0)
-port_in_ah_lb(64, 1, 1, 1)
-
-static rte_pipeline_port_in_action_handler
-get_port_in_ah(struct pipeline_passthrough *p)
-{
- if ((p->params.dma_enabled == 0) &&
- (p->params.swap_enabled == 0))
- return NULL;
-
- if (p->params.swap_enabled)
- return port_in_ah_swap;
-
- if (p->params.dma_hash_enabled) {
- if (p->params.dma_hash_lb_enabled) {
- if (rte_is_power_of_2(p->p.n_ports_out))
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_lb_size8_hash1_lb1_pw1;
- case 16: return port_in_ah_lb_size16_hash1_lb1_pw1;
- case 24: return port_in_ah_lb_size24_hash1_lb1_pw1;
- case 32: return port_in_ah_lb_size32_hash1_lb1_pw1;
- case 40: return port_in_ah_lb_size40_hash1_lb1_pw1;
- case 48: return port_in_ah_lb_size48_hash1_lb1_pw1;
- case 56: return port_in_ah_lb_size56_hash1_lb1_pw1;
- case 64: return port_in_ah_lb_size64_hash1_lb1_pw1;
- default: return NULL;
- }
- else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_lb_size8_hash1_lb1_pw0;
- case 16: return port_in_ah_lb_size16_hash1_lb1_pw0;
- case 24: return port_in_ah_lb_size24_hash1_lb1_pw0;
- case 32: return port_in_ah_lb_size32_hash1_lb1_pw0;
- case 40: return port_in_ah_lb_size40_hash1_lb1_pw0;
- case 48: return port_in_ah_lb_size48_hash1_lb1_pw0;
- case 56: return port_in_ah_lb_size56_hash1_lb1_pw0;
- case 64: return port_in_ah_lb_size64_hash1_lb1_pw0;
- default: return NULL;
- }
- } else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_dma_size8_hash1_lb0_pw0;
- case 16: return port_in_ah_dma_size16_hash1_lb0_pw0;
- case 24: return port_in_ah_dma_size24_hash1_lb0_pw0;
- case 32: return port_in_ah_dma_size32_hash1_lb0_pw0;
- case 40: return port_in_ah_dma_size40_hash1_lb0_pw0;
- case 48: return port_in_ah_dma_size48_hash1_lb0_pw0;
- case 56: return port_in_ah_dma_size56_hash1_lb0_pw0;
- case 64: return port_in_ah_dma_size64_hash1_lb0_pw0;
- default: return NULL;
- }
- } else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_dma_size8_hash0_lb0_pw0;
- case 16: return port_in_ah_dma_size16_hash0_lb0_pw0;
- case 24: return port_in_ah_dma_size24_hash0_lb0_pw0;
- case 32: return port_in_ah_dma_size32_hash0_lb0_pw0;
- case 40: return port_in_ah_dma_size40_hash0_lb0_pw0;
- case 48: return port_in_ah_dma_size48_hash0_lb0_pw0;
- case 56: return port_in_ah_dma_size56_hash0_lb0_pw0;
- case 64: return port_in_ah_dma_size64_hash0_lb0_pw0;
- default: return NULL;
- }
-}
-
-int
-pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
- struct pipeline_params *params)
-{
- uint32_t dma_dst_offset_present = 0;
- uint32_t dma_src_offset_present = 0;
- uint32_t dma_src_mask_present = 0;
- char dma_mask_str[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2 + 1];
- uint32_t dma_size_present = 0;
- uint32_t dma_hash_offset_present = 0;
- uint32_t dma_hash_lb_present = 0;
- uint32_t i;
-
- /* default values */
- p->dma_enabled = 0;
- p->dma_hash_enabled = 0;
- p->dma_hash_lb_enabled = 0;
- memset(p->dma_src_mask, 0xFF, sizeof(p->dma_src_mask));
- p->swap_enabled = 0;
- p->swap_n_fields = 0;
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- /* dma_dst_offset */
- if (strcmp(arg_name, "dma_dst_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_dst_offset_present == 0, params->name,
- arg_name);
- dma_dst_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_dst_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_src_offset */
- if (strcmp(arg_name, "dma_src_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_src_offset_present == 0, params->name,
- arg_name);
- dma_src_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_src_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_size */
- if (strcmp(arg_name, "dma_size") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_size_present == 0, params->name,
- arg_name);
- dma_size_present = 1;
-
- status = parser_read_uint32(&p->dma_size,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->dma_size != 0) &&
- ((p->dma_size % 8) == 0)),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
- (p->dma_size <=
- PIPELINE_PASSTHROUGH_DMA_SIZE_MAX)),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_src_mask */
- if (strcmp(arg_name, "dma_src_mask") == 0) {
- int mask_str_len = strlen(arg_value);
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_src_mask_present == 0,
- params->name, arg_name);
- dma_src_mask_present = 1;
-
- PIPELINE_ARG_CHECK((mask_str_len <=
- (PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2)),
- "Parse error in section \"%s\": entry "
- "\"%s\" too long", params->name,
- arg_name);
-
- strlcpy(dma_mask_str, arg_value, mask_str_len + 1);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_hash_offset */
- if (strcmp(arg_name, "dma_hash_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_hash_offset_present == 0,
- params->name, arg_name);
- dma_hash_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_hash_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_hash_enabled = 1;
-
- continue;
- }
-
- /* load_balance mode */
- if (strcmp(arg_name, "lb") == 0) {
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_hash_lb_present == 0,
- params->name, arg_name);
- dma_hash_lb_present = 1;
-
- if (strcmp(arg_value, "hash") &&
- strcmp(arg_value, "HASH"))
-
- PIPELINE_PARSE_ERR_INV_VAL(0,
- params->name,
- arg_name,
- arg_value);
-
- p->dma_hash_lb_enabled = 1;
-
- continue;
- }
-
- /* swap */
- if (strcmp(arg_name, "swap") == 0) {
- uint32_t a, b, n_args;
- int len;
-
- n_args = sscanf(arg_value, "%" SCNu32 " %" SCNu32 "%n",
- &a, &b, &len);
- PIPELINE_PARSE_ERR_INV_VAL(((n_args == 2) &&
- ((size_t) len == strlen(arg_value))),
- params->name, arg_name, arg_value);
-
- p->swap_field0_offset[p->swap_n_fields] = a;
- p->swap_field1_offset[p->swap_n_fields] = b;
- p->swap_n_fields++;
- p->swap_enabled = 1;
-
- continue;
- }
-
- /* any other */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- /* Check correlations between arguments */
- PIPELINE_ARG_CHECK((p->dma_enabled + p->swap_enabled < 2),
- "Parse error in section \"%s\": DMA and SWAP actions are both enabled",
- params->name);
- PIPELINE_ARG_CHECK((dma_dst_offset_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_dst_offset\"", params->name);
- PIPELINE_ARG_CHECK((dma_src_offset_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_src_offset\"", params->name);
- PIPELINE_ARG_CHECK((dma_size_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_size\"", params->name);
- PIPELINE_ARG_CHECK((p->dma_hash_enabled <= p->dma_enabled),
- "Parse error in section \"%s\": missing all DMA entries",
- params->name);
- PIPELINE_ARG_CHECK((p->dma_hash_lb_enabled <= p->dma_hash_enabled),
- "Parse error in section \"%s\": missing all DMA hash entries ",
- params->name);
-
- if (dma_src_mask_present) {
- uint32_t dma_size = p->dma_size;
- int status;
-
- PIPELINE_ARG_CHECK((strlen(dma_mask_str) ==
- (dma_size * 2)), "Parse error in section "
- "\"%s\": dma_src_mask should have exactly %u hex "
- "digits", params->name, (dma_size * 2));
-
- status = parse_hex_string(dma_mask_str, p->dma_src_mask,
- &p->dma_size);
-
- PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
- (dma_size == p->dma_size)), params->name,
- "dma_src_mask", dma_mask_str);
- }
-
- if (p->dma_hash_lb_enabled)
- PIPELINE_ARG_CHECK((params->n_ports_out > 1),
- "Parse error in section \"%s\": entry \"lb\" not "
- "allowed for single output port pipeline",
- params->name);
- else
- PIPELINE_ARG_CHECK(((params->n_ports_in >= params->n_ports_out)
- && ((params->n_ports_in % params->n_ports_out) == 0)),
- "Parse error in section \"%s\": n_ports_in needs to be "
- "a multiple of n_ports_out (lb mode disabled)",
- params->name);
-
- return 0;
-}
-
-static rte_table_hash_op_hash
-get_hash_function(struct pipeline_passthrough *p)
-{
- switch (p->params.dma_size) {
-
- case 8: return hash_default_key8;
- case 16: return hash_default_key16;
- case 24: return hash_default_key24;
- case 32: return hash_default_key32;
- case 40: return hash_default_key40;
- case 48: return hash_default_key48;
- case 56: return hash_default_key56;
- case 64: return hash_default_key64;
- default: return NULL;
- }
-}
-
-static int
-pipeline_passthrough_swap_convert(struct pipeline_passthrough *p)
-{
- uint32_t i;
-
- p->swap_n_fields = 0;
-
- for (i = 0; i < p->params.swap_n_fields; i++) {
- uint32_t offset0 = p->params.swap_field0_offset[i];
- uint32_t offset1 = p->params.swap_field1_offset[i];
- uint32_t size = offset1 - offset0;
- uint32_t j;
-
- /* Check */
- if ((offset0 >= offset1) ||
- (size > PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX) ||
- (p->swap_n_fields >= SWAP_DIM))
- return -1;
-
- for (j = 0; j < (size / sizeof(uint64_t)); j++) {
- p->swap_field0_offset[p->swap_n_fields] = offset0;
- p->swap_field1_offset[p->swap_n_fields] = offset1;
- p->swap_field_mask[p->swap_n_fields] = UINT64_MAX;
- p->swap_n_fields++;
- offset0 += sizeof(uint64_t);
- offset1 += sizeof(uint64_t);
- }
- if (size % sizeof(uint64_t)) {
- uint32_t n_bits = (size % sizeof(uint64_t)) * 8;
-
- p->swap_field0_offset[p->swap_n_fields] = offset0;
- p->swap_field1_offset[p->swap_n_fields] = offset1;
- p->swap_field_mask[p->swap_n_fields] =
- RTE_LEN2MASK(n_bits, uint64_t);
- p->swap_n_fields++;
- }
- }
-
- return 0;
-}
-
-static void*
-pipeline_passthrough_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_passthrough *p_pt;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_passthrough));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- p_pt = (struct pipeline_passthrough *) p;
- if (p == NULL)
- return NULL;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Pass-through");
-
- /* Parse arguments */
- if (pipeline_passthrough_parse_args(&p_pt->params, params))
- return NULL;
- if (pipeline_passthrough_swap_convert(p_pt))
- return NULL;
- p_pt->f_hash = get_hash_function(p_pt);
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = "PASS-THROUGH",
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
- p->n_tables = p->n_ports_in;
-
- /*Input ports*/
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- ¶ms->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- ¶ms->port_in[i]),
- .f_action = get_port_in_ah(p_pt),
- .arg_ah = p_pt,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- ¶ms->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- ¶ms->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Tables */
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- int status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Add entries to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- uint32_t port_out_id = (p_pt->params.dma_hash_lb_enabled == 0) ?
- (i / (p->n_ports_in / p->n_ports_out)) :
- 0;
-
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[port_out_id]},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- int status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[i],
- &default_entry,
- &default_entry_ptr);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
-
- return p;
-}
-
-static int
-pipeline_passthrough_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_passthrough_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-struct pipeline_be_ops pipeline_passthrough_be_ops = {
- .f_init = pipeline_passthrough_init,
- .f_free = pipeline_passthrough_free,
- .f_run = NULL,
- .f_timer = pipeline_passthrough_timer,
-};