git: 644f8990e2c2 - main - verbs/mlx5: Add GRE and MPLS flow specification filter

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

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

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

    verbs/mlx5: Add GRE and MPLS flow specification filter
    
    [PATCH 30/31] FreeBSD OFED support for DPDK MLX5 PMD
    
    a) Allow verbs applications packet steering of GRE tunneled traffic.
    Adding GRE flow specification based on RFC 2890.
    GRE consists of flags, protocol and key fields.
    IPv4 protocol 47 (IPPROTO_GRE) can be used when GRE packets are
    encapsulated in IPv4.
    
    b) verbs: Add MPLS flow specification filter
    Add MPLS flow specification based on RFC 3032.
    MPLS spec defined with label field which includes the
    label value and additional parameters such as: BoS, TC and TTL.
    MPLS allows stacking multiple labels in sequence.
    In addition, the MPLS header can be encapsulated on top of different
    layers, e.g.: ETH, IP (rfc4023), UDP (rfc7510), GRE (rfc4023).
    
    Therefore, when using the flow creation verb, the application should
    organize the spec filters list in the command in an ordered manner, such
    that reflects the actual protocol stack of the packet, to determine the
    exact position of the MPLS headers in the protocol stack.
    
    c) mlx5: Report MPLS tunnel offload capabilities through mlx5 direct
    verbs
    This patch exposes the mlx5 device's capability to offload MPLS based
    tunnel protocols via DV API.
    The possible protocols are:
    - Control word + MPLS over GRE.
    - Control word + MPLS over UDP.
    
    Differential revision:  https://reviews.freebsd.org/D32205
    MFC after:      1 month
---
 contrib/ofed/libibverbs/cmd.c                 | 14 +++++++++
 contrib/ofed/libibverbs/kern-abi.h            |  2 ++
 contrib/ofed/libibverbs/man/ibv_create_flow.3 | 20 ++++++++++++-
 contrib/ofed/libibverbs/verbs.h               | 42 +++++++++++++++++++++++++++
 contrib/ofed/libmlx5/mlx5dv.h                 |  2 ++
 5 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/contrib/ofed/libibverbs/cmd.c b/contrib/ofed/libibverbs/cmd.c
index 82ceb5fb9fe8..9c79757f0e60 100644
--- a/contrib/ofed/libibverbs/cmd.c
+++ b/contrib/ofed/libibverbs/cmd.c
@@ -1914,6 +1914,20 @@ static int ib_spec_to_kern_spec(struct ibv_flow_spec *ib_spec,
 		memcpy(&kern_spec->tcp_udp.mask, &ib_spec->tcp_udp.mask,
 		       sizeof(struct ibv_flow_tcp_udp_filter));
 		break;
+	case IBV_FLOW_SPEC_GRE:
+		kern_spec->gre.size = sizeof(struct ib_uverbs_flow_spec_gre);
+		memcpy(&kern_spec->gre.val, &ib_spec->gre.val,
+		       sizeof(struct ibv_flow_gre_filter));
+		memcpy(&kern_spec->gre.mask, &ib_spec->gre.mask,
+		       sizeof(struct ibv_flow_gre_filter));
+		break;
+	case IBV_FLOW_SPEC_MPLS:
+		kern_spec->mpls.size = sizeof(struct ib_uverbs_flow_spec_mpls);
+		memcpy(&kern_spec->mpls.val, &ib_spec->mpls.val,
+		       sizeof(struct ibv_flow_mpls_filter));
+		memcpy(&kern_spec->mpls.mask, &ib_spec->mpls.mask,
+		       sizeof(struct ibv_flow_mpls_filter));
+		break;
 	case IBV_FLOW_SPEC_VXLAN_TUNNEL:
 		ret = get_filters_size(ib_spec, kern_spec,
 				       &ib_filter_size, &kern_filter_size,
diff --git a/contrib/ofed/libibverbs/kern-abi.h b/contrib/ofed/libibverbs/kern-abi.h
index d5ed405d08c7..fb3d545cecc4 100644
--- a/contrib/ofed/libibverbs/kern-abi.h
+++ b/contrib/ofed/libibverbs/kern-abi.h
@@ -1027,7 +1027,9 @@ struct ibv_kern_spec {
 		struct ibv_kern_spec_ipv4_ext ipv4_ext;
 		struct ibv_kern_spec_tcp_udp tcp_udp;
 		struct ibv_kern_spec_ipv6 ipv6;
+		struct ib_uverbs_flow_spec_gre gre;
 		struct ibv_kern_spec_tunnel tunnel;
+		struct ib_uverbs_flow_spec_mpls mpls;
 		struct ibv_kern_spec_action_tag flow_tag;
 		struct ibv_kern_spec_action_drop drop;
 	};
diff --git a/contrib/ofed/libibverbs/man/ibv_create_flow.3 b/contrib/ofed/libibverbs/man/ibv_create_flow.3
index 48bbb14c9914..7c02695a93e3 100644
--- a/contrib/ofed/libibverbs/man/ibv_create_flow.3
+++ b/contrib/ofed/libibverbs/man/ibv_create_flow.3
@@ -67,6 +67,8 @@ IBV_FLOW_SPEC_IPV4_EXT                  = 0x32,   /* Extended flow specification
 IBV_FLOW_SPEC_TCP                       = 0x40,   /* Flow specification of TCP header */
 IBV_FLOW_SPEC_UDP                       = 0x41,   /* Flow specification of UDP header */
 IBV_FLOW_SPEC_VXLAN_TUNNEL             	= 0x50,   /* Flow specification of VXLAN header */
+IBV_FLOW_SPEC_GRE 			= 0x51,   /* Flow specification of GRE header */
+IBV_FLOW_SPEC_MPLS 			= 0x60,   /* Flow specification of MPLS header */
 IBV_FLOW_SPEC_INNER                    	= 0x100,  /* Flag making L2/L3/L4 specifications to be applied on the inner header */
 IBV_FLOW_SPEC_ACTION_TAG                = 0x1000, /* Action tagging matched packet */
 IBV_FLOW_SPEC_ACTION_DROP               = 0x1001, /* Action dropping matched packet */
@@ -103,7 +105,23 @@ In addition to the domain, there is priority within each of the domains.
 A lower priority numeric value (higher priority) takes precedence over matching rules with higher numeric priority value (lower priority).
 It is important to note that the priority value of a flow spec is used not only to establish the precedence of conflicting flow matches
 but also as a way to abstract the order on which flow specs are tested for matches. Flows with higher priorities will be tested before flows with lower priorities.
-.PP
+
+.SS Rules definition ordering
+An application can provide the ibv_flow_spec_xxx rules in an un-ordered scheme. In this case, each spec should be well
+defined and match a specific network header layer.
+In some cases, when certain flow spec types are present in the spec list, it is required to provide the list in an
+ordered manner so that the position of that flow spec type in the protocol stack is strictly defined.
+This is essential to represent many of the encapsulation tunnel protocols.
+.br
+
+The flow spec types which require this sort of ordering are:
+.br
+.B 1. IBV_FLOW_SPEC_MPLS -
+.br
+Since MPLS header can appear at several locations in the protocol stack and can also be
+encapsulated on top of different layers, it is required to place this spec according to its exact location in the
+protocol stack.
+.br
 .SS ibv_destroy_flow()
 destroys the flow
 .I flow_id\fR.
diff --git a/contrib/ofed/libibverbs/verbs.h b/contrib/ofed/libibverbs/verbs.h
index 54a8a2d39342..81c6a3b57bb6 100644
--- a/contrib/ofed/libibverbs/verbs.h
+++ b/contrib/ofed/libibverbs/verbs.h
@@ -1280,6 +1280,8 @@ enum ibv_flow_spec_type {
 	IBV_FLOW_SPEC_TCP		= 0x40,
 	IBV_FLOW_SPEC_UDP		= 0x41,
 	IBV_FLOW_SPEC_VXLAN_TUNNEL	= 0x50,
+	IBV_FLOW_SPEC_GRE		= 0x51,
+	IBV_FLOW_SPEC_MPLS		= 0x60,
 	IBV_FLOW_SPEC_INNER		= 0x100,
 	IBV_FLOW_SPEC_ACTION_TAG	= 0x1000,
 	IBV_FLOW_SPEC_ACTION_DROP	= 0x1001,
@@ -1358,6 +1360,44 @@ struct ibv_flow_spec_tcp_udp {
 	struct ibv_flow_tcp_udp_filter mask;
 };
 
+struct ibv_flow_gre_filter {
+	/* c_ks_res0_ver field is bits 0-15 in offset 0 of a standard GRE header:
+	 * bit 0 - checksum present bit.
+	 * bit 1 - reserved. set to 0.
+	 * bit 2 - key present bit.
+	 * bit 3 - sequence number present bit.
+	 * bits 4:12 - reserved. set to 0.
+	 * bits 13:15 - GRE version.
+	 */
+	uint16_t c_ks_res0_ver;
+	uint16_t protocol;
+	uint32_t key;
+};
+
+struct ibv_flow_spec_gre {
+	enum ibv_flow_spec_type  type;
+	uint16_t  size;
+	struct ibv_flow_gre_filter val;
+	struct ibv_flow_gre_filter mask;
+};
+
+struct ibv_flow_mpls_filter {
+	/* The field includes the entire MPLS label:
+	 * bits 0:19 - label value field.
+	 * bits 20:22 - traffic class field.
+	 * bits 23 - bottom of stack bit.
+	 * bits 24:31 - ttl field.
+	 */
+	uint32_t label;
+};
+
+struct ibv_flow_spec_mpls {
+	enum ibv_flow_spec_type  type;
+	uint16_t  size;
+	struct ibv_flow_mpls_filter val;
+	struct ibv_flow_mpls_filter mask;
+};
+
 struct ibv_flow_tunnel_filter {
 	uint32_t tunnel_id;
 };
@@ -1392,6 +1432,8 @@ struct ibv_flow_spec {
 		struct ibv_flow_spec_ipv4_ext ipv4_ext;
 		struct ibv_flow_spec_ipv6 ipv6;
 		struct ibv_flow_spec_tunnel tunnel;
+		struct ibv_flow_spec_gre gre;
+		struct ibv_flow_spec_mpls mpls;
 		struct ibv_flow_spec_action_tag flow_tag;
 		struct ibv_flow_spec_action_drop drop;
 	};
diff --git a/contrib/ofed/libmlx5/mlx5dv.h b/contrib/ofed/libmlx5/mlx5dv.h
index fb6180b50104..f31d4964998d 100644
--- a/contrib/ofed/libmlx5/mlx5dv.h
+++ b/contrib/ofed/libmlx5/mlx5dv.h
@@ -86,6 +86,8 @@ enum mlx5dv_tunnel_offloads {
 	MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN		= 1 << 0,
 	MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE		= 1 << 1,
 	MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE		= 1 << 2,
+	MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE	= 1 << 3,
+	MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP	= 1 << 4,
 };