DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 0/7] net/mlx5: support copy from inner fields
@ 2024-02-06 14:39 Michael Baum
  2024-02-06 14:39 ` [PATCH v1 1/7] common/mlx5: remove enum value duplication Michael Baum
                   ` (7 more replies)
  0 siblings, 8 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch-set adds support of encapsulation level for HWS modify field
in MLX5 PMD.
Outermost is represented by 0,1 and inner is represented by 2.
In addition, modify inner/outer us added for both IPv6 flow label and
IPv6 traffic class.

Depends-on: series-31008 ("ethdev: add modify IPv4 next protocol field")
Depends-on: series-31010 ("ethdev: add IPv6 field identifiers")

Michael Baum (7):
  common/mlx5: remove enum value duplication
  common/mlx5: reorder modification field PRM list
  common/mlx5: add inner PRM fields
  common/mlx5: add IPv6 flow label PRM field
  net/mlx5: add support for modify inner fields
  net/mlx5: support modify IPv6 traffic class field
  net/mlx5: support modify IPv6 flow label field

 doc/guides/nics/mlx5.rst               |  28 ++++-
 doc/guides/rel_notes/release_24_03.rst |   2 +
 drivers/common/mlx5/mlx5_prm.h         |  49 +++++----
 drivers/net/mlx5/hws/mlx5dr_action.c   |   4 +-
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c  |   2 +-
 drivers/net/mlx5/mlx5_flow.c           |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 136 +++++++++++++++----------
 drivers/net/mlx5/mlx5_flow_hw.c        | 134 +++++++++++++++++++++++-
 8 files changed, 282 insertions(+), 85 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 1/7] common/mlx5: remove enum value duplication
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 2/7] common/mlx5: reorder modification field PRM list Michael Baum
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

The "mlx5_modification_field" enumeration has 2 different fields
representing the same value 0x4A.
 1. "MLX5_MODI_OUT_IPV6_NEXT_HDR" - specific for IPv6.
 2. "MLX5_MODI_OUT_IP_PROTOCOL" - for both IPv4 and IPv6.

This patch removes "MLX5_MODI_OUT_IPV6_NEXT_HDR" and replaces all its
usages with "MLX5_MODI_OUT_IP_PROTOCOL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h        | 1 -
 drivers/net/mlx5/hws/mlx5dr_action.c  | 4 ++--
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 3150412580..1f04a35683 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -840,7 +840,6 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
 	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x4A,
 	MLX5_MODI_META_REG_C_8 = 0x8F,
 	MLX5_MODI_META_REG_C_9 = 0x90,
 	MLX5_MODI_META_REG_C_10 = 0x91,
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index 862ee3e332..2828a82d5b 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -2287,7 +2287,7 @@ mlx5dr_action_create_pop_ipv6_route_ext_mhdr3(struct mlx5dr_action *action)
 	MLX5_SET(copy_action_in, cmd, length, 8);
 	MLX5_SET(copy_action_in, cmd, src_offset, 24);
 	MLX5_SET(copy_action_in, cmd, src_field, mod_id);
-	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IP_PROTOCOL);
 
 	pattern.data = (__be64 *)cmd;
 	pattern.sz = sizeof(cmd);
@@ -2348,7 +2348,7 @@ mlx5dr_action_create_push_ipv6_route_ext_mhdr1(struct mlx5dr_action *action)
 	/* Set ipv6.protocol to IPPROTO_ROUTING */
 	MLX5_SET(set_action_in, cmd, action_type, MLX5_MODIFICATION_TYPE_SET);
 	MLX5_SET(set_action_in, cmd, length, 8);
-	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IP_PROTOCOL);
 	MLX5_SET(set_action_in, cmd, data, IPPROTO_ROUTING);
 
 	pattern.data = (__be64 *)cmd;
diff --git a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
index a949844d24..513549ff3c 100644
--- a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
+++ b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
@@ -67,7 +67,7 @@ bool mlx5dr_pat_require_reparse(__be64 *actions, uint16_t num_of_actions)
 
 		/* Below fields can change packet structure require a reparse */
 		if (field == MLX5_MODI_OUT_ETHERTYPE ||
-		    field == MLX5_MODI_OUT_IPV6_NEXT_HDR)
+		    field == MLX5_MODI_OUT_IP_PROTOCOL)
 			return true;
 	}
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 2/7] common/mlx5: reorder modification field PRM list
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
  2024-02-06 14:39 ` [PATCH v1 1/7] common/mlx5: remove enum value duplication Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 3/7] common/mlx5: add inner PRM fields Michael Baum
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Reorder modification field PRM list according to values from lowest to
highest.
This patch also removes value specification from all fields which their
value is one more than previous one.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 1f04a35683..a13b5790b0 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -816,6 +816,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_HOPLIMIT,
 	MLX5_MODI_IN_IPV6_HOPLIMIT,
 	MLX5_MODI_META_DATA_REG_A,
+	MLX5_MODI_OUT_IP_PROTOCOL,
 	MLX5_MODI_META_DATA_REG_B = 0x50,
 	MLX5_MODI_META_REG_C_0,
 	MLX5_MODI_META_REG_C_1,
@@ -829,32 +830,31 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
 	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_OUT_ESP_SPI = 0x5E,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
-	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
+	MLX5_MODI_OUT_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
-	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_META_REG_C_8 = 0x8F,
-	MLX5_MODI_META_REG_C_9 = 0x90,
-	MLX5_MODI_META_REG_C_10 = 0x91,
-	MLX5_MODI_META_REG_C_11 = 0x92,
-	MLX5_MODI_META_REG_C_12 = 0x93,
-	MLX5_MODI_META_REG_C_13 = 0x94,
-	MLX5_MODI_META_REG_C_14 = 0x95,
-	MLX5_MODI_META_REG_C_15 = 0x96,
+	MLX5_MODI_META_REG_C_8,
+	MLX5_MODI_META_REG_C_9,
+	MLX5_MODI_META_REG_C_10,
+	MLX5_MODI_META_REG_C_11,
+	MLX5_MODI_META_REG_C_12,
+	MLX5_MODI_META_REG_C_13,
+	MLX5_MODI_META_REG_C_14,
+	MLX5_MODI_META_REG_C_15,
 	MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS = 0x11C,
-	MLX5_MODI_OUT_IPV4_TOTAL_LEN = 0x11D,
-	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN = 0x11E,
-	MLX5_MODI_OUT_IPV4_IHL = 0x11F,
-	MLX5_MODI_OUT_TCP_DATA_OFFSET = 0x120,
-	MLX5_MODI_OUT_ESP_SPI = 0x5E,
-	MLX5_MODI_OUT_ESP_SEQ_NUM = 0x82,
+	MLX5_MODI_OUT_IPV4_TOTAL_LEN,
+	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_OUT_IPV4_IHL,
+	MLX5_MODI_OUT_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
 	MLX5_MODI_INVALID = INT_MAX,
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 3/7] common/mlx5: add inner PRM fields
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
  2024-02-06 14:39 ` [PATCH v1 1/7] common/mlx5: remove enum value duplication Michael Baum
  2024-02-06 14:39 ` [PATCH v1 2/7] common/mlx5: reorder modification field PRM list Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds inner values into PRM modify field list for each
existing outer field.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index a13b5790b0..7ac43f42b8 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -829,14 +829,17 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_TCP_SEQ_NUM,
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
-	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_IN_TCP_ACK_NUM,
 	MLX5_MODI_OUT_ESP_SPI = 0x5E,
+	MLX5_MODI_IN_ESP_SPI,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
-	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
+	MLX5_MODI_IN_IP_ECN,
+	MLX5_MODI_TUNNEL_HDR_DW_1,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
 	MLX5_MODI_OUT_ESP_SEQ_NUM,
+	MLX5_MODI_IN_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
@@ -855,7 +858,12 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
 	MLX5_MODI_OUT_IPV4_IHL,
 	MLX5_MODI_OUT_TCP_DATA_OFFSET,
-	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
+	MLX5_MODI_IN_IPV6_TRAFFIC_CLASS,
+	MLX5_MODI_IN_IPV4_TOTAL_LEN,
+	MLX5_MODI_IN_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_IN_IPV4_IHL,
+	MLX5_MODI_IN_TCP_DATA_OFFSET,
+	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 4/7] common/mlx5: add IPv6 flow label PRM field
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
                   ` (2 preceding siblings ...)
  2024-02-06 14:39 ` [PATCH v1 3/7] common/mlx5: add inner PRM fields Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 5/7] net/mlx5: add support for modify inner fields Michael Baum
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add IPv6 flow label field into PRM modify field list.
The new values are "MLX5_MODI_OUT_IPV6_FLOW_LABEL" and
"MLX5_MODI_IN_IPV6_FLOW_LABEL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 7ac43f42b8..afd0001e8f 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -864,6 +864,8 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_IPV4_IHL,
 	MLX5_MODI_IN_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
+	MLX5_MODI_OUT_IPV6_FLOW_LABEL,
+	MLX5_MODI_IN_IPV6_FLOW_LABEL,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 5/7] net/mlx5: add support for modify inner fields
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
                   ` (3 preceding siblings ...)
  2024-02-06 14:39 ` [PATCH v1 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds support for copying from inner fields using "level" 2.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/nics/mlx5.rst        |  28 ++++++-
 drivers/net/mlx5/mlx5_flow.c    |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c | 113 ++++++++++++++-------------
 drivers/net/mlx5/mlx5_flow_hw.c | 130 +++++++++++++++++++++++++++++++-
 4 files changed, 222 insertions(+), 61 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 6e1e2df79a..030bbe664f 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -595,7 +595,6 @@ Limitations
     Only DWs configured in :ref:`parser creation <geneve_parser_api>` can be modified,
     'type' and 'class' fields can be modified when ``match_on_class_mode=2``.
   - Modification of GENEVE TLV option data supports one DW per action.
-  - Encapsulation levels are not supported, can modify outermost header fields only.
   - Offsets cannot skip past the boundary of a field.
   - If the field type is ``RTE_FLOW_FIELD_MAC_TYPE``
     and packet contains one or more VLAN headers,
@@ -609,6 +608,33 @@ Limitations
   - For flow metadata fields (e.g. META or TAG)
     offset specifies the number of bits to skip from field's start,
     starting from LSB in the least significant byte, in the host order.
+  - Modification of the MPLS header is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - Only for outermost tunnel header (``level=2``).
+      For ``RTE_FLOW_FIELD_MPLS``,
+      the default encapsulation level ``0`` describes the outermost tunnel header.
+
+      .. note::
+
+         the default encapsulation level ``0`` describes the "outermost that match is supported",
+         currently it is first tunnel, but it can be changed to outer when it is supported.
+
+  - Default encapsulation level ``0`` describes outermost.
+  - Encapsulation level ``1`` is supported.
+  - Encapsulation level ``2`` is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - ``RTE_FLOW_FIELD_VLAN_ID`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV4_PROTO`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV6_PROTO/DSCP/ECN`` are not supported.
+    - ``RTE_FLOW_FIELD_ESP_PROTO/SPI/SEQ_NUM`` are not supported.
+    - ``RTE_FLOW_FIELD_TCP_SEQ/ACK_NUM`` are not supported.
+    - Second tunnel fields are not supported.
+
+  - Encapsulation levels greater than ``2`` are not supported.
 
 - Age action:
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 5159e8e773..fa85089364 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2507,10 +2507,14 @@ flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
 	if (data->level == 0)
 		return 0;
 	if (data->field != RTE_FLOW_FIELD_TAG &&
-	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "inner header fields modification is not supported");
+	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG) {
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "inner header fields modification is not supported");
+		return 0;
+	}
 	if (data->tag_index != 0)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 90413f4a38..8454d00d4f 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -82,6 +82,9 @@
 		} \
 	} while (0)
 
+#define CALC_MODI_ID(field, level) \
+	(((level) > 1) ? MLX5_MODI_IN_##field : MLX5_MODI_OUT_##field)
+
 union flow_dv_attr {
 	struct {
 		uint32_t valid:1;
@@ -1638,8 +1641,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_DMAC_15_0};
+			modi_id = CALC_MODI_ID(DMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1654,8 +1657,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_DMAC_47_16};
+		modi_id = CALC_MODI_ID(DMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1665,8 +1668,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_SMAC_15_0};
+			modi_id = CALC_MODI_ID(SMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1681,8 +1684,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_SMAC_47_16};
+		modi_id = CALC_MODI_ID(SMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1704,8 +1707,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_MAC_TYPE:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_ETHERTYPE};
+		modi_id = CALC_MODI_ID(ETHERTYPE, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1714,8 +1717,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_IHL:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_IHL};
+		modi_id = CALC_MODI_ID(IPV4_IHL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1724,8 +1727,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DSCP:
 		MLX5_ASSERT(data->offset + width <= 6);
 		off_be = 6 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_DSCP};
+		modi_id = CALC_MODI_ID(IP_DSCP, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1734,8 +1737,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV4_TOTAL_LEN};
+		modi_id = CALC_MODI_ID(IPV4_TOTAL_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1744,8 +1747,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TTL:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_TTL};
+		modi_id = CALC_MODI_ID(IPV4_TTL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1754,8 +1757,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_SRC:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_SIPV4};
+		modi_id = CALC_MODI_ID(SIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1764,8 +1767,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DST:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_DIPV4};
+		modi_id = CALC_MODI_ID(DIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1795,8 +1798,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV6_PAYLOAD_LEN};
+		modi_id = CALC_MODI_ID(IPV6_PAYLOAD_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1805,8 +1808,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV6_HOPLIMIT};
+		modi_id = CALC_MODI_ID(IPV6_HOPLIMIT, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1818,10 +1821,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_SIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_SIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_SIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_SIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(SIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(SIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(SIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(SIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1861,10 +1864,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_DIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_DIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_DIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_DIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(DIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(DIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(DIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(DIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1901,8 +1904,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_SPORT};
+		modi_id = CALC_MODI_ID(TCP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1911,8 +1914,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_DPORT};
+		modi_id = CALC_MODI_ID(TCP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1921,8 +1924,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(TCP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1931,8 +1934,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_ACK_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_ACK_NUM};
+		modi_id = CALC_MODI_ID(TCP_ACK_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1941,8 +1944,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_FLAGS:
 		MLX5_ASSERT(data->offset + width <= 9);
 		off_be = 9 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_FLAGS};
+		modi_id = CALC_MODI_ID(TCP_FLAGS, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1951,8 +1954,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_TCP_DATA_OFFSET};
+		modi_id = CALC_MODI_ID(TCP_DATA_OFFSET, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1961,8 +1964,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_SPORT};
+		modi_id = CALC_MODI_ID(UDP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1971,8 +1974,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_DPORT};
+		modi_id = CALC_MODI_ID(UDP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -2124,8 +2127,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_ECN:
 		MLX5_ASSERT(data->offset + width <= 2);
 		off_be = 2 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_ECN};
+		modi_id = CALC_MODI_ID(IP_ECN, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -2221,7 +2224,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SPI:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SPI};
+		modi_id = CALC_MODI_ID(ESP_SPI, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -2230,7 +2234,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(ESP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 7510715189..fc0f9dabb3 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -4994,6 +4994,131 @@ flow_hw_modify_field_is_add_dst_valid(const struct rte_flow_action_modify_field
 	return false;
 }
 
+/**
+ * Validate the level value for modify field action.
+ *
+ * @param[in] data
+ *   Pointer to the rte_flow_field_data structure either src or dst.
+ * @param[in] inner_supported
+ *   Indicator whether inner should be supported.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+				    bool inner_supported,
+				    struct rte_flow_error *error)
+{
+	switch ((int)data->field) {
+	case RTE_FLOW_FIELD_START:
+	case RTE_FLOW_FIELD_VLAN_TYPE:
+	case RTE_FLOW_FIELD_RANDOM:
+	case RTE_FLOW_FIELD_FLEX_ITEM:
+		/*
+		 * Level shouldn't be valid since field isn't supported or
+		 * doesn't use 'level'.
+		 */
+		break;
+	case RTE_FLOW_FIELD_MARK:
+	case RTE_FLOW_FIELD_META:
+	case RTE_FLOW_FIELD_METER_COLOR:
+	case RTE_FLOW_FIELD_HASH_RESULT:
+		/* For meta data fields encapsulation level is don't-care. */
+		break;
+	case RTE_FLOW_FIELD_TAG:
+	case MLX5_RTE_FLOW_FIELD_META_REG:
+		/*
+		 * The tag array for RTE_FLOW_FIELD_TAG type is provided using
+		 * 'tag_index' field. In old API, it was provided using 'level'
+		 * field and it is still supported for backwards compatibility.
+		 * Therefore, for meta tag field only, level is matter. It is
+		 * taken as tag index when 'tag_index' field isn't set, and
+		 * return error otherwise.
+		 */
+		if (data->level > 0) {
+			if (data->tag_index > 0)
+				return rte_flow_error_set(error, EINVAL,
+							  RTE_FLOW_ERROR_TYPE_ACTION,
+							  data,
+							  "tag array can be provided using 'level' or 'tag_index' fields, not both");
+			DRV_LOG(WARNING,
+				"tag array provided in 'level' field instead of 'tag_index' field.");
+		}
+		break;
+	case RTE_FLOW_FIELD_MAC_DST:
+	case RTE_FLOW_FIELD_MAC_SRC:
+	case RTE_FLOW_FIELD_MAC_TYPE:
+	case RTE_FLOW_FIELD_IPV4_IHL:
+	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
+	case RTE_FLOW_FIELD_IPV4_DSCP:
+	case RTE_FLOW_FIELD_IPV4_ECN:
+	case RTE_FLOW_FIELD_IPV4_TTL:
+	case RTE_FLOW_FIELD_IPV4_SRC:
+	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
+	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_SRC:
+	case RTE_FLOW_FIELD_IPV6_DST:
+	case RTE_FLOW_FIELD_TCP_PORT_SRC:
+	case RTE_FLOW_FIELD_TCP_PORT_DST:
+	case RTE_FLOW_FIELD_TCP_FLAGS:
+	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
+	case RTE_FLOW_FIELD_UDP_PORT_SRC:
+	case RTE_FLOW_FIELD_UDP_PORT_DST:
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "second inner header fields modification is not supported");
+		if (inner_supported)
+			break;
+		/* Fallthrough */
+	case RTE_FLOW_FIELD_VLAN_ID:
+	case RTE_FLOW_FIELD_IPV4_PROTO:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+	case RTE_FLOW_FIELD_IPV6_DSCP:
+	case RTE_FLOW_FIELD_IPV6_ECN:
+	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
+	case RTE_FLOW_FIELD_TCP_ACK_NUM:
+	case RTE_FLOW_FIELD_ESP_PROTO:
+	case RTE_FLOW_FIELD_ESP_SPI:
+	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
+	case RTE_FLOW_FIELD_VXLAN_VNI:
+	case RTE_FLOW_FIELD_GENEVE_VNI:
+	case RTE_FLOW_FIELD_GENEVE_OPT_TYPE:
+	case RTE_FLOW_FIELD_GENEVE_OPT_CLASS:
+	case RTE_FLOW_FIELD_GENEVE_OPT_DATA:
+	case RTE_FLOW_FIELD_GTP_TEID:
+	case RTE_FLOW_FIELD_GTP_PSC_QFI:
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner header fields modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_MPLS:
+		if (data->level == 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "outer MPLS header modification is not supported");
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner MPLS header modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_POINTER:
+	case RTE_FLOW_FIELD_VALUE:
+	default:
+		MLX5_ASSERT(false);
+	}
+	return 0;
+}
+
 static int
 flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				     const struct rte_flow_action *action,
@@ -5024,7 +5149,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"immediate value, pointer and hash result cannot be used as destination");
-	ret = flow_validate_modify_field_level(&action_conf->dst, error);
+	ret = flow_hw_validate_modify_field_level(&action_conf->dst, false, error);
 	if (ret)
 		return ret;
 	if (!flow_hw_modify_field_is_geneve_opt(action_conf->dst.field)) {
@@ -5071,7 +5196,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 			return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"source offset level must be fully masked");
-		ret = flow_validate_modify_field_level(&action_conf->src, error);
+		ret = flow_hw_validate_modify_field_level(&action_conf->src, true, error);
 		if (ret)
 			return ret;
 	}
@@ -5136,6 +5261,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				"invalid add_field destination");
 	return 0;
 }
+
 static int
 flow_hw_validate_action_port_representor(struct rte_eth_dev *dev __rte_unused,
 					 const struct rte_flow_actions_template_attr *attr,
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 6/7] net/mlx5: support modify IPv6 traffic class field
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
                   ` (4 preceding siblings ...)
  2024-02-06 14:39 ` [PATCH v1 5/7] net/mlx5: add support for modify inner fields Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-06 14:39 ` [PATCH v1 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 traffic class field modification.
Copy from inner IPv6 traffic class field is also supported using
"level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 11 +++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  3 ++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 10268b7879..272bc9d056 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -100,6 +100,7 @@ New Features
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SPI`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SEQ_NUM`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_PROTO`` flow action.
+  * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS`` flow action.
 
 
 Removed Items
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 8454d00d4f..90ef21d75b 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
@@ -1795,6 +1796,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_TRAFFIC_CLASS, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index fc0f9dabb3..90e3cf2555 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2871,7 +2871,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
 		 * bits left. Shift the data left for IPV6 DSCP
 		 */
 		if (field->id == MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS &&
-		    !(mask & MLX5_IPV6_HDR_ECN_MASK))
+		    mhdr_action->dst.field == RTE_FLOW_FIELD_IPV6_DSCP)
 			data <<= MLX5_IPV6_HDR_DSCP_SHIFT;
 		data = (data & mask) >> off_b;
 		job->mhdr_cmd[i++].data1 = rte_cpu_to_be_32(data);
@@ -5058,6 +5058,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_action_modify_data *da
 	case RTE_FLOW_FIELD_IPV4_TTL:
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 7/7] net/mlx5: support modify IPv6 flow label field
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
                   ` (5 preceding siblings ...)
  2024-02-06 14:39 ` [PATCH v1 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
@ 2024-02-06 14:39 ` Michael Baum
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-06 14:39 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 flow label field modification.
Copy from inner IPv6 flow label field is also supported using "level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 12 ++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  1 +
 3 files changed, 14 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 272bc9d056..4cb45ba439 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -101,6 +101,7 @@ New Features
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SEQ_NUM`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_PROTO`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS`` flow action.
+  * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_FLOW_LABEL`` flow action.
 
 
 Removed Items
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 90ef21d75b..418e0c0998 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,8 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		return 20;
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
@@ -1806,6 +1808,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		MLX5_ASSERT(data->offset + width <= 20);
+		off_be = 20 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_FLOW_LABEL, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_32(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 90e3cf2555..90a06e7b44 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5059,6 +5059,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_action_modify_data *da
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/7] net/mlx5: support copy from inner fields
  2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
                   ` (6 preceding siblings ...)
  2024-02-06 14:39 ` [PATCH v1 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
@ 2024-02-07 15:55 ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 1/7] common/mlx5: remove enum value duplication Michael Baum
                     ` (8 more replies)
  7 siblings, 9 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch-set adds support of encapsulation level for HWS modify field
in MLX5 PMD.
Outermost is represented by 0,1 and inner is represented by 2.
In addition, modify inner/outer us added for both IPv6 flow label and
IPv6 traffic class.

Depends-on: series-31008 ("ethdev: add modify IPv4 next protocol field")
Depends-on: series-31010 ("ethdev: add IPv6 field identifiers")

v2:
- Rebase.
- Add "copy from inner" to release notes.

Michael Baum (7):
  common/mlx5: remove enum value duplication
  common/mlx5: reorder modification field PRM list
  common/mlx5: add inner PRM fields
  common/mlx5: add IPv6 flow label PRM field
  net/mlx5: add support for modify inner fields
  net/mlx5: support modify IPv6 traffic class field
  net/mlx5: support modify IPv6 flow label field

 doc/guides/nics/mlx5.rst               |  28 ++++-
 doc/guides/rel_notes/release_24_03.rst |   4 +
 drivers/common/mlx5/mlx5_prm.h         |  49 +++++----
 drivers/net/mlx5/hws/mlx5dr_action.c   |   4 +-
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c  |   2 +-
 drivers/net/mlx5/mlx5_flow.c           |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 136 +++++++++++++++----------
 drivers/net/mlx5/mlx5_flow_hw.c        | 134 +++++++++++++++++++++++-
 8 files changed, 284 insertions(+), 85 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/7] common/mlx5: remove enum value duplication
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 2/7] common/mlx5: reorder modification field PRM list Michael Baum
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

The "mlx5_modification_field" enumeration has 2 different fields
representing the same value 0x4A.
 1. "MLX5_MODI_OUT_IPV6_NEXT_HDR" - specific for IPv6.
 2. "MLX5_MODI_OUT_IP_PROTOCOL" - for both IPv4 and IPv6.

This patch removes "MLX5_MODI_OUT_IPV6_NEXT_HDR" and replaces all its
usages with "MLX5_MODI_OUT_IP_PROTOCOL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h        | 1 -
 drivers/net/mlx5/hws/mlx5dr_action.c  | 4 ++--
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 0035a1e616..af16bf4cf6 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -840,7 +840,6 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
 	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x4A,
 	MLX5_MODI_META_REG_C_8 = 0x8F,
 	MLX5_MODI_META_REG_C_9 = 0x90,
 	MLX5_MODI_META_REG_C_10 = 0x91,
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index 862ee3e332..2828a82d5b 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -2287,7 +2287,7 @@ mlx5dr_action_create_pop_ipv6_route_ext_mhdr3(struct mlx5dr_action *action)
 	MLX5_SET(copy_action_in, cmd, length, 8);
 	MLX5_SET(copy_action_in, cmd, src_offset, 24);
 	MLX5_SET(copy_action_in, cmd, src_field, mod_id);
-	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IP_PROTOCOL);
 
 	pattern.data = (__be64 *)cmd;
 	pattern.sz = sizeof(cmd);
@@ -2348,7 +2348,7 @@ mlx5dr_action_create_push_ipv6_route_ext_mhdr1(struct mlx5dr_action *action)
 	/* Set ipv6.protocol to IPPROTO_ROUTING */
 	MLX5_SET(set_action_in, cmd, action_type, MLX5_MODIFICATION_TYPE_SET);
 	MLX5_SET(set_action_in, cmd, length, 8);
-	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IP_PROTOCOL);
 	MLX5_SET(set_action_in, cmd, data, IPPROTO_ROUTING);
 
 	pattern.data = (__be64 *)cmd;
diff --git a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
index a949844d24..513549ff3c 100644
--- a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
+++ b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
@@ -67,7 +67,7 @@ bool mlx5dr_pat_require_reparse(__be64 *actions, uint16_t num_of_actions)
 
 		/* Below fields can change packet structure require a reparse */
 		if (field == MLX5_MODI_OUT_ETHERTYPE ||
-		    field == MLX5_MODI_OUT_IPV6_NEXT_HDR)
+		    field == MLX5_MODI_OUT_IP_PROTOCOL)
 			return true;
 	}
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 2/7] common/mlx5: reorder modification field PRM list
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
  2024-02-07 15:55   ` [PATCH v2 1/7] common/mlx5: remove enum value duplication Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 3/7] common/mlx5: add inner PRM fields Michael Baum
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Reorder modification field PRM list according to values from lowest to
highest.
This patch also removes value specification from all fields which their
value is one more than previous one.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index af16bf4cf6..b758557ef9 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -816,6 +816,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_HOPLIMIT,
 	MLX5_MODI_IN_IPV6_HOPLIMIT,
 	MLX5_MODI_META_DATA_REG_A,
+	MLX5_MODI_OUT_IP_PROTOCOL,
 	MLX5_MODI_META_DATA_REG_B = 0x50,
 	MLX5_MODI_META_REG_C_0,
 	MLX5_MODI_META_REG_C_1,
@@ -829,32 +830,31 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
 	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_OUT_ESP_SPI = 0x5E,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
-	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
+	MLX5_MODI_OUT_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
-	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_META_REG_C_8 = 0x8F,
-	MLX5_MODI_META_REG_C_9 = 0x90,
-	MLX5_MODI_META_REG_C_10 = 0x91,
-	MLX5_MODI_META_REG_C_11 = 0x92,
-	MLX5_MODI_META_REG_C_12 = 0x93,
-	MLX5_MODI_META_REG_C_13 = 0x94,
-	MLX5_MODI_META_REG_C_14 = 0x95,
-	MLX5_MODI_META_REG_C_15 = 0x96,
+	MLX5_MODI_META_REG_C_8,
+	MLX5_MODI_META_REG_C_9,
+	MLX5_MODI_META_REG_C_10,
+	MLX5_MODI_META_REG_C_11,
+	MLX5_MODI_META_REG_C_12,
+	MLX5_MODI_META_REG_C_13,
+	MLX5_MODI_META_REG_C_14,
+	MLX5_MODI_META_REG_C_15,
 	MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS = 0x11C,
-	MLX5_MODI_OUT_IPV4_TOTAL_LEN = 0x11D,
-	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN = 0x11E,
-	MLX5_MODI_OUT_IPV4_IHL = 0x11F,
-	MLX5_MODI_OUT_TCP_DATA_OFFSET = 0x120,
-	MLX5_MODI_OUT_ESP_SPI = 0x5E,
-	MLX5_MODI_OUT_ESP_SEQ_NUM = 0x82,
+	MLX5_MODI_OUT_IPV4_TOTAL_LEN,
+	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_OUT_IPV4_IHL,
+	MLX5_MODI_OUT_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
 	MLX5_MODI_INVALID = INT_MAX,
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/7] common/mlx5: add inner PRM fields
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
  2024-02-07 15:55   ` [PATCH v2 1/7] common/mlx5: remove enum value duplication Michael Baum
  2024-02-07 15:55   ` [PATCH v2 2/7] common/mlx5: reorder modification field PRM list Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds inner values into PRM modify field list for each
existing outer field.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index b758557ef9..c6d409833a 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -829,14 +829,17 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_TCP_SEQ_NUM,
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
-	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_IN_TCP_ACK_NUM,
 	MLX5_MODI_OUT_ESP_SPI = 0x5E,
+	MLX5_MODI_IN_ESP_SPI,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
-	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
+	MLX5_MODI_IN_IP_ECN,
+	MLX5_MODI_TUNNEL_HDR_DW_1,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
 	MLX5_MODI_OUT_ESP_SEQ_NUM,
+	MLX5_MODI_IN_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
@@ -855,7 +858,12 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
 	MLX5_MODI_OUT_IPV4_IHL,
 	MLX5_MODI_OUT_TCP_DATA_OFFSET,
-	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
+	MLX5_MODI_IN_IPV6_TRAFFIC_CLASS,
+	MLX5_MODI_IN_IPV4_TOTAL_LEN,
+	MLX5_MODI_IN_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_IN_IPV4_IHL,
+	MLX5_MODI_IN_TCP_DATA_OFFSET,
+	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 4/7] common/mlx5: add IPv6 flow label PRM field
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (2 preceding siblings ...)
  2024-02-07 15:55   ` [PATCH v2 3/7] common/mlx5: add inner PRM fields Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 5/7] net/mlx5: add support for modify inner fields Michael Baum
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add IPv6 flow label field into PRM modify field list.
The new values are "MLX5_MODI_OUT_IPV6_FLOW_LABEL" and
"MLX5_MODI_IN_IPV6_FLOW_LABEL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index c6d409833a..59d885e43b 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -864,6 +864,8 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_IPV4_IHL,
 	MLX5_MODI_IN_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
+	MLX5_MODI_OUT_IPV6_FLOW_LABEL,
+	MLX5_MODI_IN_IPV6_FLOW_LABEL,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 5/7] net/mlx5: add support for modify inner fields
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (3 preceding siblings ...)
  2024-02-07 15:55   ` [PATCH v2 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds support for copying from inner fields using "level" 2.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/nics/mlx5.rst               |  28 +++++-
 doc/guides/rel_notes/release_24_03.rst |   2 +
 drivers/net/mlx5/mlx5_flow.c           |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 113 +++++++++++----------
 drivers/net/mlx5/mlx5_flow_hw.c        | 130 ++++++++++++++++++++++++-
 5 files changed, 224 insertions(+), 61 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index fa013b03bb..5439e8fd7d 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -595,7 +595,6 @@ Limitations
     Only DWs configured in :ref:`parser creation <geneve_parser_api>` can be modified,
     'type' and 'class' fields can be modified when ``match_on_class_mode=2``.
   - Modification of GENEVE TLV option data supports one DW per action.
-  - Encapsulation levels are not supported, can modify outermost header fields only.
   - Offsets cannot skip past the boundary of a field.
   - If the field type is ``RTE_FLOW_FIELD_MAC_TYPE``
     and packet contains one or more VLAN headers,
@@ -609,6 +608,33 @@ Limitations
   - For flow metadata fields (e.g. META or TAG)
     offset specifies the number of bits to skip from field's start,
     starting from LSB in the least significant byte, in the host order.
+  - Modification of the MPLS header is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - Only for outermost tunnel header (``level=2``).
+      For ``RTE_FLOW_FIELD_MPLS``,
+      the default encapsulation level ``0`` describes the outermost tunnel header.
+
+      .. note::
+
+         the default encapsulation level ``0`` describes the "outermost that match is supported",
+         currently it is first tunnel, but it can be changed to outer when it is supported.
+
+  - Default encapsulation level ``0`` describes outermost.
+  - Encapsulation level ``1`` is supported.
+  - Encapsulation level ``2`` is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - ``RTE_FLOW_FIELD_VLAN_ID`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV4_PROTO`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV6_PROTO/DSCP/ECN`` are not supported.
+    - ``RTE_FLOW_FIELD_ESP_PROTO/SPI/SEQ_NUM`` are not supported.
+    - ``RTE_FLOW_FIELD_TCP_SEQ/ACK_NUM`` are not supported.
+    - Second tunnel fields are not supported.
+
+  - Encapsulation levels greater than ``2`` are not supported.
 
 - Age action:
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index f548eacc5e..a504aebe15 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -92,6 +92,8 @@ New Features
 
   * Added support for accumulating from src field to dst field.
 
+  * Added support for copy inner fields in HW Steering flow engine.
+
   * Added support for VXLAN-GPE flags/rsvd0/rsvd fields matching in DV flow
     engine (``dv_flow_en`` = 1).
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 40376c99ba..b8cb385564 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2507,10 +2507,14 @@ flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 	if (data->level == 0)
 		return 0;
 	if (data->field != RTE_FLOW_FIELD_TAG &&
-	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "inner header fields modification is not supported");
+	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG) {
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "inner header fields modification is not supported");
+		return 0;
+	}
 	if (data->tag_index != 0)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 6fded15d91..46f9f59e67 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -82,6 +82,9 @@
 		} \
 	} while (0)
 
+#define CALC_MODI_ID(field, level) \
+	(((level) > 1) ? MLX5_MODI_IN_##field : MLX5_MODI_OUT_##field)
+
 union flow_dv_attr {
 	struct {
 		uint32_t valid:1;
@@ -1638,8 +1641,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_DMAC_15_0};
+			modi_id = CALC_MODI_ID(DMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1654,8 +1657,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_DMAC_47_16};
+		modi_id = CALC_MODI_ID(DMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1665,8 +1668,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_SMAC_15_0};
+			modi_id = CALC_MODI_ID(SMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1681,8 +1684,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_SMAC_47_16};
+		modi_id = CALC_MODI_ID(SMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1704,8 +1707,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_MAC_TYPE:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_ETHERTYPE};
+		modi_id = CALC_MODI_ID(ETHERTYPE, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1714,8 +1717,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_IHL:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_IHL};
+		modi_id = CALC_MODI_ID(IPV4_IHL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1724,8 +1727,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DSCP:
 		MLX5_ASSERT(data->offset + width <= 6);
 		off_be = 6 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_DSCP};
+		modi_id = CALC_MODI_ID(IP_DSCP, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1734,8 +1737,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV4_TOTAL_LEN};
+		modi_id = CALC_MODI_ID(IPV4_TOTAL_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1744,8 +1747,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TTL:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_TTL};
+		modi_id = CALC_MODI_ID(IPV4_TTL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1754,8 +1757,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_SRC:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_SIPV4};
+		modi_id = CALC_MODI_ID(SIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1764,8 +1767,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DST:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_DIPV4};
+		modi_id = CALC_MODI_ID(DIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1795,8 +1798,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV6_PAYLOAD_LEN};
+		modi_id = CALC_MODI_ID(IPV6_PAYLOAD_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1805,8 +1808,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV6_HOPLIMIT};
+		modi_id = CALC_MODI_ID(IPV6_HOPLIMIT, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1818,10 +1821,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_SIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_SIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_SIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_SIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(SIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(SIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(SIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(SIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1861,10 +1864,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_DIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_DIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_DIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_DIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(DIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(DIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(DIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(DIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1901,8 +1904,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_SPORT};
+		modi_id = CALC_MODI_ID(TCP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1911,8 +1914,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_DPORT};
+		modi_id = CALC_MODI_ID(TCP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1921,8 +1924,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(TCP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1931,8 +1934,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_ACK_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_ACK_NUM};
+		modi_id = CALC_MODI_ID(TCP_ACK_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1941,8 +1944,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_FLAGS:
 		MLX5_ASSERT(data->offset + width <= 9);
 		off_be = 9 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_FLAGS};
+		modi_id = CALC_MODI_ID(TCP_FLAGS, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1951,8 +1954,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_TCP_DATA_OFFSET};
+		modi_id = CALC_MODI_ID(TCP_DATA_OFFSET, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1961,8 +1964,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_SPORT};
+		modi_id = CALC_MODI_ID(UDP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1971,8 +1974,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_DPORT};
+		modi_id = CALC_MODI_ID(UDP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -2124,8 +2127,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_ECN:
 		MLX5_ASSERT(data->offset + width <= 2);
 		off_be = 2 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_ECN};
+		modi_id = CALC_MODI_ID(IP_ECN, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -2221,7 +2224,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SPI:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SPI};
+		modi_id = CALC_MODI_ID(ESP_SPI, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -2230,7 +2234,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(ESP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 3af5e1f160..7a1821f457 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -4999,6 +4999,131 @@ flow_hw_modify_field_is_add_dst_valid(const struct rte_flow_action_modify_field
 	return false;
 }
 
+/**
+ * Validate the level value for modify field action.
+ *
+ * @param[in] data
+ *   Pointer to the rte_flow_field_data structure either src or dst.
+ * @param[in] inner_supported
+ *   Indicator whether inner should be supported.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
+				    bool inner_supported,
+				    struct rte_flow_error *error)
+{
+	switch ((int)data->field) {
+	case RTE_FLOW_FIELD_START:
+	case RTE_FLOW_FIELD_VLAN_TYPE:
+	case RTE_FLOW_FIELD_RANDOM:
+	case RTE_FLOW_FIELD_FLEX_ITEM:
+		/*
+		 * Level shouldn't be valid since field isn't supported or
+		 * doesn't use 'level'.
+		 */
+		break;
+	case RTE_FLOW_FIELD_MARK:
+	case RTE_FLOW_FIELD_META:
+	case RTE_FLOW_FIELD_METER_COLOR:
+	case RTE_FLOW_FIELD_HASH_RESULT:
+		/* For meta data fields encapsulation level is don't-care. */
+		break;
+	case RTE_FLOW_FIELD_TAG:
+	case MLX5_RTE_FLOW_FIELD_META_REG:
+		/*
+		 * The tag array for RTE_FLOW_FIELD_TAG type is provided using
+		 * 'tag_index' field. In old API, it was provided using 'level'
+		 * field and it is still supported for backwards compatibility.
+		 * Therefore, for meta tag field only, level is matter. It is
+		 * taken as tag index when 'tag_index' field isn't set, and
+		 * return error otherwise.
+		 */
+		if (data->level > 0) {
+			if (data->tag_index > 0)
+				return rte_flow_error_set(error, EINVAL,
+							  RTE_FLOW_ERROR_TYPE_ACTION,
+							  data,
+							  "tag array can be provided using 'level' or 'tag_index' fields, not both");
+			DRV_LOG(WARNING,
+				"tag array provided in 'level' field instead of 'tag_index' field.");
+		}
+		break;
+	case RTE_FLOW_FIELD_MAC_DST:
+	case RTE_FLOW_FIELD_MAC_SRC:
+	case RTE_FLOW_FIELD_MAC_TYPE:
+	case RTE_FLOW_FIELD_IPV4_IHL:
+	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
+	case RTE_FLOW_FIELD_IPV4_DSCP:
+	case RTE_FLOW_FIELD_IPV4_ECN:
+	case RTE_FLOW_FIELD_IPV4_TTL:
+	case RTE_FLOW_FIELD_IPV4_SRC:
+	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
+	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_SRC:
+	case RTE_FLOW_FIELD_IPV6_DST:
+	case RTE_FLOW_FIELD_TCP_PORT_SRC:
+	case RTE_FLOW_FIELD_TCP_PORT_DST:
+	case RTE_FLOW_FIELD_TCP_FLAGS:
+	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
+	case RTE_FLOW_FIELD_UDP_PORT_SRC:
+	case RTE_FLOW_FIELD_UDP_PORT_DST:
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "second inner header fields modification is not supported");
+		if (inner_supported)
+			break;
+		/* Fallthrough */
+	case RTE_FLOW_FIELD_VLAN_ID:
+	case RTE_FLOW_FIELD_IPV4_PROTO:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+	case RTE_FLOW_FIELD_IPV6_DSCP:
+	case RTE_FLOW_FIELD_IPV6_ECN:
+	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
+	case RTE_FLOW_FIELD_TCP_ACK_NUM:
+	case RTE_FLOW_FIELD_ESP_PROTO:
+	case RTE_FLOW_FIELD_ESP_SPI:
+	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
+	case RTE_FLOW_FIELD_VXLAN_VNI:
+	case RTE_FLOW_FIELD_GENEVE_VNI:
+	case RTE_FLOW_FIELD_GENEVE_OPT_TYPE:
+	case RTE_FLOW_FIELD_GENEVE_OPT_CLASS:
+	case RTE_FLOW_FIELD_GENEVE_OPT_DATA:
+	case RTE_FLOW_FIELD_GTP_TEID:
+	case RTE_FLOW_FIELD_GTP_PSC_QFI:
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner header fields modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_MPLS:
+		if (data->level == 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "outer MPLS header modification is not supported");
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner MPLS header modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_POINTER:
+	case RTE_FLOW_FIELD_VALUE:
+	default:
+		MLX5_ASSERT(false);
+	}
+	return 0;
+}
+
 static int
 flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				     const struct rte_flow_action *action,
@@ -5029,7 +5154,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"immediate value, pointer and hash result cannot be used as destination");
-	ret = flow_validate_modify_field_level(&action_conf->dst, error);
+	ret = flow_hw_validate_modify_field_level(&action_conf->dst, false, error);
 	if (ret)
 		return ret;
 	if (!flow_hw_modify_field_is_geneve_opt(action_conf->dst.field)) {
@@ -5076,7 +5201,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 			return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"source offset level must be fully masked");
-		ret = flow_validate_modify_field_level(&action_conf->src, error);
+		ret = flow_hw_validate_modify_field_level(&action_conf->src, true, error);
 		if (ret)
 			return ret;
 	}
@@ -5141,6 +5266,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				"invalid add_field destination");
 	return 0;
 }
+
 static int
 flow_hw_validate_action_port_representor(struct rte_eth_dev *dev __rte_unused,
 					 const struct rte_flow_actions_template_attr *attr,
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 6/7] net/mlx5: support modify IPv6 traffic class field
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (4 preceding siblings ...)
  2024-02-07 15:55   ` [PATCH v2 5/7] net/mlx5: add support for modify inner fields Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-07 15:55   ` [PATCH v2 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 traffic class field modification.
Copy from inner IPv6 traffic class field is also supported using
"level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 11 +++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  3 ++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index a504aebe15..50ba66daac 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -113,6 +113,7 @@ New Features
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SPI`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SEQ_NUM`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_PROTO`` flow action.
+  * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS`` flow action.
 
 
 Removed Items
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 46f9f59e67..7d92c1cc24 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
@@ -1795,6 +1796,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_TRAFFIC_CLASS, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 7a1821f457..a41b46e18f 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2874,7 +2874,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
 		 * bits left. Shift the data left for IPV6 DSCP
 		 */
 		if (field->id == MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS &&
-		    !(mask & MLX5_IPV6_HDR_ECN_MASK))
+		    mhdr_action->dst.field == RTE_FLOW_FIELD_IPV6_DSCP)
 			data <<= MLX5_IPV6_HDR_DSCP_SHIFT;
 		data = (data & mask) >> off_b;
 		job->mhdr_cmd[i++].data1 = rte_cpu_to_be_32(data);
@@ -5063,6 +5063,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
 	case RTE_FLOW_FIELD_IPV4_TTL:
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 7/7] net/mlx5: support modify IPv6 flow label field
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (5 preceding siblings ...)
  2024-02-07 15:55   ` [PATCH v2 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
@ 2024-02-07 15:55   ` Michael Baum
  2024-02-14  8:28   ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Dariusz Sosnowski
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
  8 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-07 15:55 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 flow label field modification.
Copy from inner IPv6 flow label field is also supported using "level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 12 ++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  1 +
 3 files changed, 14 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 50ba66daac..267851f920 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -114,6 +114,7 @@ New Features
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_SEQ_NUM`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_ESP_PROTO`` flow action.
   * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS`` flow action.
+  * Added HW steering support for modify field ``RTE_FLOW_FIELD_IPV6_FLOW_LABEL`` flow action.
 
 
 Removed Items
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 7d92c1cc24..bf5cd37f2f 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,8 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		return 20;
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
@@ -1806,6 +1808,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		MLX5_ASSERT(data->offset + width <= 20);
+		off_be = 20 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_FLOW_LABEL, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_32(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index a41b46e18f..1d003c9389 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5064,6 +5064,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 0/7] net/mlx5: support copy from inner fields
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (6 preceding siblings ...)
  2024-02-07 15:55   ` [PATCH v2 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
@ 2024-02-14  8:28   ` Dariusz Sosnowski
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
  8 siblings, 0 replies; 26+ messages in thread
From: Dariusz Sosnowski @ 2024-02-14  8:28 UTC (permalink / raw)
  To: Michael Baum, dev
  Cc: Matan Azrad, Raslan Darawsheh, Slava Ovsiienko, Ori Kam, Suanming Mou

> -----Original Message-----
> From: Michael Baum <michaelba@nvidia.com>
> Sent: Wednesday, February 7, 2024 16:55
> To: dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski
> <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava
> Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; Suanming
> Mou <suanmingm@nvidia.com>
> Subject: [PATCH v2 0/7] net/mlx5: support copy from inner fields
> 
> This patch-set adds support of encapsulation level for HWS modify field in MLX5
> PMD.
> Outermost is represented by 0,1 and inner is represented by 2.
> In addition, modify inner/outer us added for both IPv6 flow label and
> IPv6 traffic class.
> 
> Depends-on: series-31008 ("ethdev: add modify IPv4 next protocol field")
> Depends-on: series-31010 ("ethdev: add IPv6 field identifiers")
> 
> v2:
> - Rebase.
> - Add "copy from inner" to release notes.
> 
> Michael Baum (7):
>   common/mlx5: remove enum value duplication
>   common/mlx5: reorder modification field PRM list
>   common/mlx5: add inner PRM fields
>   common/mlx5: add IPv6 flow label PRM field
>   net/mlx5: add support for modify inner fields
>   net/mlx5: support modify IPv6 traffic class field
>   net/mlx5: support modify IPv6 flow label field
> 
>  doc/guides/nics/mlx5.rst               |  28 ++++-
>  doc/guides/rel_notes/release_24_03.rst |   4 +
>  drivers/common/mlx5/mlx5_prm.h         |  49 +++++----
>  drivers/net/mlx5/hws/mlx5dr_action.c   |   4 +-
>  drivers/net/mlx5/hws/mlx5dr_pat_arg.c  |   2 +-
>  drivers/net/mlx5/mlx5_flow.c           |  12 ++-
>  drivers/net/mlx5/mlx5_flow_dv.c        | 136 +++++++++++++++----------
>  drivers/net/mlx5/mlx5_flow_hw.c        | 134 +++++++++++++++++++++++-
>  8 files changed, 284 insertions(+), 85 deletions(-)
> 
> --
> 2.25.1
Series-acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>

Best regards,
Dariusz Sosnowski


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 0/7] net/mlx5: support copy from inner fields
  2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
                     ` (7 preceding siblings ...)
  2024-02-14  8:28   ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Dariusz Sosnowski
@ 2024-02-26 13:45   ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 1/7] common/mlx5: remove enum value duplication Michael Baum
                       ` (7 more replies)
  8 siblings, 8 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch-set adds support of encapsulation level for HWS modify field
in MLX5 PMD.
Outermost is represented by 0,1 and inner is represented by 2.
In addition, modify inner/outer us added for both IPv6 flow label and
IPv6 traffic class.

v2:
- Rebase.
- Add "copy from inner" to release notes.

v3:
 - Rebase.
 - Add "Acked-by" from v2.
 - Remove the "Depends-on" labels.

Michael Baum (7):
  common/mlx5: remove enum value duplication
  common/mlx5: reorder modification field PRM list
  common/mlx5: add inner PRM fields
  common/mlx5: add IPv6 flow label PRM field
  net/mlx5: add support for modify inner fields
  net/mlx5: support modify IPv6 traffic class field
  net/mlx5: support modify IPv6 flow label field

 doc/guides/nics/mlx5.rst               |  28 ++++-
 doc/guides/rel_notes/release_24_03.rst |   3 +
 drivers/common/mlx5/mlx5_prm.h         |  49 +++++----
 drivers/net/mlx5/hws/mlx5dr_action.c   |   4 +-
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c  |   2 +-
 drivers/net/mlx5/mlx5_flow.c           |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 136 +++++++++++++++----------
 drivers/net/mlx5/mlx5_flow_hw.c        | 134 +++++++++++++++++++++++-
 8 files changed, 283 insertions(+), 85 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 1/7] common/mlx5: remove enum value duplication
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 2/7] common/mlx5: reorder modification field PRM list Michael Baum
                       ` (6 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

The "mlx5_modification_field" enumeration has 2 different fields
representing the same value 0x4A.
 1. "MLX5_MODI_OUT_IPV6_NEXT_HDR" - specific for IPv6.
 2. "MLX5_MODI_OUT_IP_PROTOCOL" - for both IPv4 and IPv6.

This patch removes "MLX5_MODI_OUT_IPV6_NEXT_HDR" and replaces all its
usages with "MLX5_MODI_OUT_IP_PROTOCOL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h        | 1 -
 drivers/net/mlx5/hws/mlx5dr_action.c  | 4 ++--
 drivers/net/mlx5/hws/mlx5dr_pat_arg.c | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 282e59e52c..6a8cb7a8aa 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -840,7 +840,6 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
 	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x4A,
 	MLX5_MODI_META_REG_C_8 = 0x8F,
 	MLX5_MODI_META_REG_C_9 = 0x90,
 	MLX5_MODI_META_REG_C_10 = 0x91,
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c
index f55069c675..631763dee0 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -2291,7 +2291,7 @@ mlx5dr_action_create_pop_ipv6_route_ext_mhdr3(struct mlx5dr_action *action)
 	MLX5_SET(copy_action_in, cmd, length, 8);
 	MLX5_SET(copy_action_in, cmd, src_offset, 24);
 	MLX5_SET(copy_action_in, cmd, src_field, mod_id);
-	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IP_PROTOCOL);
 
 	pattern.data = (__be64 *)cmd;
 	pattern.sz = sizeof(cmd);
@@ -2352,7 +2352,7 @@ mlx5dr_action_create_push_ipv6_route_ext_mhdr1(struct mlx5dr_action *action)
 	/* Set ipv6.protocol to IPPROTO_ROUTING */
 	MLX5_SET(set_action_in, cmd, action_type, MLX5_MODIFICATION_TYPE_SET);
 	MLX5_SET(set_action_in, cmd, length, 8);
-	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IP_PROTOCOL);
 	MLX5_SET(set_action_in, cmd, data, IPPROTO_ROUTING);
 
 	pattern.data = (__be64 *)cmd;
diff --git a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
index a949844d24..513549ff3c 100644
--- a/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
+++ b/drivers/net/mlx5/hws/mlx5dr_pat_arg.c
@@ -67,7 +67,7 @@ bool mlx5dr_pat_require_reparse(__be64 *actions, uint16_t num_of_actions)
 
 		/* Below fields can change packet structure require a reparse */
 		if (field == MLX5_MODI_OUT_ETHERTYPE ||
-		    field == MLX5_MODI_OUT_IPV6_NEXT_HDR)
+		    field == MLX5_MODI_OUT_IP_PROTOCOL)
 			return true;
 	}
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 2/7] common/mlx5: reorder modification field PRM list
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
  2024-02-26 13:45     ` [PATCH v3 1/7] common/mlx5: remove enum value duplication Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 3/7] common/mlx5: add inner PRM fields Michael Baum
                       ` (5 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Reorder modification field PRM list according to values from lowest to
highest.
This patch also removes value specification from all fields which their
value is one more than previous one.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 6a8cb7a8aa..6967acbdc3 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -816,6 +816,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_HOPLIMIT,
 	MLX5_MODI_IN_IPV6_HOPLIMIT,
 	MLX5_MODI_META_DATA_REG_A,
+	MLX5_MODI_OUT_IP_PROTOCOL,
 	MLX5_MODI_META_DATA_REG_B = 0x50,
 	MLX5_MODI_META_REG_C_0,
 	MLX5_MODI_META_REG_C_1,
@@ -829,32 +830,31 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
 	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_OUT_ESP_SPI = 0x5E,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
-	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
+	MLX5_MODI_OUT_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
 	MLX5_MODI_IN_MPLS_LABEL_3,
 	MLX5_MODI_IN_MPLS_LABEL_4,
-	MLX5_MODI_OUT_IP_PROTOCOL = 0x4A,
-	MLX5_MODI_META_REG_C_8 = 0x8F,
-	MLX5_MODI_META_REG_C_9 = 0x90,
-	MLX5_MODI_META_REG_C_10 = 0x91,
-	MLX5_MODI_META_REG_C_11 = 0x92,
-	MLX5_MODI_META_REG_C_12 = 0x93,
-	MLX5_MODI_META_REG_C_13 = 0x94,
-	MLX5_MODI_META_REG_C_14 = 0x95,
-	MLX5_MODI_META_REG_C_15 = 0x96,
+	MLX5_MODI_META_REG_C_8,
+	MLX5_MODI_META_REG_C_9,
+	MLX5_MODI_META_REG_C_10,
+	MLX5_MODI_META_REG_C_11,
+	MLX5_MODI_META_REG_C_12,
+	MLX5_MODI_META_REG_C_13,
+	MLX5_MODI_META_REG_C_14,
+	MLX5_MODI_META_REG_C_15,
 	MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS = 0x11C,
-	MLX5_MODI_OUT_IPV4_TOTAL_LEN = 0x11D,
-	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN = 0x11E,
-	MLX5_MODI_OUT_IPV4_IHL = 0x11F,
-	MLX5_MODI_OUT_TCP_DATA_OFFSET = 0x120,
-	MLX5_MODI_OUT_ESP_SPI = 0x5E,
-	MLX5_MODI_OUT_ESP_SEQ_NUM = 0x82,
+	MLX5_MODI_OUT_IPV4_TOTAL_LEN,
+	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_OUT_IPV4_IHL,
+	MLX5_MODI_OUT_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
 	MLX5_MODI_INVALID = INT_MAX,
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 3/7] common/mlx5: add inner PRM fields
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
  2024-02-26 13:45     ` [PATCH v3 1/7] common/mlx5: remove enum value duplication Michael Baum
  2024-02-26 13:45     ` [PATCH v3 2/7] common/mlx5: reorder modification field PRM list Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds inner values into PRM modify field list for each
existing outer field.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 6967acbdc3..6124af1857 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -829,14 +829,17 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_TCP_SEQ_NUM,
 	MLX5_MODI_IN_TCP_SEQ_NUM,
 	MLX5_MODI_OUT_TCP_ACK_NUM,
-	MLX5_MODI_IN_TCP_ACK_NUM = 0x5C,
+	MLX5_MODI_IN_TCP_ACK_NUM,
 	MLX5_MODI_OUT_ESP_SPI = 0x5E,
+	MLX5_MODI_IN_ESP_SPI,
 	MLX5_MODI_GTP_TEID = 0x6E,
 	MLX5_MODI_OUT_IP_ECN = 0x73,
-	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
+	MLX5_MODI_IN_IP_ECN,
+	MLX5_MODI_TUNNEL_HDR_DW_1,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0,
 	MLX5_MODI_HASH_RESULT = 0x81,
 	MLX5_MODI_OUT_ESP_SEQ_NUM,
+	MLX5_MODI_IN_ESP_SEQ_NUM,
 	MLX5_MODI_IN_MPLS_LABEL_0 = 0x8a,
 	MLX5_MODI_IN_MPLS_LABEL_1,
 	MLX5_MODI_IN_MPLS_LABEL_2,
@@ -855,7 +858,12 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IPV6_PAYLOAD_LEN,
 	MLX5_MODI_OUT_IPV4_IHL,
 	MLX5_MODI_OUT_TCP_DATA_OFFSET,
-	MLX5_MODI_OUT_IPSEC_NEXT_HDR = 0x126,
+	MLX5_MODI_IN_IPV6_TRAFFIC_CLASS,
+	MLX5_MODI_IN_IPV4_TOTAL_LEN,
+	MLX5_MODI_IN_IPV6_PAYLOAD_LEN,
+	MLX5_MODI_IN_IPV4_IHL,
+	MLX5_MODI_IN_TCP_DATA_OFFSET,
+	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 4/7] common/mlx5: add IPv6 flow label PRM field
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
                       ` (2 preceding siblings ...)
  2024-02-26 13:45     ` [PATCH v3 3/7] common/mlx5: add inner PRM fields Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 5/7] net/mlx5: add support for modify inner fields Michael Baum
                       ` (3 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add IPv6 flow label field into PRM modify field list.
The new values are "MLX5_MODI_OUT_IPV6_FLOW_LABEL" and
"MLX5_MODI_IN_IPV6_FLOW_LABEL".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 6124af1857..92309d453b 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -864,6 +864,8 @@ enum mlx5_modification_field {
 	MLX5_MODI_IN_IPV4_IHL,
 	MLX5_MODI_IN_TCP_DATA_OFFSET,
 	MLX5_MODI_OUT_IPSEC_NEXT_HDR,
+	MLX5_MODI_OUT_IPV6_FLOW_LABEL,
+	MLX5_MODI_IN_IPV6_FLOW_LABEL,
 	MLX5_MODI_INVALID = INT_MAX,
 };
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 5/7] net/mlx5: add support for modify inner fields
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
                       ` (3 preceding siblings ...)
  2024-02-26 13:45     ` [PATCH v3 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

This patch adds support for copying from inner fields using "level" 2.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 doc/guides/nics/mlx5.rst               |  28 +++++-
 doc/guides/rel_notes/release_24_03.rst |   1 +
 drivers/net/mlx5/mlx5_flow.c           |  12 ++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 113 +++++++++++----------
 drivers/net/mlx5/mlx5_flow_hw.c        | 130 ++++++++++++++++++++++++-
 5 files changed, 223 insertions(+), 61 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 0d2213497a..dcf58c0a34 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -639,7 +639,6 @@ Limitations
     Only DWs configured in :ref:`parser creation <geneve_parser_api>` can be modified,
     'type' and 'class' fields can be modified when ``match_on_class_mode=2``.
   - Modification of GENEVE TLV option data supports one DW per action.
-  - Encapsulation levels are not supported, can modify outermost header fields only.
   - Offsets cannot skip past the boundary of a field.
   - If the field type is ``RTE_FLOW_FIELD_MAC_TYPE``
     and packet contains one or more VLAN headers,
@@ -653,6 +652,33 @@ Limitations
   - For flow metadata fields (e.g. META or TAG)
     offset specifies the number of bits to skip from field's start,
     starting from LSB in the least significant byte, in the host order.
+  - Modification of the MPLS header is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - Only for outermost tunnel header (``level=2``).
+      For ``RTE_FLOW_FIELD_MPLS``,
+      the default encapsulation level ``0`` describes the outermost tunnel header.
+
+      .. note::
+
+         the default encapsulation level ``0`` describes the "outermost that match is supported",
+         currently it is first tunnel, but it can be changed to outer when it is supported.
+
+  - Default encapsulation level ``0`` describes outermost.
+  - Encapsulation level ``1`` is supported.
+  - Encapsulation level ``2`` is supported with some limitations:
+
+    - Only in HW steering.
+    - Only in ``src`` field.
+    - ``RTE_FLOW_FIELD_VLAN_ID`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV4_PROTO`` is not supported.
+    - ``RTE_FLOW_FIELD_IPV6_PROTO/DSCP/ECN`` are not supported.
+    - ``RTE_FLOW_FIELD_ESP_PROTO/SPI/SEQ_NUM`` are not supported.
+    - ``RTE_FLOW_FIELD_TCP_SEQ/ACK_NUM`` are not supported.
+    - Second tunnel fields are not supported.
+
+  - Encapsulation levels greater than ``2`` are not supported.
 
 - Age action:
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 879bb4944c..0473858e19 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -130,6 +130,7 @@ New Features
   * Added support for matching a random value.
   * Added support for comparing result between packet fields or value.
   * Added support for accumulating value of field into another one.
+  * Added support for copy inner fields in HWS flow engine.
 
 * **Updated Marvell cnxk crypto driver.**
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2b2ae62618..3e179110a0 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2387,10 +2387,14 @@ flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 	if (data->level == 0)
 		return 0;
 	if (data->field != RTE_FLOW_FIELD_TAG &&
-	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "inner header fields modification is not supported");
+	    data->field != (enum rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG) {
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "inner header fields modification is not supported");
+		return 0;
+	}
 	if (data->tag_index != 0)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 42810e359c..feda003c07 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -82,6 +82,9 @@
 		} \
 	} while (0)
 
+#define CALC_MODI_ID(field, level) \
+	(((level) > 1) ? MLX5_MODI_IN_##field : MLX5_MODI_OUT_##field)
+
 union flow_dv_attr {
 	struct {
 		uint32_t valid:1;
@@ -1638,8 +1641,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_DMAC_15_0};
+			modi_id = CALC_MODI_ID(DMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1654,8 +1657,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_DMAC_47_16};
+		modi_id = CALC_MODI_ID(DMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1665,8 +1668,8 @@ mlx5_flow_field_id_to_modify_info
 		MLX5_ASSERT(data->offset + width <= 48);
 		off_be = 48 - (data->offset + width);
 		if (off_be < 16) {
-			info[idx] = (struct field_modify_info){2, 4,
-					MLX5_MODI_OUT_SMAC_15_0};
+			modi_id = CALC_MODI_ID(SMAC_15_0, data->level);
+			info[idx] = (struct field_modify_info){2, 4, modi_id};
 			length = off_be + width <= 16 ? width : 16 - off_be;
 			if (mask)
 				mask[1] = flow_modify_info_mask_16(length,
@@ -1681,8 +1684,8 @@ mlx5_flow_field_id_to_modify_info
 		} else {
 			off_be -= 16;
 		}
-		info[idx] = (struct field_modify_info){4, 0,
-				MLX5_MODI_OUT_SMAC_47_16};
+		modi_id = CALC_MODI_ID(SMAC_47_16, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[0] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1704,8 +1707,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_MAC_TYPE:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_ETHERTYPE};
+		modi_id = CALC_MODI_ID(ETHERTYPE, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1714,8 +1717,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_IHL:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_IHL};
+		modi_id = CALC_MODI_ID(IPV4_IHL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1724,8 +1727,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DSCP:
 		MLX5_ASSERT(data->offset + width <= 6);
 		off_be = 6 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_DSCP};
+		modi_id = CALC_MODI_ID(IP_DSCP, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1734,8 +1737,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV4_TOTAL_LEN};
+		modi_id = CALC_MODI_ID(IPV4_TOTAL_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1744,8 +1747,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_TTL:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV4_TTL};
+		modi_id = CALC_MODI_ID(IPV4_TTL, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1754,8 +1757,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_SRC:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_SIPV4};
+		modi_id = CALC_MODI_ID(SIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1764,8 +1767,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_DST:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_DIPV4};
+		modi_id = CALC_MODI_ID(DIPV4, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1795,8 +1798,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_IPV6_PAYLOAD_LEN};
+		modi_id = CALC_MODI_ID(IPV6_PAYLOAD_LEN, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1805,8 +1808,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 		MLX5_ASSERT(data->offset + width <= 8);
 		off_be = 8 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IPV6_HOPLIMIT};
+		modi_id = CALC_MODI_ID(IPV6_HOPLIMIT, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1818,10 +1821,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_SIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_SIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_SIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_SIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(SIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(SIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(SIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(SIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1861,10 +1864,10 @@ mlx5_flow_field_id_to_modify_info
 		 * arranged according to network byte ordering.
 		 */
 		struct field_modify_info fields[] = {
-			{ 4, 0, MLX5_MODI_OUT_DIPV6_127_96 },
-			{ 4, 4, MLX5_MODI_OUT_DIPV6_95_64 },
-			{ 4, 8, MLX5_MODI_OUT_DIPV6_63_32 },
-			{ 4, 12, MLX5_MODI_OUT_DIPV6_31_0 },
+			{ 4, 0, CALC_MODI_ID(DIPV6_127_96, data->level)},
+			{ 4, 4, CALC_MODI_ID(DIPV6_95_64, data->level)},
+			{ 4, 8, CALC_MODI_ID(DIPV6_63_32, data->level)},
+			{ 4, 12, CALC_MODI_ID(DIPV6_31_0, data->level)},
 		};
 		/* First mask to be modified is the mask of 4th address byte. */
 		uint32_t midx = 3;
@@ -1901,8 +1904,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_SPORT};
+		modi_id = CALC_MODI_ID(TCP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1911,8 +1914,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_DPORT};
+		modi_id = CALC_MODI_ID(TCP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1921,8 +1924,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(TCP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1931,8 +1934,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_ACK_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0,
-					MLX5_MODI_OUT_TCP_ACK_NUM};
+		modi_id = CALC_MODI_ID(TCP_ACK_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -1941,8 +1944,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_FLAGS:
 		MLX5_ASSERT(data->offset + width <= 9);
 		off_be = 9 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_TCP_FLAGS};
+		modi_id = CALC_MODI_ID(TCP_FLAGS, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1951,8 +1954,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
 		MLX5_ASSERT(data->offset + width <= 4);
 		off_be = 4 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_TCP_DATA_OFFSET};
+		modi_id = CALC_MODI_ID(TCP_DATA_OFFSET, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -1961,8 +1964,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_SRC:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_SPORT};
+		modi_id = CALC_MODI_ID(UDP_SPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -1971,8 +1974,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_UDP_PORT_DST:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
-		info[idx] = (struct field_modify_info){2, 0,
-					MLX5_MODI_OUT_UDP_DPORT};
+		modi_id = CALC_MODI_ID(UDP_DPORT, data->level);
+		info[idx] = (struct field_modify_info){2, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_16(width, off_be);
 		else
@@ -2124,8 +2127,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_IPV4_ECN:
 		MLX5_ASSERT(data->offset + width <= 2);
 		off_be = 2 - (data->offset + width);
-		info[idx] = (struct field_modify_info){1, 0,
-					MLX5_MODI_OUT_IP_ECN};
+		modi_id = CALC_MODI_ID(IP_ECN, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_8(width, off_be);
 		else
@@ -2221,7 +2224,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SPI:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SPI};
+		modi_id = CALC_MODI_ID(ESP_SPI, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
@@ -2230,7 +2234,8 @@ mlx5_flow_field_id_to_modify_info
 	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
 		MLX5_ASSERT(data->offset + width <= 32);
 		off_be = 32 - (data->offset + width);
-		info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_ESP_SEQ_NUM};
+		modi_id = CALC_MODI_ID(ESP_SEQ_NUM, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
 		if (mask)
 			mask[idx] = flow_modify_info_mask_32(width, off_be);
 		else
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 3ae1220587..fc1bcdd84e 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5003,6 +5003,131 @@ flow_hw_modify_field_is_add_dst_valid(const struct rte_flow_action_modify_field
 	return false;
 }
 
+/**
+ * Validate the level value for modify field action.
+ *
+ * @param[in] data
+ *   Pointer to the rte_flow_field_data structure either src or dst.
+ * @param[in] inner_supported
+ *   Indicator whether inner should be supported.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
+				    bool inner_supported,
+				    struct rte_flow_error *error)
+{
+	switch ((int)data->field) {
+	case RTE_FLOW_FIELD_START:
+	case RTE_FLOW_FIELD_VLAN_TYPE:
+	case RTE_FLOW_FIELD_RANDOM:
+	case RTE_FLOW_FIELD_FLEX_ITEM:
+		/*
+		 * Level shouldn't be valid since field isn't supported or
+		 * doesn't use 'level'.
+		 */
+		break;
+	case RTE_FLOW_FIELD_MARK:
+	case RTE_FLOW_FIELD_META:
+	case RTE_FLOW_FIELD_METER_COLOR:
+	case RTE_FLOW_FIELD_HASH_RESULT:
+		/* For meta data fields encapsulation level is don't-care. */
+		break;
+	case RTE_FLOW_FIELD_TAG:
+	case MLX5_RTE_FLOW_FIELD_META_REG:
+		/*
+		 * The tag array for RTE_FLOW_FIELD_TAG type is provided using
+		 * 'tag_index' field. In old API, it was provided using 'level'
+		 * field and it is still supported for backwards compatibility.
+		 * Therefore, for meta tag field only, level is matter. It is
+		 * taken as tag index when 'tag_index' field isn't set, and
+		 * return error otherwise.
+		 */
+		if (data->level > 0) {
+			if (data->tag_index > 0)
+				return rte_flow_error_set(error, EINVAL,
+							  RTE_FLOW_ERROR_TYPE_ACTION,
+							  data,
+							  "tag array can be provided using 'level' or 'tag_index' fields, not both");
+			DRV_LOG(WARNING,
+				"tag array provided in 'level' field instead of 'tag_index' field.");
+		}
+		break;
+	case RTE_FLOW_FIELD_MAC_DST:
+	case RTE_FLOW_FIELD_MAC_SRC:
+	case RTE_FLOW_FIELD_MAC_TYPE:
+	case RTE_FLOW_FIELD_IPV4_IHL:
+	case RTE_FLOW_FIELD_IPV4_TOTAL_LEN:
+	case RTE_FLOW_FIELD_IPV4_DSCP:
+	case RTE_FLOW_FIELD_IPV4_ECN:
+	case RTE_FLOW_FIELD_IPV4_TTL:
+	case RTE_FLOW_FIELD_IPV4_SRC:
+	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
+	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_SRC:
+	case RTE_FLOW_FIELD_IPV6_DST:
+	case RTE_FLOW_FIELD_TCP_PORT_SRC:
+	case RTE_FLOW_FIELD_TCP_PORT_DST:
+	case RTE_FLOW_FIELD_TCP_FLAGS:
+	case RTE_FLOW_FIELD_TCP_DATA_OFFSET:
+	case RTE_FLOW_FIELD_UDP_PORT_SRC:
+	case RTE_FLOW_FIELD_UDP_PORT_DST:
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "second inner header fields modification is not supported");
+		if (inner_supported)
+			break;
+		/* Fallthrough */
+	case RTE_FLOW_FIELD_VLAN_ID:
+	case RTE_FLOW_FIELD_IPV4_PROTO:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+	case RTE_FLOW_FIELD_IPV6_DSCP:
+	case RTE_FLOW_FIELD_IPV6_ECN:
+	case RTE_FLOW_FIELD_TCP_SEQ_NUM:
+	case RTE_FLOW_FIELD_TCP_ACK_NUM:
+	case RTE_FLOW_FIELD_ESP_PROTO:
+	case RTE_FLOW_FIELD_ESP_SPI:
+	case RTE_FLOW_FIELD_ESP_SEQ_NUM:
+	case RTE_FLOW_FIELD_VXLAN_VNI:
+	case RTE_FLOW_FIELD_GENEVE_VNI:
+	case RTE_FLOW_FIELD_GENEVE_OPT_TYPE:
+	case RTE_FLOW_FIELD_GENEVE_OPT_CLASS:
+	case RTE_FLOW_FIELD_GENEVE_OPT_DATA:
+	case RTE_FLOW_FIELD_GTP_TEID:
+	case RTE_FLOW_FIELD_GTP_PSC_QFI:
+		if (data->level > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner header fields modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_MPLS:
+		if (data->level == 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "outer MPLS header modification is not supported");
+		if (data->level > 2)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  data,
+						  "inner MPLS header modification is not supported");
+		break;
+	case RTE_FLOW_FIELD_POINTER:
+	case RTE_FLOW_FIELD_VALUE:
+	default:
+		MLX5_ASSERT(false);
+	}
+	return 0;
+}
+
 static int
 flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				     const struct rte_flow_action *action,
@@ -5033,7 +5158,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"immediate value, pointer and hash result cannot be used as destination");
-	ret = flow_validate_modify_field_level(&action_conf->dst, error);
+	ret = flow_hw_validate_modify_field_level(&action_conf->dst, false, error);
 	if (ret)
 		return ret;
 	if (!flow_hw_modify_field_is_geneve_opt(action_conf->dst.field)) {
@@ -5080,7 +5205,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 			return rte_flow_error_set(error, EINVAL,
 				RTE_FLOW_ERROR_TYPE_ACTION, action,
 				"source offset level must be fully masked");
-		ret = flow_validate_modify_field_level(&action_conf->src, error);
+		ret = flow_hw_validate_modify_field_level(&action_conf->src, true, error);
 		if (ret)
 			return ret;
 	}
@@ -5145,6 +5270,7 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
 				"invalid add_field destination");
 	return 0;
 }
+
 static int
 flow_hw_validate_action_port_representor(struct rte_eth_dev *dev __rte_unused,
 					 const struct rte_flow_actions_template_attr *attr,
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 6/7] net/mlx5: support modify IPv6 traffic class field
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
                       ` (4 preceding siblings ...)
  2024-02-26 13:45     ` [PATCH v3 5/7] net/mlx5: add support for modify inner fields Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-26 13:45     ` [PATCH v3 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
  2024-02-27 13:24     ` [PATCH v3 0/7] net/mlx5: support copy from inner fields Raslan Darawsheh
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 traffic class field modification.
Copy from inner IPv6 traffic class field is also supported using
"level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 11 +++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  3 ++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 0473858e19..c2fc22ed66 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -127,6 +127,7 @@ New Features
   * Added support for GENEVE matching and modifying in HWS flow engine.
   * Added support for modifying IPv4 proto field in HWS flow engine.
   * Added support for modifying IPsec ESP fields in HWS flow engine.
+  * Added support for modifying IPv6 traffic class field in HWS flow engine.
   * Added support for matching a random value.
   * Added support for comparing result between packet fields or value.
   * Added support for accumulating value of field into another one.
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index feda003c07..2c0c8e37f7 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
@@ -1795,6 +1796,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_TRAFFIC_CLASS, data->level);
+		info[idx] = (struct field_modify_info){1, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index fc1bcdd84e..9d4fdb06c1 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2878,7 +2878,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
 		 * bits left. Shift the data left for IPv6 DSCP
 		 */
 		if (field->id == MLX5_MODI_OUT_IPV6_TRAFFIC_CLASS &&
-		    !(mask & MLX5_IPV6_HDR_ECN_MASK))
+		    mhdr_action->dst.field == RTE_FLOW_FIELD_IPV6_DSCP)
 			data <<= MLX5_IPV6_HDR_DSCP_SHIFT;
 		data = (data & mask) >> off_b;
 		job->mhdr_cmd[i++].data1 = rte_cpu_to_be_32(data);
@@ -5067,6 +5067,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
 	case RTE_FLOW_FIELD_IPV4_TTL:
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
+	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v3 7/7] net/mlx5: support modify IPv6 flow label field
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
                       ` (5 preceding siblings ...)
  2024-02-26 13:45     ` [PATCH v3 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
@ 2024-02-26 13:45     ` Michael Baum
  2024-02-27 13:24     ` [PATCH v3 0/7] net/mlx5: support copy from inner fields Raslan Darawsheh
  7 siblings, 0 replies; 26+ messages in thread
From: Michael Baum @ 2024-02-26 13:45 UTC (permalink / raw)
  To: dev
  Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou

Add HW steering support for IPv6 flow label field modification.
Copy from inner IPv6 flow label field is also supported using "level=2".

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 12 ++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c        |  1 +
 3 files changed, 14 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index c2fc22ed66..ff9c6552e4 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -128,6 +128,7 @@ New Features
   * Added support for modifying IPv4 proto field in HWS flow engine.
   * Added support for modifying IPsec ESP fields in HWS flow engine.
   * Added support for modifying IPv6 traffic class field in HWS flow engine.
+  * Added support for modifying IPv6 flow label field in HWS flow engine.
   * Added support for matching a random value.
   * Added support for comparing result between packet fields or value.
   * Added support for accumulating value of field into another one.
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 2c0c8e37f7..75a8a223ab 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1394,6 +1394,8 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 		return 32;
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		return 20;
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_PROTO:
@@ -1806,6 +1808,16 @@ mlx5_flow_field_id_to_modify_info
 		else
 			info[idx].offset = off_be;
 		break;
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
+		MLX5_ASSERT(data->offset + width <= 20);
+		off_be = 20 - (data->offset + width);
+		modi_id = CALC_MODI_ID(IPV6_FLOW_LABEL, data->level);
+		info[idx] = (struct field_modify_info){4, 0, modi_id};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_32(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 		MLX5_ASSERT(data->offset + width <= 16);
 		off_be = 16 - (data->offset + width);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 9d4fdb06c1..254273e0fb 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5068,6 +5068,7 @@ flow_hw_validate_modify_field_level(const struct rte_flow_field_data *data,
 	case RTE_FLOW_FIELD_IPV4_SRC:
 	case RTE_FLOW_FIELD_IPV4_DST:
 	case RTE_FLOW_FIELD_IPV6_TRAFFIC_CLASS:
+	case RTE_FLOW_FIELD_IPV6_FLOW_LABEL:
 	case RTE_FLOW_FIELD_IPV6_PAYLOAD_LEN:
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
 	case RTE_FLOW_FIELD_IPV6_SRC:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v3 0/7] net/mlx5: support copy from inner fields
  2024-02-26 13:45   ` [PATCH v3 " Michael Baum
                       ` (6 preceding siblings ...)
  2024-02-26 13:45     ` [PATCH v3 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
@ 2024-02-27 13:24     ` Raslan Darawsheh
  7 siblings, 0 replies; 26+ messages in thread
From: Raslan Darawsheh @ 2024-02-27 13:24 UTC (permalink / raw)
  To: Michael Baum, dev
  Cc: Matan Azrad, Dariusz Sosnowski, Slava Ovsiienko, Ori Kam, Suanming Mou

Hi,

> -----Original Message-----
> From: Michael Baum <michaelba@nvidia.com>
> Sent: Monday, February 26, 2024 3:46 PM
> To: dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski
> <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava
> Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>;
> Suanming Mou <suanmingm@nvidia.com>
> Subject: [PATCH v3 0/7] net/mlx5: support copy from inner fields
> 
> This patch-set adds support of encapsulation level for HWS modify field in
> MLX5 PMD.
> Outermost is represented by 0,1 and inner is represented by 2.
> In addition, modify inner/outer us added for both IPv6 flow label and
> IPv6 traffic class.
> 
> v2:
> - Rebase.
> - Add "copy from inner" to release notes.
> 
> v3:
>  - Rebase.
>  - Add "Acked-by" from v2.
>  - Remove the "Depends-on" labels.
> 
> Michael Baum (7):
>   common/mlx5: remove enum value duplication
>   common/mlx5: reorder modification field PRM list
>   common/mlx5: add inner PRM fields
>   common/mlx5: add IPv6 flow label PRM field
>   net/mlx5: add support for modify inner fields
>   net/mlx5: support modify IPv6 traffic class field
>   net/mlx5: support modify IPv6 flow label field
> 
>  doc/guides/nics/mlx5.rst               |  28 ++++-
>  doc/guides/rel_notes/release_24_03.rst |   3 +
>  drivers/common/mlx5/mlx5_prm.h         |  49 +++++----
>  drivers/net/mlx5/hws/mlx5dr_action.c   |   4 +-
>  drivers/net/mlx5/hws/mlx5dr_pat_arg.c  |   2 +-
>  drivers/net/mlx5/mlx5_flow.c           |  12 ++-
>  drivers/net/mlx5/mlx5_flow_dv.c        | 136 +++++++++++++++----------
>  drivers/net/mlx5/mlx5_flow_hw.c        | 134 +++++++++++++++++++++++-
>  8 files changed, 283 insertions(+), 85 deletions(-)
> 
> --
> 2.25.1
Series applied to next-net-mlx,
Kindest regards,
Raslan Darawsheh

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2024-02-27 13:24 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-06 14:39 [PATCH v1 0/7] net/mlx5: support copy from inner fields Michael Baum
2024-02-06 14:39 ` [PATCH v1 1/7] common/mlx5: remove enum value duplication Michael Baum
2024-02-06 14:39 ` [PATCH v1 2/7] common/mlx5: reorder modification field PRM list Michael Baum
2024-02-06 14:39 ` [PATCH v1 3/7] common/mlx5: add inner PRM fields Michael Baum
2024-02-06 14:39 ` [PATCH v1 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
2024-02-06 14:39 ` [PATCH v1 5/7] net/mlx5: add support for modify inner fields Michael Baum
2024-02-06 14:39 ` [PATCH v1 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
2024-02-06 14:39 ` [PATCH v1 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
2024-02-07 15:55 ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Michael Baum
2024-02-07 15:55   ` [PATCH v2 1/7] common/mlx5: remove enum value duplication Michael Baum
2024-02-07 15:55   ` [PATCH v2 2/7] common/mlx5: reorder modification field PRM list Michael Baum
2024-02-07 15:55   ` [PATCH v2 3/7] common/mlx5: add inner PRM fields Michael Baum
2024-02-07 15:55   ` [PATCH v2 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
2024-02-07 15:55   ` [PATCH v2 5/7] net/mlx5: add support for modify inner fields Michael Baum
2024-02-07 15:55   ` [PATCH v2 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
2024-02-07 15:55   ` [PATCH v2 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
2024-02-14  8:28   ` [PATCH v2 0/7] net/mlx5: support copy from inner fields Dariusz Sosnowski
2024-02-26 13:45   ` [PATCH v3 " Michael Baum
2024-02-26 13:45     ` [PATCH v3 1/7] common/mlx5: remove enum value duplication Michael Baum
2024-02-26 13:45     ` [PATCH v3 2/7] common/mlx5: reorder modification field PRM list Michael Baum
2024-02-26 13:45     ` [PATCH v3 3/7] common/mlx5: add inner PRM fields Michael Baum
2024-02-26 13:45     ` [PATCH v3 4/7] common/mlx5: add IPv6 flow label PRM field Michael Baum
2024-02-26 13:45     ` [PATCH v3 5/7] net/mlx5: add support for modify inner fields Michael Baum
2024-02-26 13:45     ` [PATCH v3 6/7] net/mlx5: support modify IPv6 traffic class field Michael Baum
2024-02-26 13:45     ` [PATCH v3 7/7] net/mlx5: support modify IPv6 flow label field Michael Baum
2024-02-27 13:24     ` [PATCH v3 0/7] net/mlx5: support copy from inner fields Raslan Darawsheh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).