[PATCH v6 04/27] net/i40e: get rid of global filter variables

Anatoly Burakov anatoly.burakov at intel.com
Thu Feb 19 17:22:47 CET 2026


Currently, i40e driver relies on global state to work around the fact that
`rte_flow_validate()` is being called directly from `rte_flow_create()`,
and it not being possible to pass state between two functions. Fix that by
making a small wrapper around validation that will create a dummy context.

Additionally, tunnel filter doesn't appear to be used by anything and so is
omitted from the structure.

Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
Acked-by: Vladimir Medvedkin <vladimir.medvedkin at intel.com>
---
 drivers/net/intel/i40e/i40e_ethdev.h |  16 ++--
 drivers/net/intel/i40e/i40e_flow.c   | 117 ++++++++++++++-------------
 2 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index cab6d7e9dc..0de036f2d9 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1304,12 +1304,14 @@ struct i40e_vf_representor {
 
 extern const struct rte_flow_ops i40e_flow_ops;
 
-union i40e_filter_t {
-	struct rte_eth_ethertype_filter ethertype_filter;
-	struct i40e_fdir_filter_conf fdir_filter;
-	struct rte_eth_tunnel_filter_conf tunnel_filter;
-	struct i40e_tunnel_filter_conf consistent_tunnel_filter;
-	struct i40e_rte_flow_rss_conf rss_conf;
+struct i40e_filter_ctx {
+	union {
+		struct rte_eth_ethertype_filter ethertype_filter;
+		struct i40e_fdir_filter_conf fdir_filter;
+		struct i40e_tunnel_filter_conf consistent_tunnel_filter;
+		struct i40e_rte_flow_rss_conf rss_conf;
+	};
+	enum rte_filter_type type;
 };
 
 typedef int (*parse_filter_t)(struct rte_eth_dev *dev,
@@ -1317,7 +1319,7 @@ typedef int (*parse_filter_t)(struct rte_eth_dev *dev,
 			      const struct rte_flow_item pattern[],
 			      const struct rte_flow_action actions[],
 			      struct rte_flow_error *error,
-			      union i40e_filter_t *filter);
+			      struct i40e_filter_ctx *filter);
 struct i40e_valid_pattern {
 	enum rte_flow_item_type *items;
 	parse_filter_t parse_filter;
diff --git a/drivers/net/intel/i40e/i40e_flow.c b/drivers/net/intel/i40e/i40e_flow.c
index 2374b9bbca..e611de0c06 100644
--- a/drivers/net/intel/i40e/i40e_flow.c
+++ b/drivers/net/intel/i40e/i40e_flow.c
@@ -80,37 +80,37 @@ static int i40e_flow_parse_ethertype_filter(struct rte_eth_dev *dev,
 				    const struct rte_flow_item pattern[],
 				    const struct rte_flow_action actions[],
 				    struct rte_flow_error *error,
-				    union i40e_filter_t *filter);
+				    struct i40e_filter_ctx *filter);
 static int i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 				       const struct rte_flow_attr *attr,
 				       const struct rte_flow_item pattern[],
 				       const struct rte_flow_action actions[],
 				       struct rte_flow_error *error,
-				       union i40e_filter_t *filter);
+				       struct i40e_filter_ctx *filter);
 static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 					const struct rte_flow_attr *attr,
 					const struct rte_flow_item pattern[],
 					const struct rte_flow_action actions[],
 					struct rte_flow_error *error,
-					union i40e_filter_t *filter);
+					struct i40e_filter_ctx *filter);
 static int i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
 					const struct rte_flow_attr *attr,
 					const struct rte_flow_item pattern[],
 					const struct rte_flow_action actions[],
 					struct rte_flow_error *error,
-					union i40e_filter_t *filter);
+					struct i40e_filter_ctx *filter);
 static int i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
 				       const struct rte_flow_attr *attr,
 				       const struct rte_flow_item pattern[],
 				       const struct rte_flow_action actions[],
 				       struct rte_flow_error *error,
-				       union i40e_filter_t *filter);
+				       struct i40e_filter_ctx *filter);
 static int i40e_flow_parse_gtp_filter(struct rte_eth_dev *dev,
 				      const struct rte_flow_attr *attr,
 				      const struct rte_flow_item pattern[],
 				      const struct rte_flow_action actions[],
 				      struct rte_flow_error *error,
-				      union i40e_filter_t *filter);
+				      struct i40e_filter_ctx *filter);
 static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
 				      struct i40e_ethertype_filter *filter);
 static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
@@ -124,7 +124,7 @@ i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
 			      const struct rte_flow_item pattern[],
 			      const struct rte_flow_action actions[],
 			      struct rte_flow_error *error,
-			      union i40e_filter_t *filter);
+			      struct i40e_filter_ctx *filter);
 static int
 i40e_flow_parse_qinq_pattern(struct rte_eth_dev *dev,
 			      const struct rte_flow_item *pattern,
@@ -136,7 +136,7 @@ static int i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,
 					   const struct rte_flow_item pattern[],
 					   const struct rte_flow_action actions[],
 					   struct rte_flow_error *error,
-					   union i40e_filter_t *filter);
+					   struct i40e_filter_ctx *filter);
 const struct rte_flow_ops i40e_flow_ops = {
 	.validate = i40e_flow_validate,
 	.create = i40e_flow_create,
@@ -145,8 +145,6 @@ const struct rte_flow_ops i40e_flow_ops = {
 	.query = i40e_flow_query,
 };
 
-static union i40e_filter_t cons_filter;
-static enum rte_filter_type cons_filter_type = RTE_ETH_FILTER_NONE;
 /* internal pattern w/o VOID items */
 struct rte_flow_item g_items[32];
 
@@ -1454,10 +1452,9 @@ i40e_flow_parse_ethertype_filter(struct rte_eth_dev *dev,
 				 const struct rte_flow_item pattern[],
 				 const struct rte_flow_action actions[],
 				 struct rte_flow_error *error,
-				 union i40e_filter_t *filter)
+				 struct i40e_filter_ctx *filter)
 {
-	struct rte_eth_ethertype_filter *ethertype_filter =
-		&filter->ethertype_filter;
+	struct rte_eth_ethertype_filter *ethertype_filter = &filter->ethertype_filter;
 	int ret;
 
 	ret = i40e_flow_parse_ethertype_pattern(dev, pattern, error,
@@ -1474,7 +1471,7 @@ i40e_flow_parse_ethertype_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_ETHERTYPE;
+	filter->type = RTE_ETH_FILTER_ETHERTYPE;
 
 	return ret;
 }
@@ -2549,7 +2546,7 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 			    const struct rte_flow_item pattern[],
 			    const struct rte_flow_action actions[],
 			    struct rte_flow_error *error,
-			    union i40e_filter_t *filter)
+			    struct i40e_filter_ctx *filter)
 {
 	struct i40e_fdir_filter_conf *fdir_filter = &filter->fdir_filter;
 	int ret;
@@ -2566,7 +2563,7 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_FDIR;
+	filter->type = RTE_ETH_FILTER_FDIR;
 
 	return 0;
 }
@@ -2834,10 +2831,9 @@ i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,
 				const struct rte_flow_item pattern[],
 				const struct rte_flow_action actions[],
 				struct rte_flow_error *error,
-				union i40e_filter_t *filter)
+				struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_l4_pattern(pattern, error, tunnel_filter);
@@ -2852,7 +2848,7 @@ i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
@@ -3086,10 +3082,9 @@ i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 			     const struct rte_flow_item pattern[],
 			     const struct rte_flow_action actions[],
 			     struct rte_flow_error *error,
-			     union i40e_filter_t *filter)
+			     struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_vxlan_pattern(dev, pattern,
@@ -3105,7 +3100,7 @@ i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
@@ -3338,10 +3333,9 @@ i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
 			     const struct rte_flow_item pattern[],
 			     const struct rte_flow_action actions[],
 			     struct rte_flow_error *error,
-			     union i40e_filter_t *filter)
+			     struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_nvgre_pattern(dev, pattern,
@@ -3357,7 +3351,7 @@ i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
@@ -3495,10 +3489,9 @@ i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
 			    const struct rte_flow_item pattern[],
 			    const struct rte_flow_action actions[],
 			    struct rte_flow_error *error,
-			    union i40e_filter_t *filter)
+			    struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_mpls_pattern(dev, pattern,
@@ -3514,7 +3507,7 @@ i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
@@ -3648,10 +3641,9 @@ i40e_flow_parse_gtp_filter(struct rte_eth_dev *dev,
 			   const struct rte_flow_item pattern[],
 			   const struct rte_flow_action actions[],
 			   struct rte_flow_error *error,
-			   union i40e_filter_t *filter)
+			   struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_gtp_pattern(dev, pattern,
@@ -3667,7 +3659,7 @@ i40e_flow_parse_gtp_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
@@ -3766,10 +3758,9 @@ i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
 			      const struct rte_flow_item pattern[],
 			      const struct rte_flow_action actions[],
 			      struct rte_flow_error *error,
-			      union i40e_filter_t *filter)
+			      struct i40e_filter_ctx *filter)
 {
-	struct i40e_tunnel_filter_conf *tunnel_filter =
-		&filter->consistent_tunnel_filter;
+	struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
 	int ret;
 
 	ret = i40e_flow_parse_qinq_pattern(dev, pattern,
@@ -3785,16 +3776,17 @@ i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
 	if (ret)
 		return ret;
 
-	cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+	filter->type = RTE_ETH_FILTER_TUNNEL;
 
 	return ret;
 }
 
 static int
-i40e_flow_validate(struct rte_eth_dev *dev,
+i40e_flow_check(struct rte_eth_dev *dev,
 		   const struct rte_flow_attr *attr,
 		   const struct rte_flow_item pattern[],
 		   const struct rte_flow_action actions[],
+		   struct i40e_filter_ctx *filter_ctx,
 		   struct rte_flow_error *error)
 {
 	struct rte_flow_item *items; /* internal pattern w/o VOID items */
@@ -3823,7 +3815,6 @@ i40e_flow_validate(struct rte_eth_dev *dev,
 				   NULL, "NULL attribute.");
 		return -rte_errno;
 	}
-	memset(&cons_filter, 0, sizeof(cons_filter));
 
 	/* Get the non-void item of action */
 	while ((actions + i)->type == RTE_FLOW_ACTION_TYPE_VOID)
@@ -3834,9 +3825,8 @@ i40e_flow_validate(struct rte_eth_dev *dev,
 		if (ret)
 			return ret;
 
-		cons_filter_type = RTE_ETH_FILTER_HASH;
-		return i40e_hash_parse(dev, pattern, actions + i,
-				       &cons_filter.rss_conf, error);
+		filter_ctx->type = RTE_ETH_FILTER_HASH;
+		return i40e_hash_parse(dev, pattern, actions + i, &filter_ctx->rss_conf, error);
 	}
 
 	i = 0;
@@ -3878,8 +3868,7 @@ i40e_flow_validate(struct rte_eth_dev *dev,
 		}
 
 		if (parse_filter)
-			ret = parse_filter(dev, attr, items, actions,
-					   error, &cons_filter);
+			ret = parse_filter(dev, attr, items, actions, error, filter_ctx);
 
 		flag = true;
 	} while ((ret < 0) && (i < RTE_DIM(i40e_supported_patterns)));
@@ -3890,6 +3879,19 @@ i40e_flow_validate(struct rte_eth_dev *dev,
 	return ret;
 }
 
+static int
+i40e_flow_validate(struct rte_eth_dev *dev,
+		   const struct rte_flow_attr *attr,
+		   const struct rte_flow_item pattern[],
+		   const struct rte_flow_action actions[],
+		   struct rte_flow_error *error)
+{
+	/* creates dummy context */
+	struct i40e_filter_ctx filter_ctx = {0};
+
+	return i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error);
+}
+
 static struct rte_flow *
 i40e_flow_create(struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr,
@@ -3898,15 +3900,16 @@ i40e_flow_create(struct rte_eth_dev *dev,
 		 struct rte_flow_error *error)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_filter_ctx filter_ctx = {0};
 	struct rte_flow *flow = NULL;
 	struct i40e_fdir_info *fdir_info = &pf->fdir;
 	int ret;
 
-	ret = i40e_flow_validate(dev, attr, pattern, actions, error);
+	ret = i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error);
 	if (ret < 0)
 		return NULL;
 
-	if (cons_filter_type == RTE_ETH_FILTER_FDIR) {
+	if (filter_ctx.type == RTE_ETH_FILTER_FDIR) {
 		/* if this is the first time we're creating an fdir flow */
 		if (pf->fdir.fdir_vsi == NULL) {
 			ret = i40e_fdir_setup(pf);
@@ -3947,18 +3950,16 @@ i40e_flow_create(struct rte_eth_dev *dev,
 		}
 	}
 
-	switch (cons_filter_type) {
+	switch (filter_ctx.type) {
 	case RTE_ETH_FILTER_ETHERTYPE:
-		ret = i40e_ethertype_filter_set(pf,
-					&cons_filter.ethertype_filter, 1);
+		ret = i40e_ethertype_filter_set(pf, &filter_ctx.ethertype_filter, 1);
 		if (ret)
 			goto free_flow;
 		flow->rule = TAILQ_LAST(&pf->ethertype.ethertype_list,
 					i40e_ethertype_filter_list);
 		break;
 	case RTE_ETH_FILTER_FDIR:
-		ret = i40e_flow_add_del_fdir_filter(dev,
-			       &cons_filter.fdir_filter, 1);
+		ret = i40e_flow_add_del_fdir_filter(dev, &filter_ctx.fdir_filter, 1);
 		if (ret)
 			goto free_flow;
 		flow->rule = TAILQ_LAST(&pf->fdir.fdir_list,
@@ -3966,14 +3967,14 @@ i40e_flow_create(struct rte_eth_dev *dev,
 		break;
 	case RTE_ETH_FILTER_TUNNEL:
 		ret = i40e_dev_consistent_tunnel_filter_set(pf,
-			    &cons_filter.consistent_tunnel_filter, 1);
+				&filter_ctx.consistent_tunnel_filter, 1);
 		if (ret)
 			goto free_flow;
 		flow->rule = TAILQ_LAST(&pf->tunnel.tunnel_list,
 					i40e_tunnel_filter_list);
 		break;
 	case RTE_ETH_FILTER_HASH:
-		ret = i40e_hash_filter_create(pf, &cons_filter.rss_conf);
+		ret = i40e_hash_filter_create(pf, &filter_ctx.rss_conf);
 		if (ret)
 			goto free_flow;
 		flow->rule = TAILQ_LAST(&pf->rss_config_list,
@@ -3983,7 +3984,7 @@ i40e_flow_create(struct rte_eth_dev *dev,
 		goto free_flow;
 	}
 
-	flow->filter_type = cons_filter_type;
+	flow->filter_type = filter_ctx.type;
 	TAILQ_INSERT_TAIL(&pf->flow_list, flow, node);
 	return flow;
 
@@ -3992,7 +3993,7 @@ i40e_flow_create(struct rte_eth_dev *dev,
 			   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
 			   "Failed to create flow.");
 
-	if (cons_filter_type != RTE_ETH_FILTER_FDIR)
+	if (filter_ctx.type != RTE_ETH_FILTER_FDIR)
 		rte_free(flow);
 	else
 		i40e_fdir_entry_pool_put(fdir_info, flow);
-- 
2.47.3



More information about the dev mailing list