From: Ivan Malov Date: Tue, 20 Oct 2020 09:12:59 +0000 (+0100) Subject: net/sfc: support flow item eth in MAE backend X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=0b90a1377d0680f03b82889dec02b6560338e245;p=dpdk.git net/sfc: support flow item eth in MAE backend Add support for this flow item to MAE-specific RTE flow implementation. Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 9097c0d7b8..e590088589 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -192,6 +192,8 @@ Supported pattern items (***transfer*** rules): - PHY_PORT (cannot repeat; conflicts with other traffic source items) +- ETH + Validating flow rules depends on the firmware variant. The :ref:`flow_isolated_mode` is supported. diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 87d2e15d29..95f8cffc27 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -221,6 +221,105 @@ sfc_mae_rule_parse_item_phy_port(const struct rte_flow_item *item, return 0; } +struct sfc_mae_field_locator { + efx_mae_field_id_t field_id; + size_t size; + /* Field offset in the corresponding rte_flow_item_ struct */ + size_t ofst; +}; + +static void +sfc_mae_item_build_supp_mask(const struct sfc_mae_field_locator *field_locators, + unsigned int nb_field_locators, void *mask_ptr, + size_t mask_size) +{ + unsigned int i; + + memset(mask_ptr, 0, mask_size); + + for (i = 0; i < nb_field_locators; ++i) { + const struct sfc_mae_field_locator *fl = &field_locators[i]; + + SFC_ASSERT(fl->ofst + fl->size <= mask_size); + memset(RTE_PTR_ADD(mask_ptr, fl->ofst), 0xff, fl->size); + } +} + +static int +sfc_mae_parse_item(const struct sfc_mae_field_locator *field_locators, + unsigned int nb_field_locators, const uint8_t *spec, + const uint8_t *mask, efx_mae_match_spec_t *efx_spec, + struct rte_flow_error *error) +{ + unsigned int i; + int rc = 0; + + for (i = 0; i < nb_field_locators; ++i) { + const struct sfc_mae_field_locator *fl = &field_locators[i]; + + rc = efx_mae_match_spec_field_set(efx_spec, fl->field_id, + fl->size, spec + fl->ofst, + fl->size, mask + fl->ofst); + if (rc != 0) + break; + } + + if (rc != 0) { + rc = rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ITEM, + NULL, "Failed to process item fields"); + } + + return rc; +} + +static const struct sfc_mae_field_locator flocs_eth[] = { + { + EFX_MAE_FIELD_ETHER_TYPE_BE, + RTE_SIZEOF_FIELD(struct rte_flow_item_eth, type), + offsetof(struct rte_flow_item_eth, type), + }, + { + EFX_MAE_FIELD_ETH_DADDR_BE, + RTE_SIZEOF_FIELD(struct rte_flow_item_eth, dst), + offsetof(struct rte_flow_item_eth, dst), + }, + { + EFX_MAE_FIELD_ETH_SADDR_BE, + RTE_SIZEOF_FIELD(struct rte_flow_item_eth, src), + offsetof(struct rte_flow_item_eth, src), + }, +}; + +static int +sfc_mae_rule_parse_item_eth(const struct rte_flow_item *item, + struct sfc_flow_parse_ctx *ctx, + struct rte_flow_error *error) +{ + struct sfc_mae_parse_ctx *ctx_mae = ctx->mae; + struct rte_flow_item_eth supp_mask; + const uint8_t *spec = NULL; + const uint8_t *mask = NULL; + int rc; + + sfc_mae_item_build_supp_mask(flocs_eth, RTE_DIM(flocs_eth), + &supp_mask, sizeof(supp_mask)); + + rc = sfc_flow_parse_init(item, + (const void **)&spec, (const void **)&mask, + (const void *)&supp_mask, + &rte_flow_item_eth_mask, + sizeof(struct rte_flow_item_eth), error); + if (rc != 0) + return rc; + + /* If "spec" is not set, could be any Ethernet */ + if (spec == NULL) + return 0; + + return sfc_mae_parse_item(flocs_eth, RTE_DIM(flocs_eth), spec, mask, + ctx_mae->match_spec_action, error); +} + static const struct sfc_flow_item sfc_flow_items[] = { { .type = RTE_FLOW_ITEM_TYPE_PHY_PORT, @@ -233,6 +332,13 @@ static const struct sfc_flow_item sfc_flow_items[] = { .ctx_type = SFC_FLOW_PARSE_CTX_MAE, .parse = sfc_mae_rule_parse_item_phy_port, }, + { + .type = RTE_FLOW_ITEM_TYPE_ETH, + .prev_layer = SFC_FLOW_ITEM_START_LAYER, + .layer = SFC_FLOW_ITEM_L2, + .ctx_type = SFC_FLOW_PARSE_CTX_MAE, + .parse = sfc_mae_rule_parse_item_eth, + }, }; int