[10/10] net/sfc: refine pattern of GROUP flows in tunnel offload

Message ID 20210929205730.775-11-ivan.malov@oktetlabs.ru (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series net/sfc: add support for tunnel offload |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ivan Malov Sept. 29, 2021, 8:57 p.m. UTC
  By design, in a GROUP flow, outer match criteria go to "ENC" fields
of the action rule match specification. The current HW/FW hasn't
got support for these fields (except the VXLAN VNI) yet.

As a workaround, start parsing the pattern from the tunnel item.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_mae.c | 37 ++++++++++++++++++++++++++-----------
 drivers/net/sfc/sfc_mae.h |  1 +
 2 files changed, 27 insertions(+), 11 deletions(-)
  

Patch

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 73fb40a02d..eb2133f167 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -1991,14 +1991,21 @@  sfc_mae_rule_parse_item_tunnel(const struct rte_flow_item *item,
 	const uint8_t *mask = NULL;
 	int rc;
 
-	/*
-	 * We're about to start processing inner frame items.
-	 * Process pattern data that has been deferred so far
-	 * and reset pattern data storage.
-	 */
-	rc = sfc_mae_rule_process_pattern_data(ctx_mae, error);
-	if (rc != 0)
-		return rc;
+	if (ctx_mae->ft_rule_type == SFC_FT_RULE_GROUP) {
+		/*
+		 * As a workaround, pattern processing has started from
+		 * this (tunnel) item. No pattern data to process yet.
+		 */
+	} else {
+		/*
+		 * We're about to start processing inner frame items.
+		 * Process pattern data that has been deferred so far
+		 * and reset pattern data storage.
+		 */
+		rc = sfc_mae_rule_process_pattern_data(ctx_mae, error);
+		if (rc != 0)
+			return rc;
+	}
 
 	memset(&ctx_mae->pattern_data, 0, sizeof(ctx_mae->pattern_data));
 
@@ -2317,10 +2324,10 @@  sfc_mae_rule_preparse_item_mark(const struct rte_flow_item_mark *spec,
 
 static int
 sfc_mae_rule_encap_parse_init(struct sfc_adapter *sa,
-			      const struct rte_flow_item pattern[],
 			      struct sfc_mae_parse_ctx *ctx,
 			      struct rte_flow_error *error)
 {
+	const struct rte_flow_item *pattern = ctx->pattern;
 	struct sfc_mae *mae = &sa->mae;
 	uint8_t recirc_id = 0;
 	int rc;
@@ -2395,6 +2402,13 @@  sfc_mae_rule_encap_parse_init(struct sfc_adapter *sa,
 						  RTE_FLOW_ERROR_TYPE_ITEM,
 						  pattern, "tunnel offload: GROUP: tunnel type mismatch");
 		}
+
+		/*
+		 * The HW/FW hasn't got support for the use of "ENC" fields in
+		 * action rules (except the VNET_ID one) yet. As a workaround,
+		 * start parsing the pattern from the tunnel item.
+		 */
+		ctx->pattern = pattern;
 		break;
 	default:
 		SFC_ASSERT(B_FALSE);
@@ -2539,11 +2553,12 @@  sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 	ctx_mae.encap_type = EFX_TUNNEL_PROTOCOL_NONE;
 	ctx_mae.match_spec = ctx_mae.match_spec_action;
 	ctx_mae.field_ids_remap = field_ids_no_remap;
+	ctx_mae.pattern = pattern;
 
 	ctx.type = SFC_FLOW_PARSE_CTX_MAE;
 	ctx.mae = &ctx_mae;
 
-	rc = sfc_mae_rule_encap_parse_init(sa, pattern, &ctx_mae, error);
+	rc = sfc_mae_rule_encap_parse_init(sa, &ctx_mae, error);
 	if (rc != 0)
 		goto fail_encap_parse_init;
 
@@ -2555,7 +2570,7 @@  sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 	spec->ft = ctx_mae.ft;
 
 	rc = sfc_flow_parse_pattern(sa, sfc_flow_items, RTE_DIM(sfc_flow_items),
-				    pattern, &ctx, error);
+				    ctx_mae.pattern, &ctx, error);
 	if (rc != 0)
 		goto fail_parse_pattern;
 
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index b2a62fc10b..53959d568f 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -297,6 +297,7 @@  struct sfc_mae_parse_ctx {
 	enum sfc_flow_tunnel_rule_type	ft_rule_type;
 	struct sfc_mae_pattern_data	pattern_data;
 	efx_tunnel_protocol_t		encap_type;
+	const struct rte_flow_item	*pattern;
 	unsigned int			priority;
 	struct sfc_flow_tunnel		*ft;
 };