[PATCH 26.07 4/5] net/mlx5/hws: add source vport match in HWS

Dariusz Sosnowski dsosnowski at nvidia.com
Wed Mar 25 10:07:56 CET 2026


Matching source vport without having vport metadata available
requires matching on 2 fields:

- source_gvmi - equal to VHCA ID property of the port,
- functional_lb

There are following cases:

- If packet comes from PF/VF/SF, then it originated on some Tx queue on
  the host. In this case, source_gvmi will be populated with
  the ID of the originating function.
- If packet comes from the wire, then source_gvmi will be set to 0.

There is one edge case - discriminating packets coming from PF0 and
from wire. In this case, both packets will have source_gvmi set to 0.
Distinguishing them requires additional match on functional_lb.
If packet comes from PF, functional_lb will be set to 1.
This only happens when packet was sent from PF to FDB, and
then moved to PF again.

Because of all of the above:

- Unified FDB must be disabled when vport metadata is disabled,
  because packet from PF0 and from wire will not have
  correct functional_lb set yet when flow rules in FDB are processed.
- Without unified FDB, when separate FDB_RX and FDB_TX tables are used
  internally, match on functional_lb is not needed.
  Table type already defines the direction.
- NIC_TX tables belong to a single GVMI and as a result
  vport matching is not needed there.

As a result, functional_lb match is only required on NIC_RX.

This patch adds support for source_gvmi and functional_lb matching
in HWS layer.

Signed-off-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_definer.c | 65 +++++++++++++++++++++++++--
 drivers/net/mlx5/hws/mlx5dr_definer.h |  2 +
 drivers/net/mlx5/hws/mlx5dr_table.c   |  6 +++
 3 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 3ba69c1001..7400b8f252 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -6,6 +6,8 @@
 
 #include "mlx5dr_internal.h"
 
+#define WIRE_GVMI	0
+#define BAD_GVMI	0xFFFF
 #define GTP_PDU_SC	0x85
 #define BAD_PORT	0xBAD
 #define BAD_SQN		0xBAD
@@ -789,6 +791,49 @@ mlx5dr_definer_vport_set(struct mlx5dr_definer_fc *fc,
 	DR_SET(tag, regc_value, fc->byte_off, fc->bit_off, fc->bit_mask);
 }
 
+static void
+mlx5dr_definer_source_gvmi_set(struct mlx5dr_definer_fc *fc,
+			       const void *item_spec,
+			       uint8_t *tag)
+{
+	const struct rte_flow_item_ethdev *v = item_spec;
+	const struct flow_hw_port_info *port_info;
+	uint32_t source_gvmi;
+
+	if (v) {
+		port_info = flow_hw_conv_port_id(fc->dr_ctx, v->port_id);
+		assert(port_info != NULL);
+		if (port_info->is_wire)
+			source_gvmi = WIRE_GVMI;
+		else
+			source_gvmi = port_info->vhca_id;
+	} else {
+		source_gvmi = BAD_GVMI;
+	}
+
+	DR_SET(tag, source_gvmi, fc->byte_off, fc->bit_off, fc->bit_mask);
+}
+
+static void
+mlx5dr_definer_functional_lb_set(struct mlx5dr_definer_fc *fc,
+				 const void *item_spec,
+				 uint8_t *tag)
+{
+	const struct rte_flow_item_ethdev *v = item_spec;
+	const struct flow_hw_port_info *port_info;
+	uint32_t functional_lb;
+
+	if (v) {
+		port_info = flow_hw_conv_port_id(fc->dr_ctx, v->port_id);
+		assert(port_info != NULL);
+		functional_lb = !port_info->is_wire;
+	} else {
+		functional_lb = 0;
+	}
+
+	DR_SET(tag, functional_lb, fc->byte_off, fc->bit_off, fc->bit_mask);
+}
+
 static struct mlx5dr_definer_fc *
 mlx5dr_definer_get_mpls_fc(struct mlx5dr_definer_conv_data *cd, bool inner)
 {
@@ -1610,10 +1655,22 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 			fc->bit_mask = caps->wire_regc_mask >> fc->bit_off;
 			fc->dr_ctx = cd->ctx;
 		} else {
-			/* TODO */
-			DR_LOG(ERR, "Port ID item with legacy vport match is not implemented");
-			rte_errno = ENOTSUP;
-			return rte_errno;
+			fc = &cd->fc[MLX5DR_DEFINER_FNAME_SOURCE_GVMI];
+			fc->item_idx = item_idx;
+			fc->tag_set = &mlx5dr_definer_source_gvmi_set;
+			fc->tag_mask_set = &mlx5dr_definer_ones_set;
+			DR_CALC_SET_HDR(fc, source_qp_gvmi, source_gvmi);
+			fc->dr_ctx = cd->ctx;
+
+			if (cd->table_type != MLX5DR_TABLE_TYPE_NIC_RX)
+				return 0;
+
+			fc = &cd->fc[MLX5DR_DEFINER_FNAME_FUNCTIONAL_LB];
+			fc->item_idx = item_idx;
+			fc->tag_set = &mlx5dr_definer_functional_lb_set;
+			fc->tag_mask_set = &mlx5dr_definer_ones_set;
+			DR_CALC_SET_HDR(fc, source_qp_gvmi, functional_lb);
+			fc->dr_ctx = cd->ctx;
 		}
 	}
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h
index d0c99399ae..f5d6cce887 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.h
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.h
@@ -214,6 +214,8 @@ enum mlx5dr_definer_fname {
 	MLX5DR_DEFINER_FNAME_PTYPE_FRAG_O,
 	MLX5DR_DEFINER_FNAME_PTYPE_FRAG_I,
 	MLX5DR_DEFINER_FNAME_RANDOM_NUM,
+	MLX5DR_DEFINER_FNAME_SOURCE_GVMI,
+	MLX5DR_DEFINER_FNAME_FUNCTIONAL_LB,
 	MLX5DR_DEFINER_FNAME_MAX,
 };
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c
index 41ffaa19e3..14e983a363 100644
--- a/drivers/net/mlx5/hws/mlx5dr_table.c
+++ b/drivers/net/mlx5/hws/mlx5dr_table.c
@@ -468,6 +468,12 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_context *ctx,
 		return NULL;
 	}
 
+	if (attr->type == MLX5DR_TABLE_TYPE_FDB_UNIFIED && !ctx->caps->vport_metadata_match) {
+		DR_LOG(ERR, "Table type %d requires vport metadata to be enabled", attr->type);
+		rte_errno = ENOTSUP;
+		return NULL;
+	}
+
 	if ((mlx5dr_table_is_fdb_any(attr->type) && attr->type != MLX5DR_TABLE_TYPE_FDB) &&
 	    !attr->level) {
 		DR_LOG(ERR, "Table type %d not supported by root table", attr->type);
-- 
2.47.3



More information about the dev mailing list