Support GRE tunnel type in RTE FLOW.

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

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 26002c4..2acd42b 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -79,6 +79,11 @@ struct ibv_flow_spec_counter_action {
                       const void *default_mask,
                       void *data);
 
+static int
+mlx5_flow_create_gre(const struct rte_flow_item *item,
+                      const void *default_mask,
+                      void *data);
+
 struct mlx5_flow_parse;
 
 static void
@@ -222,6 +227,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. */
@@ -274,7 +283,8 @@ struct mlx5_flow_items {
 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,
@@ -305,7 +315,8 @@ struct 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 = {
@@ -322,7 +333,8 @@ struct 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 = {
@@ -375,6 +387,18 @@ struct 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_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,
@@ -390,7 +414,7 @@ struct 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; /**< Verb spec, 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. */
@@ -815,13 +839,13 @@ struct ibv_spec_header {
                                              cur_item->mask_sz);
                if (err)
                        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;
@@ -1548,6 +1572,35 @@ struct ibv_spec_header {
 }
 
 /**
+ * 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.
+ */
+static int
+mlx5_flow_create_gre(const struct rte_flow_item *item,
+                      const void *default_mask,
+                      void *data)
+{
+       struct mlx5_flow_parse *parser = (struct mlx5_flow_parse *)data;
+       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,
+       };
+
+       (void)item;
+       (void)default_mask;
+       parser->inner = IBV_FLOW_SPEC_INNER;
+       mlx5_flow_create_copy(parser, &tunnel, size);
+       return 0;
+}
+
+/**
  * Convert mark/flag action to Verbs specification.
  *
  * @param parser
-- 
1.8.3.1

Reply via email to