git: d58b41b0f282 - main - IB/mlx5: Expose GRE flow spec to user-kernel ABI header

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

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

commit d58b41b0f28207521ddd916f5746b589bd1faf06
Author:     Vag Singh <vag.singh@oneconvergence.com>
AuthorDate: 2025-08-14 07:03:43 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-16 14:12:10 +0000

    IB/mlx5: Expose GRE flow spec to user-kernel ABI header
    
    [PATCH 29/31] FreeBSD OFED support for DPDK MLX5 PMD
    
    a) Add ib_uverbs_flow_spec_gre to define the rule to match GRE
    encapsulation protocol.
    
    The spec includes the generic specs header, type, size and reserved
    fields while the filter itself is defined as ib_uverbs_flow_gre_filter
    and includes:
    
    - Checksum present bit, key present bit and version bits in a single
    16bit field.
    - Protocol type field - Indicates the ether protocol type of the
    encapsulated payload.
    - Key field - present if key bit is set and contains an application
    specific key value.
    
    b) IB/uverbs: Expose MPLS flow spec to user-kernel ABI header
    Add ib_uverbs_flow_spec_mpls to define the rule to match MPLS
    protocol.
    
    The spec includes the generic specs header, type, size and reserved
    fields while the filter itself is defined as ib_uverbs_flow_mpls_filter
    and includes a single 32bit field named 'label' which consists of:
    Bits 0:19 - The MPLS label.
    Bits 20:22 - Traffic class field.
    Bit 23 - Bottom of stack bit.
    Bits 24:31 - Time to live (TTL) field.
    
    c) IB/mlx5: Add support for GRE flow specification
    This patch introduces support for the GRE flow spec and
    allowing the creation of rules based on the protocol and
    key fields that are part of GRE protocol header.
    
    d) IB/mlx5: Expose MPLS related tunneling offloads
    This patch reports the device's capbilities to offload
    encapsulated MPLS tunnel protocols to user-space:
    - Capability to offload MPLS over GRE.
    - Capability to offload MPLS over UDP.
    
    Differential revision:  https://reviews.freebsd.org/D32204
    MFC after:      1 month
---
 contrib/ofed/libibverbs/kern-abi.h  | 61 +++++++++++++++++++++++++++++++++++++
 sys/dev/mlx5/device.h               |  5 +++
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c | 31 +++++++++++++++++++
 sys/dev/mlx5/mlx5_ifc.h             |  3 +-
 4 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/contrib/ofed/libibverbs/kern-abi.h b/contrib/ofed/libibverbs/kern-abi.h
index 9c3557559676..74cf407840e9 100644
--- a/contrib/ofed/libibverbs/kern-abi.h
+++ b/contrib/ofed/libibverbs/kern-abi.h
@@ -954,6 +954,67 @@ struct ibv_kern_spec_action_drop {
 	__u16 reserved;
 };
 
+/* Copied from rdma/ib_user_verbs.h, remove after refactoring OFED */
+struct __ib_uverbs_flow_spec_hdr {
+	__u32 type;
+	__u16 size;
+	__u16 reserved;
+	/* followed by flow_spec */
+	__u64 flow_spec_data[0];
+};
+
+/* Define in rdma/ib_user_verbs.h after refactoring OFED - start */
+struct ib_uverbs_flow_gre_filter {
+	/* c_ks_res0_ver field is bits 0-15 in offset 0 of a standard GRE header:
+	 * bit 0 - C - checksum bit.
+	 * bit 1 - reserved. set to 0.
+	 * bit 2 - key bit.
+	 * bit 3 - sequence number bit.
+	 * bits 4:12 - reserved. set to 0.
+	 * bits 13:15 - GRE version.
+	 */
+	__be16 c_ks_res0_ver;
+	__be16 protocol;
+	__be32 key;
+};
+
+struct ib_uverbs_flow_spec_gre {
+	union {
+		struct __ib_uverbs_flow_spec_hdr hdr;
+		struct {
+			__u32 type;
+			__u16 size;
+			__u16 reserved;
+		};
+	};
+	struct ib_uverbs_flow_gre_filter     val;
+	struct ib_uverbs_flow_gre_filter     mask;
+};
+
+struct ib_uverbs_flow_mpls_filter {
+	/* The field includes the entire MPLS label:
+	 * bits 0:19 - label field.
+	 * bits 20:22 - traffic class field.
+	 * bits 23 - bottom of stack bit.
+	 * bits 24:31 - ttl field.
+	 */
+	__be32 label;
+};
+
+struct ib_uverbs_flow_spec_mpls {
+	union {
+		struct __ib_uverbs_flow_spec_hdr hdr;
+		struct {
+			__u32 type;
+			__u16 size;
+			__u16 reserved;
+		};
+	};
+	struct ib_uverbs_flow_mpls_filter     val;
+	struct ib_uverbs_flow_mpls_filter     mask;
+};
+/* Define in rdma/ib_user_verbs.h after refactoring OFED - end */
+
 struct ibv_kern_spec {
 	union {
 		struct {
diff --git a/sys/dev/mlx5/device.h b/sys/dev/mlx5/device.h
index 3e2c4f15a5cc..a31f5970206b 100644
--- a/sys/dev/mlx5/device.h
+++ b/sys/dev/mlx5/device.h
@@ -982,6 +982,11 @@ enum {
 	MLX5_ESW_VPORT_ADMIN_STATE_AUTO  = 0x2,
 };
 
+enum mlx5_flex_parser_protos {
+	MLX5_FLEX_PROTO_CW_MPLS_GRE   = 1 << 4,
+	MLX5_FLEX_PROTO_CW_MPLS_UDP   = 1 << 5,
+};
+
 /* MLX5 DEV CAPs */
 
 /* TODO: EAT.ME */
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index 1e31e738e6f1..f9c2c2a1b310 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -934,6 +934,14 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
 		if (MLX5_CAP_ETH(mdev, tunnel_stateless_gre))
 			resp.tunnel_offloads_caps |=
 				MLX5_IB_TUNNELED_OFFLOADS_GRE;
+		if (MLX5_CAP_GEN(mdev, flex_parser_protocols) &
+				MLX5_FLEX_PROTO_CW_MPLS_GRE)
+			resp.tunnel_offloads_caps |=
+				MLX5_IB_TUNNELED_OFFLOADS_MPLS_GRE;
+		if (MLX5_CAP_GEN(mdev, flex_parser_protocols) &
+				MLX5_FLEX_PROTO_CW_MPLS_UDP)
+			resp.tunnel_offloads_caps |=
+				MLX5_IB_TUNNELED_OFFLOADS_MPLS_UDP;
 	}
 
 	if (uhw->outlen) {
@@ -2191,6 +2199,29 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v,
 		MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
 			 ntohs(ib_spec->tcp_udp.val.dst_port));
 		break;
+	case IB_FLOW_SPEC_GRE:
+		if (ib_spec->gre.mask.c_ks_res0_ver)
+			return -EOPNOTSUPP;
+
+		MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
+			 0xff);
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
+			 IPPROTO_GRE);
+
+		MLX5_SET(fte_match_set_misc, misc_params_c, gre_protocol,
+			 0xffff);
+		MLX5_SET(fte_match_set_misc, misc_params_v, gre_protocol,
+			 ntohs(ib_spec->gre.val.protocol));
+
+		memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_c,
+				    gre_key),
+		       &ib_spec->gre.mask.key,
+		       sizeof(ib_spec->gre.mask.key));
+		memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_v,
+				    gre_key),
+		       &ib_spec->gre.val.key,
+		       sizeof(ib_spec->gre.val.key));
+		break;
 	case IB_FLOW_SPEC_VXLAN_TUNNEL:
 		if (FIELDS_NOT_SUPPORTED(ib_spec->tunnel.mask,
 					 LAST_TUNNEL_FIELD))
diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h
index f2ae0dbfd0b3..35e197d0a587 100644
--- a/sys/dev/mlx5/mlx5_ifc.h
+++ b/sys/dev/mlx5/mlx5_ifc.h
@@ -1626,7 +1626,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 
 	u8         reserved_at_500[0x20];
 	u8	   num_of_uars_per_page[0x20];
-	u8         reserved_at_540[0x40];
+	u8         flex_parser_protocols[0x20];
+	u8         reserved_at_540[0x20];
 
 	u8         log_max_atomic_size_qp[0x8];
 	u8         reserved_67[0x10];