[dpdk-dev,v3,02/14] net/mlx5: support GRE tunnel flow

Message ID 20180413112023.106420-3-xuemingl@mellanox.com (mailing list archive)
State Superseded, archived
Delegated to: Shahaf Shuler
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply patch file failure

Commit Message

Xueming Li April 13, 2018, 11:20 a.m. UTC
  Support GRE tunnel type flow.

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

Comments

Nélio Laranjeiro April 13, 2018, 12:02 p.m. UTC | #1
Some nits,

On Fri, Apr 13, 2018 at 07:20:11PM +0800, Xueming Li wrote:
> Support GRE tunnel type flow.

Not sure it is necessary to copy/paste the commit title in the body.

> Signed-off-by: Xueming Li <xuemingl@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 5c4f0b586..2aae988f2 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -90,6 +90,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);
> +

Is not there an indentation issue here?

>  struct mlx5_flow_parse;
>  
>  static void
> @@ -232,6 +237,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. */
> @@ -285,7 +294,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,
> @@ -317,7 +327,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 = {
> @@ -334,7 +345,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 = {
> @@ -387,6 +399,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,
> @@ -402,7 +427,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. */
> @@ -830,13 +855,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;
> @@ -1644,6 +1669,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

Thanks,
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 5c4f0b586..2aae988f2 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -90,6 +90,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
@@ -232,6 +237,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. */
@@ -285,7 +294,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,
@@ -317,7 +327,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 = {
@@ -334,7 +345,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 = {
@@ -387,6 +399,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,
@@ -402,7 +427,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. */
@@ -830,13 +855,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;
@@ -1644,6 +1669,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