git: 138873b604ae - main - fixup! IB/mlx5: Support Vxlan tunneling specification

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 16 Sep 2026 14:12:59 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=138873b604aeb5062813a85f60e1fbec7095e1c2

commit 138873b604aeb5062813a85f60e1fbec7095e1c2
Author:     Ariel Ehrenberg <aehrenberg@nvidia.com>
AuthorDate: 2026-07-28 12:02:44 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-16 14:12:08 +0000

    fixup! IB/mlx5: Support Vxlan tunneling specification
    
    Import Linux upstream commits 37da2a03c036 ("RDMA/mlx5: Use proper spec
    flow label type") and 0f750966dca8 ("IB/mlx5: Add inner spec and IPv6
    validation in user's flow attribute list").
    
    The first widens set_flow_label()'s mask and value to u32, so the 20-bit
    IPv6 flow label is no longer truncated to 8 bits.  The second validates
    the ethertype of inner flow specs as well as outer ones, and adds the IPv6
    ethertype checking this tree was missing.
    
    Sponsored by:   NVidia networking
    MFC after:      1 month
---
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c | 46 ++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index 81bd1a66294d..658bbd1a39ff 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -1903,7 +1903,7 @@ static void set_proto(void *outer_c, void *outer_v, u8 mask, u8 val)
 	MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val);
 }
 
-static void set_flow_label(void *misc_c, void *misc_v, u8 mask, u8 val,
+static void set_flow_label(void *misc_c, void *misc_v, u32 mask, u32 val,
 			   bool inner)
 {
 	if (inner) {
@@ -2171,26 +2171,50 @@ static bool flow_is_multicast_only(struct ib_flow_attr *ib_attr)
 	       is_multicast_ether_addr(eth_spec->val.dst_mac);
 }
 
-static bool is_valid_attr(const struct ib_flow_attr *flow_attr)
+static bool is_valid_ethertype(const struct ib_flow_attr *flow_attr,
+			       bool check_inner)
 {
 	union ib_flow_spec *ib_spec = (union ib_flow_spec *)(flow_attr + 1);
-	bool has_ipv4_spec = false;
-	bool eth_type_ipv4 = true;
+	int inner_bit = check_inner ? IB_FLOW_SPEC_INNER : 0;
+	bool ipv4_spec_valid, ipv6_spec_valid;
+	unsigned int ip_spec_type = 0;
+	bool has_ethertype = false;
 	unsigned int spec_index;
+	bool mask_valid = true;
+	u16 eth_type = 0;
+	bool type_valid;
 
 	/* Validate that ethertype is correct */
 	for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
-		if (ib_spec->type == IB_FLOW_SPEC_ETH &&
+		if ((ib_spec->type == (IB_FLOW_SPEC_ETH | inner_bit)) &&
 		    ib_spec->eth.mask.ether_type) {
-			if (!((ib_spec->eth.mask.ether_type == htons(0xffff)) &&
-			      ib_spec->eth.val.ether_type == htons(ETH_P_IP)))
-				eth_type_ipv4 = false;
-		} else if (ib_spec->type == IB_FLOW_SPEC_IPV4) {
-			has_ipv4_spec = true;
+			mask_valid = (ib_spec->eth.mask.ether_type ==
+				      htons(0xffff));
+			has_ethertype = true;
+			eth_type = ntohs(ib_spec->eth.val.ether_type);
+		} else if ((ib_spec->type == (IB_FLOW_SPEC_IPV4 | inner_bit)) ||
+			   (ib_spec->type == (IB_FLOW_SPEC_IPV6 | inner_bit))) {
+			ip_spec_type = ib_spec->type;
 		}
 		ib_spec = (void *)ib_spec + ib_spec->size;
 	}
-	return !has_ipv4_spec || eth_type_ipv4;
+
+	type_valid = (!has_ethertype) || (!ip_spec_type);
+	if (!type_valid && mask_valid) {
+		ipv4_spec_valid = (eth_type == ETH_P_IP) &&
+			(ip_spec_type == (IB_FLOW_SPEC_IPV4 | inner_bit));
+		ipv6_spec_valid = (eth_type == ETH_P_IPV6) &&
+			(ip_spec_type == (IB_FLOW_SPEC_IPV6 | inner_bit));
+		type_valid = ipv4_spec_valid || ipv6_spec_valid;
+	}
+
+	return type_valid;
+}
+
+static bool is_valid_attr(const struct ib_flow_attr *flow_attr)
+{
+	return is_valid_ethertype(flow_attr, false) &&
+	       is_valid_ethertype(flow_attr, true);
 }
 
 static void put_flow_table(struct mlx5_ib_dev *dev,