[dpdk-dev] [PATCH v2 19/62] net/sfc: support flow item ETH in MAE backend

Andrew Rybchenko arybchenko at solarflare.com
Tue Oct 20 11:12:59 CEST 2020


From: Ivan Malov <ivan.malov at oktetlabs.ru>

Add support for this flow item to MAE-specific RTE flow implementation.

Signed-off-by: Ivan Malov <ivan.malov at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
Reviewed-by: Andy Moreton <amoreton at xilinx.com>
---
 doc/guides/nics/sfc_efx.rst |   2 +
 drivers/net/sfc/sfc_mae.c   | 106 ++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index b12e93180e..65d52d5551 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
-- 
2.17.1



More information about the dev mailing list