net/mlx5: fix tunnel header with IPIP offload

Message ID 20221020125534.37363-1-jiaweiw@nvidia.com (mailing list archive)
State Accepted, archived
Delegated to: Raslan Darawsheh
Headers
Series net/mlx5: fix tunnel header with IPIP offload |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/github-robot: build success github build: passed
ci/intel-Testing success Testing PASS

Commit Message

Jiawei Wang Oct. 20, 2022, 12:55 p.m. UTC
  For the flows with multiple tunnel layers and containing
tunnel decap and modify actions, for example:

... / vxlan / eth / ipv4 proto is 4 / end
actions raw_decap / modify_field / ...
(note: proto 4 means we have the IP-over-IP tunnel in VXLAN payload)

We have added the multiple tunnel layers validation rejecting
the flows like above mentioned one.

The hardware supports the above match combination till the inner
IP-over-IP header (not including the last one), both for IP-over-IPv4
and IP-over-IPv6, so we should not blindly reject. Also, for the modify
actions following the decap we should set the layer attributes correctly.

This patch reverts the below code changes to support the match, and
adjusts the layers update in case of decap with outer tunnel header.

Fixes: fa06906a48ee ("net/mlx5: fix IPIP multi-tunnel validation")
Cc: stable@dpdk.org

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Slava Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    |  4 ++--
 drivers/net/mlx5/mlx5_flow_dv.c | 11 ++++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)
  

Comments

Raslan Darawsheh Oct. 25, 2022, 1:53 p.m. UTC | #1
Hi,

> -----Original Message-----
> From: Jiawei(Jonny) Wang <jiaweiw@nvidia.com>
> Sent: Thursday, October 20, 2022 3:56 PM
> To: Slava Ovsiienko <viacheslavo@nvidia.com>; Matan Azrad
> <matan@nvidia.com>; Ori Kam <orika@nvidia.com>; Raslan Darawsheh
> <rasland@nvidia.com>; Lior Margalit <lmargalit@nvidia.com>
> Cc: dev@dpdk.org; stable@dpdk.org
> Subject: [PATCH] net/mlx5: fix tunnel header with IPIP offload
> 
> For the flows with multiple tunnel layers and containing tunnel decap and
> modify actions, for example:
> 
> ... / vxlan / eth / ipv4 proto is 4 / end actions raw_decap / modify_field / ...
> (note: proto 4 means we have the IP-over-IP tunnel in VXLAN payload)
> 
> We have added the multiple tunnel layers validation rejecting the flows like
> above mentioned one.
> 
> The hardware supports the above match combination till the inner IP-over-IP
> header (not including the last one), both for IP-over-IPv4 and IP-over-IPv6,
> so we should not blindly reject. Also, for the modify actions following the
> decap we should set the layer attributes correctly.
> 
> This patch reverts the below code changes to support the match, and adjusts
> the layers update in case of decap with outer tunnel header.
> 
> Fixes: fa06906a48ee ("net/mlx5: fix IPIP multi-tunnel validation")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
> Acked-by: Slava Ovsiienko <viacheslavo@nvidia.com>

Patch applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 06b465de7a..7ebe67028d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2512,7 +2512,7 @@  mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "IPv4 cannot follow L2/VLAN layer "
 					  "which ether type is not IPv4");
-	if (item_flags & MLX5_FLOW_LAYER_TUNNEL) {
+	if (item_flags & MLX5_FLOW_LAYER_IPIP) {
 		if (mask && spec)
 			next_proto = mask->hdr.next_proto_id &
 				     spec->hdr.next_proto_id;
@@ -2620,7 +2620,7 @@  mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
 					  "which ether type is not IPv6");
 	if (mask && mask->hdr.proto == UINT8_MAX && spec)
 		next_proto = spec->hdr.proto;
-	if (item_flags & MLX5_FLOW_LAYER_TUNNEL) {
+	if (item_flags & MLX5_FLOW_LAYER_IPIP) {
 		if (next_proto == IPPROTO_IPIP || next_proto == IPPROTO_IPV6)
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ITEM,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 4bdcb1815b..bf093ab981 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -109,6 +109,7 @@  flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
 		  struct mlx5_flow *dev_flow, bool tunnel_decap)
 {
 	uint64_t layers = dev_flow->handle->layers;
+	bool tunnel_match = false;
 
 	/*
 	 * If layers is already initialized, it means this dev_flow is the
@@ -145,8 +146,10 @@  flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
 		case RTE_FLOW_ITEM_TYPE_GENEVE:
 		case RTE_FLOW_ITEM_TYPE_MPLS:
 		case RTE_FLOW_ITEM_TYPE_GTP:
-			if (tunnel_decap)
+			if (tunnel_decap) {
 				attr->attr = 0;
+				tunnel_match = true;
+			}
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV4:
 			if (!attr->ipv6)
@@ -160,7 +163,8 @@  flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
 				    ((const struct rte_flow_item_ipv4 *)
 				      (item->mask))->hdr.next_proto_id;
 			if ((next_protocol == IPPROTO_IPIP ||
-			    next_protocol == IPPROTO_IPV6) && tunnel_decap)
+			    next_protocol == IPPROTO_IPV6) && tunnel_decap &&
+			    !tunnel_match)
 				attr->attr = 0;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
@@ -175,7 +179,8 @@  flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
 				    ((const struct rte_flow_item_ipv6 *)
 				      (item->mask))->hdr.proto;
 			if ((next_protocol == IPPROTO_IPIP ||
-			    next_protocol == IPPROTO_IPV6) && tunnel_decap)
+			    next_protocol == IPPROTO_IPV6) && tunnel_decap &&
+			    !tunnel_match)
 				attr->attr = 0;
 			break;
 		case RTE_FLOW_ITEM_TYPE_UDP: