support matching on the present bits (C,K,S)
as well as the optional key field.

If the rte_flow_item_gre_key is specified in pattern,
it will set K present match automatically.

Signed-off-by: Xiaoyu Min <jack...@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 49 +++++++++++++++++++-
 drivers/net/mlx5/mlx5_flow.h    |  5 +++
 drivers/net/mlx5/mlx5_flow_dv.c | 80 +++++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_prm.h     |  6 ++-
 4 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 4cb04c32ff..4f0583eead 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1564,6 +1564,49 @@ mlx5_flow_validate_item_vxlan_gpe(const struct 
rte_flow_item *item,
                                          " defined");
        return 0;
 }
+/**
+ * Validate GRE Key item.
+ *
+ * @param[in] item
+ *   Item specification.
+ * @param[in] item_flags
+ *   Bit flags to mark detected items.
+ * @param[in] target_protocol
+ *   The next protocol in the previous item.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_flow_validate_item_gre_key(const struct rte_flow_item *item,
+                                   uint64_t item_flags,
+                                   struct rte_flow_error *error)
+{
+       const struct rte_flow_item_gre_key *mask = item->mask;
+       int ret = 0;
+
+       if (item_flags & MLX5_FLOW_LAYER_GRE_KEY)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
+                                         "Multiple GRE key not support");
+       if (!(item_flags & MLX5_FLOW_LAYER_GRE))
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
+                                         "No preceding GRE header");
+       if (item_flags & MLX5_FLOW_LAYER_INNER)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM, item,
+                                         "GRE key following a wrong item");
+       if (!mask)
+               mask = &rte_flow_item_gre_key_mask;
+       ret = mlx5_flow_item_acceptable
+               (item, (const uint8_t *)mask,
+                (const uint8_t *)&rte_flow_item_gre_key_mask,
+                sizeof(struct rte_flow_item_gre_key), error);
+       return ret;
+}
 
 /**
  * Validate GRE item.
@@ -1589,6 +1632,10 @@ mlx5_flow_validate_item_gre(const struct rte_flow_item 
*item,
        const struct rte_flow_item_gre *spec __rte_unused = item->spec;
        const struct rte_flow_item_gre *mask = item->mask;
        int ret;
+       const struct rte_flow_item_gre nic_mask = {
+               .c_rsvd0_ver = RTE_BE16(0xB000),
+               .protocol = RTE_BE16(UINT16_MAX),
+       };
 
        if (target_protocol != 0xff && target_protocol != IPPROTO_GRE)
                return rte_flow_error_set(error, EINVAL,
@@ -1608,7 +1655,7 @@ mlx5_flow_validate_item_gre(const struct rte_flow_item 
*item,
                mask = &rte_flow_item_gre_mask;
        ret = mlx5_flow_item_acceptable
                (item, (const uint8_t *)mask,
-                (const uint8_t *)&rte_flow_item_gre_mask,
+                (const uint8_t *)&nic_mask,
                 sizeof(struct rte_flow_item_gre), error);
        if (ret < 0)
                return ret;
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index b6654200cb..0d83539cc9 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -50,6 +50,8 @@
 #define MLX5_FLOW_ITEM_METADATA (1u << 16)
 #define MLX5_FLOW_ITEM_PORT_ID (1u << 17)
 
+#define MLX5_FLOW_LAYER_GRE_KEY (1u << 18)
+
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
        (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
@@ -480,6 +482,9 @@ int mlx5_flow_validate_item_gre(const struct rte_flow_item 
*item,
                                uint64_t item_flags,
                                uint8_t target_protocol,
                                struct rte_flow_error *error);
+int mlx5_flow_validate_item_gre_key(const struct rte_flow_item *item,
+                                   uint64_t item_flags,
+                                   struct rte_flow_error *error);
 int mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
                                 uint64_t item_flags,
                                 const struct rte_flow_item_ipv4 *acc_mask,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 933ad0b819..eca926d670 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2177,6 +2177,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct 
rte_flow_attr *attr,
                                return ret;
                        last_item = MLX5_FLOW_LAYER_GRE;
                        break;
+               case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+                       ret = mlx5_flow_validate_item_gre_key
+                               (items, item_flags, error);
+                       if (ret < 0)
+                               return ret;
+                       item_flags |= MLX5_FLOW_LAYER_GRE_KEY;
+                       break;
                case RTE_FLOW_ITEM_TYPE_VXLAN:
                        ret = mlx5_flow_validate_item_vxlan(items, item_flags,
                                                            error);
@@ -2922,6 +2929,43 @@ flow_dv_translate_item_udp(void *matcher, void *key,
                 rte_be_to_cpu_16(udp_v->hdr.dst_port & udp_m->hdr.dst_port));
 }
 
+/**
+ * Add GRE optional Key item to matcher and to the value.
+ *
+ * @param[in, out] matcher
+ *   Flow matcher.
+ * @param[in, out] key
+ *   Flow matcher value.
+ * @param[in] item
+ *   Flow pattern to translate.
+ * @param[in] inner
+ *   Item is inner pattern.
+ */
+static void
+flow_dv_translate_item_gre_key(void *matcher, void *key,
+                                  const struct rte_flow_item *item)
+{
+       const struct rte_flow_item_gre_key *key_m = item->mask;
+       const struct rte_flow_item_gre_key *key_v = item->spec;
+       void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters);
+       void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+
+       if (!key_v)
+               return;
+       if (!key_m)
+               key_m = &rte_flow_item_gre_key_mask;
+       MLX5_SET(fte_match_set_misc, misc_m, gre_k_present, 1);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_k_present, 1);
+       MLX5_SET(fte_match_set_misc, misc_m, gre_key_h,
+                rte_be_to_cpu_32(key_m->key) >> 8);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_key_h,
+                rte_be_to_cpu_32(key_v->key & key_m->key) >> 8);
+       MLX5_SET(fte_match_set_misc, misc_m, gre_key_l,
+                rte_be_to_cpu_32(key_m->key) & 0xFF);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_key_l,
+                rte_be_to_cpu_32(key_v->key & key_m->key) & 0xFF);
+}
+
 /**
  * Add GRE item to matcher and to the value.
  *
@@ -2945,6 +2989,20 @@ flow_dv_translate_item_gre(void *matcher, void *key,
        void *headers_v;
        void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters);
        void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+       struct {
+               union {
+                       __extension__
+                       struct {
+                               uint16_t version:3;
+                               uint16_t rsvd0:9;
+                               uint16_t s_present:1;
+                               uint16_t k_present:1;
+                               uint16_t rsvd_bit1:1;
+                               uint16_t c_present:1;
+                       };
+                       uint16_t value;
+               };
+       } gre_crks_rsvd0_ver_m, gre_crks_rsvd0_ver_v;
 
        if (inner) {
                headers_m = MLX5_ADDR_OF(fte_match_param, matcher,
@@ -2965,6 +3023,23 @@ flow_dv_translate_item_gre(void *matcher, void *key,
                 rte_be_to_cpu_16(gre_m->protocol));
        MLX5_SET(fte_match_set_misc, misc_v, gre_protocol,
                 rte_be_to_cpu_16(gre_v->protocol & gre_m->protocol));
+       gre_crks_rsvd0_ver_m.value = rte_be_to_cpu_16(gre_m->c_rsvd0_ver);
+       gre_crks_rsvd0_ver_v.value = rte_be_to_cpu_16(gre_v->c_rsvd0_ver);
+       MLX5_SET(fte_match_set_misc, misc_m, gre_c_present,
+                gre_crks_rsvd0_ver_m.c_present);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_c_present,
+                gre_crks_rsvd0_ver_v.c_present &
+                gre_crks_rsvd0_ver_m.c_present);
+       MLX5_SET(fte_match_set_misc, misc_m, gre_k_present,
+                gre_crks_rsvd0_ver_m.k_present);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_k_present,
+                gre_crks_rsvd0_ver_v.k_present &
+                gre_crks_rsvd0_ver_m.k_present);
+       MLX5_SET(fte_match_set_misc, misc_m, gre_s_present,
+                gre_crks_rsvd0_ver_m.s_present);
+       MLX5_SET(fte_match_set_misc, misc_v, gre_s_present,
+                gre_crks_rsvd0_ver_v.s_present &
+                gre_crks_rsvd0_ver_m.s_present);
 }
 
 /**
@@ -3995,6 +4070,11 @@ flow_dv_translate(struct rte_eth_dev *dev,
                                                   items, tunnel);
                        last_item = MLX5_FLOW_LAYER_GRE;
                        break;
+               case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+                       flow_dv_translate_item_gre_key(match_mask,
+                                                          match_value, items);
+                       item_flags |= MLX5_FLOW_LAYER_GRE_KEY;
+                       break;
                case RTE_FLOW_ITEM_TYPE_NVGRE:
                        flow_dv_translate_item_nvgre(match_mask, match_value,
                                                     items, tunnel);
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index 1a199580c5..4022770b7b 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -416,7 +416,11 @@ typedef uint8_t u8;
 #define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8)
 
 struct mlx5_ifc_fte_match_set_misc_bits {
-       u8 reserved_at_0[0x8];
+       u8 gre_c_present[0x1];
+       u8 reserved_at_1[0x1];
+       u8 gre_k_present[0x1];
+       u8 gre_s_present[0x1];
+       u8 source_vhci_port[0x4];
        u8 source_sqn[0x18];
        u8 reserved_at_20[0x10];
        u8 source_port[0x10];
-- 
2.21.0

Reply via email to