net/mlx5: fix NVGRE matching
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_dv.c
index afaa19c..f1d32bd 100644 (file)
@@ -62,6 +62,9 @@ union flow_dv_attr {
        uint32_t attr;
 };
 
+#define MLX5_FLOW_IPV4_LRO (1 << 0)
+#define MLX5_FLOW_IPV6_LRO (1 << 1)
+
 /**
  * Initialize flow attributes structure according to flow items' types.
  *
@@ -2319,8 +2322,6 @@ flow_dv_create_counter_stat_mem_mng(struct rte_eth_dev *dev, int raws_n)
 {
        struct mlx5_ibv_shared *sh = ((struct mlx5_priv *)
                                        (dev->data->dev_private))->sh;
-       struct mlx5dv_pd dv_pd;
-       struct mlx5dv_obj dv_obj;
        struct mlx5_devx_mkey_attr mkey_attr;
        struct mlx5_counter_stats_mem_mng *mem_mng;
        volatile struct flow_counter_stats *raw_data;
@@ -2344,13 +2345,10 @@ flow_dv_create_counter_stat_mem_mng(struct rte_eth_dev *dev, int raws_n)
                rte_free(mem);
                return NULL;
        }
-       dv_obj.pd.in = sh->pd;
-       dv_obj.pd.out = &dv_pd;
-       mlx5_glue->dv_init_obj(&dv_obj, MLX5DV_OBJ_PD);
        mkey_attr.addr = (uintptr_t)mem;
        mkey_attr.size = size;
        mkey_attr.umem_id = mem_mng->umem->umem_id;
-       mkey_attr.pd = dv_pd.pdn;
+       mkey_attr.pd = sh->pdn;
        mem_mng->dm = mlx5_devx_cmd_mkey_create(sh->ctx, &mkey_attr);
        if (!mem_mng->dm) {
                mlx5_glue->devx_umem_dereg(mem_mng->umem);
@@ -2968,7 +2966,6 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                             MLX5_FLOW_LAYER_OUTER_L4_UDP;
                        break;
                case RTE_FLOW_ITEM_TYPE_GRE:
-               case RTE_FLOW_ITEM_TYPE_NVGRE:
                        ret = mlx5_flow_validate_item_gre(items, item_flags,
                                                          next_protocol, error);
                        if (ret < 0)
@@ -2976,6 +2973,14 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        gre_item = items;
                        last_item = MLX5_FLOW_LAYER_GRE;
                        break;
+               case RTE_FLOW_ITEM_TYPE_NVGRE:
+                       ret = mlx5_flow_validate_item_nvgre(items, item_flags,
+                                                           next_protocol,
+                                                           error);
+                       if (ret < 0)
+                               return ret;
+                       last_item = MLX5_FLOW_LAYER_NVGRE;
+                       break;
                case RTE_FLOW_ITEM_TYPE_GRE_KEY:
                        ret = mlx5_flow_validate_item_gre_key
                                (items, item_flags, gre_item, error);
@@ -3921,7 +3926,21 @@ flow_dv_translate_item_nvgre(void *matcher, void *key,
        int size;
        int i;
 
-       flow_dv_translate_item_gre(matcher, key, item, inner);
+       /* For NVGRE, GRE header fields must be set with defined values. */
+       const struct rte_flow_item_gre gre_spec = {
+               .c_rsvd0_ver = RTE_BE16(0x2000),
+               .protocol = RTE_BE16(RTE_ETHER_TYPE_TEB)
+       };
+       const struct rte_flow_item_gre gre_mask = {
+               .c_rsvd0_ver = RTE_BE16(0xB000),
+               .protocol = RTE_BE16(UINT16_MAX),
+       };
+       const struct rte_flow_item gre_item = {
+               .spec = &gre_spec,
+               .mask = &gre_mask,
+               .last = NULL,
+       };
+       flow_dv_translate_item_gre(matcher, key, &gre_item, inner);
        if (!nvgre_v)
                return;
        if (!nvgre_m)
@@ -5166,13 +5185,27 @@ flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
                                             dv->hash_fields,
                                             (*flow->queue),
                                             flow->rss.queue_num);
-                       if (!hrxq)
+                       if (!hrxq) {
+                               int lro = 0;
+
+                               if (mlx5_lro_on(dev)) {
+                                       if ((dev_flow->layers &
+                                            MLX5_FLOW_LAYER_IPV4_LRO)
+                                           == MLX5_FLOW_LAYER_IPV4_LRO)
+                                               lro = MLX5_FLOW_IPV4_LRO;
+                                       else if ((dev_flow->layers &
+                                                 MLX5_FLOW_LAYER_IPV6_LRO)
+                                                == MLX5_FLOW_LAYER_IPV6_LRO)
+                                               lro = MLX5_FLOW_IPV6_LRO;
+                               }
                                hrxq = mlx5_hrxq_new
                                        (dev, flow->key, MLX5_RSS_HASH_KEY_LEN,
                                         dv->hash_fields, (*flow->queue),
                                         flow->rss.queue_num,
                                         !!(dev_flow->layers &
-                                           MLX5_FLOW_LAYER_TUNNEL));
+                                           MLX5_FLOW_LAYER_TUNNEL), lro);
+                       }
+
                        if (!hrxq) {
                                rte_flow_error_set
                                        (error, rte_errno,