Support GRE tunnel type flow.

Signed-off-by: Xueming Li <xuemi...@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.c | 69 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 394760418..026952b46 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -87,6 +87,11 @@ mlx5_flow_create_vxlan(const struct rte_flow_item *item,
                       const void *default_mask,
                       struct mlx5_flow_data *data);
 
+static int
+mlx5_flow_create_gre(const struct rte_flow_item *item,
+                      const void *default_mask,
+                      struct mlx5_flow_data *data);
+
 struct mlx5_flow_parse;
 
 static void
@@ -229,6 +234,10 @@ struct rte_flow {
                __VA_ARGS__, RTE_FLOW_ITEM_TYPE_END, \
        }
 
+#define IS_TUNNEL(type) ( \
+       (type) == RTE_FLOW_ITEM_TYPE_VXLAN || \
+       (type) == RTE_FLOW_ITEM_TYPE_GRE)
+
 /** Structure to generate a simple graph of layers supported by the NIC. */
 struct mlx5_flow_items {
        /** List of possible actions for these items. */
@@ -282,7 +291,8 @@ static const enum rte_flow_action_type valid_actions[] = {
 static const struct mlx5_flow_items mlx5_flow_items[] = {
        [RTE_FLOW_ITEM_TYPE_END] = {
                .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH,
-                              RTE_FLOW_ITEM_TYPE_VXLAN),
+                              RTE_FLOW_ITEM_TYPE_VXLAN,
+                              RTE_FLOW_ITEM_TYPE_GRE),
        },
        [RTE_FLOW_ITEM_TYPE_ETH] = {
                .items = ITEMS(RTE_FLOW_ITEM_TYPE_VLAN,
@@ -314,7 +324,8 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
        },
        [RTE_FLOW_ITEM_TYPE_IPV4] = {
                .items = ITEMS(RTE_FLOW_ITEM_TYPE_UDP,
-                              RTE_FLOW_ITEM_TYPE_TCP),
+                              RTE_FLOW_ITEM_TYPE_TCP,
+                              RTE_FLOW_ITEM_TYPE_GRE),
                .actions = valid_actions,
                .mask = &(const struct rte_flow_item_ipv4){
                        .hdr = {
@@ -331,7 +342,8 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
        },
        [RTE_FLOW_ITEM_TYPE_IPV6] = {
                .items = ITEMS(RTE_FLOW_ITEM_TYPE_UDP,
-                              RTE_FLOW_ITEM_TYPE_TCP),
+                              RTE_FLOW_ITEM_TYPE_TCP,
+                              RTE_FLOW_ITEM_TYPE_GRE),
                .actions = valid_actions,
                .mask = &(const struct rte_flow_item_ipv6){
                        .hdr = {
@@ -384,6 +396,19 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
                .convert = mlx5_flow_create_tcp,
                .dst_sz = sizeof(struct ibv_flow_spec_tcp_udp),
        },
+       [RTE_FLOW_ITEM_TYPE_GRE] = {
+               .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH,
+                              RTE_FLOW_ITEM_TYPE_IPV4,
+                              RTE_FLOW_ITEM_TYPE_IPV6),
+               .actions = valid_actions,
+               .mask = &(const struct rte_flow_item_gre){
+                       .protocol = -1,
+               },
+               .default_mask = &rte_flow_item_gre_mask,
+               .mask_sz = sizeof(struct rte_flow_item_gre),
+               .convert = mlx5_flow_create_gre,
+               .dst_sz = sizeof(struct ibv_flow_spec_tunnel),
+       },
        [RTE_FLOW_ITEM_TYPE_VXLAN] = {
                .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH),
                .actions = valid_actions,
@@ -399,7 +424,7 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
 
 /** Structure to pass to the conversion function. */
 struct mlx5_flow_parse {
-       uint32_t inner; /**< Set once VXLAN is encountered. */
+       uint32_t inner; /**< Verbs value, set once tunnel is encountered. */
        uint32_t create:1;
        /**< Whether resources should remain after a validate. */
        uint32_t drop:1; /**< Target is a drop queue. */
@@ -832,13 +857,13 @@ mlx5_flow_convert_items_validate(const struct 
rte_flow_item items[],
                                              cur_item->mask_sz);
                if (ret)
                        goto exit_item_not_supported;
-               if (items->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
+               if (IS_TUNNEL(items->type)) {
                        if (parser->inner) {
                                rte_flow_error_set(error, ENOTSUP,
                                                   RTE_FLOW_ERROR_TYPE_ITEM,
                                                   items,
-                                                  "cannot recognize multiple"
-                                                  " VXLAN encapsulations");
+                                                  "Cannot recognize multiple"
+                                                  " tunnel encapsulations.");
                                return -rte_errno;
                        }
                        parser->inner = IBV_FLOW_SPEC_INNER;
@@ -1634,6 +1659,36 @@ mlx5_flow_create_vxlan(const struct rte_flow_item *item,
 }
 
 /**
+ * Convert GRE item to Verbs specification.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param default_mask[in]
+ *   Default bit-masks to use when item->mask is not provided.
+ * @param data[in, out]
+ *   User structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_create_gre(const struct rte_flow_item *item __rte_unused,
+                    const void *default_mask __rte_unused,
+                    struct mlx5_flow_data *data)
+{
+       struct mlx5_flow_parse *parser = data->parser;
+       unsigned int size = sizeof(struct ibv_flow_spec_tunnel);
+       struct ibv_flow_spec_tunnel tunnel = {
+               .type = parser->inner | IBV_FLOW_SPEC_VXLAN_TUNNEL,
+               .size = size,
+       };
+
+       parser->inner = IBV_FLOW_SPEC_INNER;
+       mlx5_flow_create_copy(parser, &tunnel, size);
+       return 0;
+}
+
+/**
  * Convert mark/flag action to Verbs specification.
  *
  * @param parser
-- 
2.13.3

Reply via email to