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 <[email protected]>
---
 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

Reply via email to