Skip to content

Commit

Permalink
net/mlx5: fix tunnel header with IPIP offload
Browse files Browse the repository at this point in the history
[ upstream commit bfa87e2 ]

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: fa06906 ("net/mlx5: fix IPIP multi-tunnel validation")

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
  • Loading branch information
jiaweiwsz authored and kevintraynor committed Nov 7, 2022
1 parent 2356e48 commit ee2387b
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
4 changes: 2 additions & 2 deletions drivers/net/mlx5/mlx5_flow.c
Expand Up @@ -2356,7 +2356,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;
Expand Down Expand Up @@ -2464,7 +2464,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,
Expand Down
11 changes: 8 additions & 3 deletions drivers/net/mlx5/mlx5_flow_dv.c
Expand Up @@ -113,6 +113,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
Expand Down Expand Up @@ -149,8 +150,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)
Expand All @@ -164,7 +167,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:
Expand All @@ -179,7 +183,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:
Expand Down

0 comments on commit ee2387b

Please sign in to comment.