DPDK patches and discussions
 help / color / mirror / Atom feed
* [RFC 0/9] support ipv6 routing header matching
@ 2022-12-21  8:42 Rongwei Liu
  2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
                   ` (8 more replies)
  0 siblings, 9 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:42 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Support IPv6 routing extension header matching.

Rongwei Liu (9):
  ethdev: add IPv6 routing extension header definition
  app/testpmd: add IPv6 routing extension header support
  net/mlx5: adopt new flex item definition
  net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data
  net/mlx5/hws: add IPv6 routing extension matching support
  app/testpmd: add IPv6 routing extension header in raw encap
  ethdev: add modify IPv6 protocol field
  app/testpmd: add modify IPv6 protocol command line
  net/mlx5/hws: add modify IPv6 protocol implementation

 app/test-pmd/cmdline_flow.c            |  61 ++++++++++-
 doc/guides/nics/features/mlx5.ini      |   1 +
 doc/guides/nics/mlx5.rst               |   1 +
 doc/guides/prog_guide/rte_flow.rst     |   9 ++
 doc/guides/rel_notes/release_22_03.rst |  11 ++
 drivers/common/mlx5/mlx5_devx_cmds.c   |  13 ++-
 drivers/common/mlx5/mlx5_devx_cmds.h   |   7 +-
 drivers/common/mlx5/mlx5_prm.h         |  23 +++-
 drivers/net/mlx5/hws/mlx5dr.h          |  21 ++++
 drivers/net/mlx5/hws/mlx5dr_context.c  |  81 +++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_context.h  |   1 +
 drivers/net/mlx5/hws/mlx5dr_definer.c  | 144 +++++++++++++++++++++----
 drivers/net/mlx5/mlx5.c                |  15 ++-
 drivers/net/mlx5/mlx5.h                |  13 ++-
 drivers/net/mlx5/mlx5_flow.h           |   3 +
 drivers/net/mlx5/mlx5_flow_dv.c        |  10 ++
 drivers/net/mlx5/mlx5_flow_flex.c      |  14 ++-
 drivers/net/mlx5/mlx5_flow_hw.c        |  39 +++++--
 lib/ethdev/rte_flow.c                  |  15 +++
 lib/ethdev/rte_flow.h                  |  40 +++++++
 lib/net/rte_ip.h                       |  21 ++++
 21 files changed, 500 insertions(+), 43 deletions(-)

-- 
2.27.0


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

* [RFC 1/9] ethdev: add IPv6 routing extension header definition
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
@ 2022-12-21  8:42 ` Rongwei Liu
  2023-01-16 16:15   ` Ori Kam
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
  2022-12-21  8:42 ` [RFC 2/9] app/testpmd: add IPv6 routing extension header support Rongwei Liu
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:42 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Ferruh Yigit,
	Andrew Rybchenko, Olivier Matz
  Cc: dev, rasland

Add IPv6 routing extension header definition and no
TLV support for now.
At rte_flow layer, there are new items defined for matching
type/nexthdr/segment_left field.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  9 ++++++
 doc/guides/rel_notes/release_22_03.rst |  5 ++++
 lib/ethdev/rte_flow.c                  | 15 ++++++++++
 lib/ethdev/rte_flow.h                  | 39 ++++++++++++++++++++++++++
 lib/net/rte_ip.h                       | 21 ++++++++++++++
 5 files changed, 89 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..1ebc159893 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^
+
+Matches ipv6 routing extension header.
+
+- ``nexthdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on 
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index 0923707cb8..cc050ff3e7 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -207,6 +207,11 @@ API Changes
 * ethdev: Old public macros and enumeration constants without ``RTE_ETH_`` prefix,
   which are kept for backward compatibility, are marked as deprecated.
 
+* ethdev: added a new structure:
+
+    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
+      ``rte_ipv6_routing_ext``
+
 * cryptodev: The asymmetric session handling was modified to use a single
   mempool object. An API ``rte_cryptodev_asym_session_pool_create`` was added
   to create a mempool with element size big enough to hold the generic asymmetric
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..e08b690300 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -76,6 +76,19 @@ rte_flow_item_flex_conv(void *buf, const void *data)
 	return src->length;
 }
 
+static size_t
+rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
+{
+	struct rte_flow_item_ipv6_routing_ext *dst = buf;
+	const struct rte_flow_item_ipv6_routing_ext *src = data;
+
+	if (buf)
+		rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
+			   src->hdr.segments,
+			   src->hdr.segments_left << 4);
+	return src->hdr.segments_left << 4;
+}
+
 /** Generate flow_item[] entry. */
 #define MK_FLOW_ITEM(t, s) \
 	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
@@ -157,6 +170,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
+			rte_flow_item_ipv6_routing_ext_conv),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..f8f1d6f9dd 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,33 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * See struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
+
+	/**
+	 * Matches IPv6 routing extension header next header.
+	 *
+	 * See struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_NEXT_HDR,
+
+	/**
+	 * Matches IPv6 routing extension header type.
+	 *
+	 * See struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_TYPE,
+
+	/**
+	 * Matches IPv6 routing extension header segment left.
+	 *
+	 * See struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_SEG_LEFT,
 };
 
 /**
@@ -873,6 +900,18 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..2b9a65dfcb 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t nexthdr;			/**< Protocol, next header. */
+	uint8_t hdrlen;				/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		uint32_t flags;
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			uint16_t tag;		/**< Packet tag. */
+		};
+	};
+	__extension__
+	uint32_t segments[0];			/**< Each hop IPv6 address. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [RFC 2/9] app/testpmd: add IPv6 routing extension header support
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
  2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2022-12-21  8:42 ` Rongwei Liu
  2022-12-21  8:42 ` [RFC 3/9] net/mlx5: adopt new flex item definition Rongwei Liu
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:42 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang; +Cc: dev, rasland

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 41 ++++++++++++++++++++++++++
 doc/guides/rel_notes/release_22_03.rst |  6 ++++
 2 files changed, 47 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..70685aafb1 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,10 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3853,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ipv6_routing_ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ipv6_routing_ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.nexthdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ipv6_routing_ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index cc050ff3e7..6208f2677c 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,12 @@ New Features
   Added ``gre_option`` item in rte_flow to support checksum/key/sequence
   matching in GRE packets.
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` ``ipv6_routing_ext_type`` ``ipv6_routing_ext_seg_left``
+  and ``ipv6_routing_ext_next_hdr`` items in rte_flow to match IPv6 routing extension
+  header.
+
 * **Added new RSS offload types for L2TPv2 in RSS flow.**
 
   Added ``RTE_ETH_RSS_L2TPV2`` macro so that he L2TPv2 session ID field can be used as
-- 
2.27.0


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

* [RFC 3/9] net/mlx5: adopt new flex item definition
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
  2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2022-12-21  8:42 ` [RFC 2/9] app/testpmd: add IPv6 routing extension header support Rongwei Liu
@ 2022-12-21  8:42 ` Rongwei Liu
  2022-12-21  8:42 ` [RFC 4/9] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:42 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Per newest PRM definition, sample_id stands for 3 parts
of information instead of single uint32_t id: sample_id +
modify_filed_id + formate_select_dw.

Also new FW capability bits have been introduces to identify
the new capability.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 13 +++++++++++--
 drivers/common/mlx5/mlx5_devx_cmds.h |  7 ++++++-
 drivers/common/mlx5/mlx5_prm.h       | 22 ++++++++++++++++++++--
 drivers/net/mlx5/mlx5.c              | 15 +++++++++++----
 drivers/net/mlx5/mlx5.h              |  3 ++-
 drivers/net/mlx5/mlx5_flow_flex.c    | 14 +++++++++++---
 6 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 59cebb530f..ccd03e2a94 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -607,7 +607,8 @@ mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
 
 int
 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				  uint32_t ids[], uint32_t num)
+				  struct mlx5_ext_sample_id ids[],
+				  uint32_t num, uint8_t *anchor)
 {
 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
 	uint32_t out[MLX5_ST_SZ_DW(create_flex_parser_out)] = {0};
@@ -636,6 +637,7 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			(void *)flex_obj);
 		return -rte_errno;
 	}
+	*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
 	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
 		void *s_off = (void *)((char *)sample + i *
 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
@@ -645,8 +647,9 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			      flow_match_sample_en);
 		if (!en)
 			continue;
-		ids[idx++] = MLX5_GET(parse_graph_flow_match_sample, s_off,
+		ids[idx++].id = MLX5_GET(parse_graph_flow_match_sample, s_off,
 				  flow_match_sample_field_id);
+		printf("id index %d val %x\n", idx - 1, ids[idx-1].id);
 	}
 	if (num != idx) {
 		rte_errno = EINVAL;
@@ -794,6 +797,12 @@ mlx5_devx_cmd_query_hca_parse_graph_node_cap
 					 max_num_arc_out);
 	attr->max_num_sample = MLX5_GET(parse_graph_node_cap, hcattr,
 					max_num_sample);
+	attr->anchor_en = MLX5_GET(parse_graph_node_cap, hcattr, anchor_en);
+	attr->ext_sample_id = MLX5_GET(parse_graph_node_cap, hcattr, ext_sample_id);
+	attr->sample_tunnel_inner2 = MLX5_GET(parse_graph_node_cap, hcattr,
+					      sample_tunnel_inner2);
+	attr->zero_size_supported = MLX5_GET(parse_graph_node_cap, hcattr,
+					     zero_size_supported);
 	attr->sample_id_in_out = MLX5_GET(parse_graph_node_cap, hcattr,
 					  sample_id_in_out);
 	attr->max_base_header_length = MLX5_GET(parse_graph_node_cap, hcattr,
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index c94b9eac06..5b33010155 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -114,6 +114,10 @@ struct mlx5_hca_flex_attr {
 	uint8_t  max_num_arc_out;
 	uint8_t  max_num_sample;
 	uint8_t  max_num_prog_sample:5;	/* From HCA CAP 2 */
+	uint8_t  anchor_en:1;
+	uint8_t  ext_sample_id:1;
+	uint8_t  sample_tunnel_inner2:1;
+	uint8_t  zero_size_supported:1;
 	uint8_t  sample_id_in_out:1;
 	uint16_t max_base_header_length;
 	uint8_t  max_sample_base_offset;
@@ -706,7 +710,8 @@ int mlx5_devx_cmd_modify_tir(struct mlx5_devx_obj *tir,
 			     struct mlx5_devx_modify_tir_attr *tir_attr);
 __rte_internal
 int mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				      uint32_t ids[], uint32_t num);
+				      struct mlx5_ext_sample_id ids[],
+				      uint32_t num, uint8_t *anchor);
 
 __rte_internal
 struct mlx5_devx_obj *
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 2b5c43ee6e..1545b929b6 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1890,7 +1890,11 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 max_num_arc_in[0x08];
 	u8 max_num_arc_out[0x08];
 	u8 max_num_sample[0x08];
-	u8 reserved_at_78[0x07];
+	u8 reserved_at_78[0x03];
+	u8 anchor_en[0x1];
+	u8 ext_sample_id[0x1];
+	u8 sample_tunnel_inner2[0x1];
+	u8 zero_size_supported[0x1];
 	u8 sample_id_in_out[0x1];
 	u8 max_base_header_length[0x10];
 	u8 reserved_at_90[0x08];
@@ -1900,6 +1904,18 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 header_length_mask_width[0x08];
 };
 
+/* ext_sample_id structure, see PRM Table 539. */
+struct mlx5_ext_sample_id {
+	union {
+		struct {
+			uint32_t format_select_dw:8;
+			uint32_t modify_field_id:12;
+			uint32_t sample_id:12;
+		};
+		uint32_t id;
+	};
+};
+
 struct mlx5_ifc_flow_table_prop_layout_bits {
 	u8 ft_support[0x1];
 	u8 flow_tag[0x1];
@@ -4455,7 +4471,9 @@ struct mlx5_ifc_parse_graph_flex_bits {
 	u8 header_length_mode[0x4];
 	u8 header_length_field_offset[0x10];
 	u8 next_header_field_offset[0x10];
-	u8 reserved_at_160[0x1b];
+	u8 reserved_at_160[0x12];
+	u8 head_anchor_id[0x6];
+	u8 reserved_at_178[0x3];
 	u8 next_header_field_size[0x5];
 	u8 header_length_field_mask[0x20];
 	u8 reserved_at_224[0x20];
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index e55be8720e..04b641aa75 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -964,11 +964,13 @@ int
 mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_ecpri_parser_profile *prf =	&priv->sh->ecpri_parser;
 	struct mlx5_devx_graph_node_attr node = {
 		.modify_field_select = 0,
 	};
-	uint32_t ids[8];
+	struct mlx5_ext_sample_id ids[8];
+	uint8_t anchor_id;
 	int ret;
 
 	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
@@ -1004,15 +1006,20 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->num = 2;
-	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num);
+	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, &anchor_id);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to query sample IDs.");
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->offset[0] = 0x0;
 	prf->offset[1] = sizeof(uint32_t);
-	prf->ids[0] = ids[0];
-	prf->ids[1] = ids[1];
+	if (attr->ext_sample_id) {
+		prf->ids[0] = ids[0].sample_id;
+		prf->ids[1] = ids[1].sample_id;
+	} else {
+		prf->ids[0] = ids[0].id;
+		prf->ids[1] = ids[1].id;
+	}
 	return 0;
 }
 
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 31982002ee..1c11b77ac3 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1307,9 +1307,10 @@ struct mlx5_lag {
 struct mlx5_flex_parser_devx {
 	struct mlx5_list_entry entry;  /* List element at the beginning. */
 	uint32_t num_samples;
+	uint8_t anchor_id;
 	void *devx_obj;
 	struct mlx5_devx_graph_node_attr devx_conf;
-	uint32_t sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	struct mlx5_ext_sample_id sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
 };
 
 /* Pattern field descriptor - how to translate flex pattern into samples. */
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c b/drivers/net/mlx5/mlx5_flow_flex.c
index fb08910ddb..35f2a9923d 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -226,15 +226,18 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 	void *misc4_m = MLX5_ADDR_OF(fte_match_param, matcher,
 				     misc_parameters_4);
 	void *misc4_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_4);
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_flex_item *tp;
 	uint32_t i, pos = 0;
+	uint32_t sample_id;
 
 	RTE_SET_USED(dev);
 	MLX5_ASSERT(item->spec && item->mask);
 	spec = item->spec;
 	mask = item->mask;
 	tp = (struct mlx5_flex_item *)spec->handle;
-	MLX5_ASSERT(mlx5_flex_index(dev->data->dev_private, tp) >= 0);
+	MLX5_ASSERT(mlx5_flex_index(priv, tp) >= 0);
 	for (i = 0; i < tp->mapnum; i++) {
 		struct mlx5_flex_pattern_field *map = tp->map + i;
 		uint32_t id = map->reg_id;
@@ -257,9 +260,13 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 			MLX5_ASSERT(id < num_samples);
 			id += num_samples;
 		}
+		if (attr->ext_sample_id)
+			sample_id = tp->devx_fp->sample_ids[id].sample_id;
+		else
+			sample_id = tp->devx_fp->sample_ids[id].id;
 		mlx5_flex_set_match_sample(misc4_m, misc4_v,
 					   def, msk & def, val & msk & def,
-					   tp->devx_fp->sample_ids[id], id);
+					   sample_id, id);
 		pos += map->width;
 	}
 }
@@ -1298,7 +1305,8 @@ mlx5_flex_parser_create_cb(void *list_ctx, void *ctx)
 	/* Query the firmware assigned sample ids. */
 	ret = mlx5_devx_cmd_query_parse_samples(fp->devx_obj,
 						fp->sample_ids,
-						fp->num_samples);
+						fp->num_samples,
+						&fp->anchor_id);
 	if (ret)
 		goto error;
 	DRV_LOG(DEBUG, "DEVx flex parser %p created, samples num: %u",
-- 
2.27.0


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

* [RFC 4/9] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (2 preceding siblings ...)
  2022-12-21  8:42 ` [RFC 3/9] net/mlx5: adopt new flex item definition Rongwei Liu
@ 2022-12-21  8:42 ` Rongwei Liu
  2022-12-21  8:43 ` [RFC 5/9] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:42 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland, Gregory Etelson

New mlx5dr_context member replaces mlx5dr_cmd_query_caps.
Capabilities structure is a member of mlx5dr_context.

Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_definer.c | 41 ++++++++++++++-------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 6b98eb8c96..10b1e43d6e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -100,7 +100,7 @@ struct mlx5dr_definer_sel_ctrl {
 };
 
 struct mlx5dr_definer_conv_data {
-	struct mlx5dr_cmd_query_caps *caps;
+	struct mlx5dr_context *ctx;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t relaxed;
 	uint8_t tunnel;
@@ -815,6 +815,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 			     struct rte_flow_item *item,
 			     int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
@@ -836,7 +837,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 	}
 
 	if (m->teid) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -844,11 +845,11 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->item_idx = item_idx;
 		fc->tag_set = &mlx5dr_definer_gtp_teid_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, teid);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_1 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_1 * DW_SIZE;
 	}
 
 	if (m->v_pt_rsv_flags) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -857,12 +858,12 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_flag_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 
 	if (m->msg_type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -871,7 +872,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_msg_type_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, msg_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -882,12 +883,13 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 				 struct rte_flow_item *item,
 				 int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp_psc *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
 	/* Overwrite GTP extension flag to be 1 */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -896,12 +898,12 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	/* Overwrite next extension header type */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -911,14 +913,14 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_opt_gtp, next_ext_hdr_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_opt_gtp, next_ext_hdr_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_2 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_2 * DW_SIZE;
 	}
 
 	if (!m)
 		return 0;
 
 	if (m->hdr.type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -927,11 +929,11 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_pdu_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, pdu_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, pdu_type);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	if (m->hdr.qfi) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -940,7 +942,7 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_qfi_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, qfi);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, qfi);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -951,18 +953,19 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 			      struct rte_flow_item *item,
 			      int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_ethdev *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t bit_offset = 0;
 
 	if (m->port_id) {
-		if (!cd->caps->wire_regc_mask) {
+		if (!caps->wire_regc_mask) {
 			DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask");
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
 
-		while (!(cd->caps->wire_regc_mask & (1 << bit_offset)))
+		while (!(caps->wire_regc_mask & (1 << bit_offset)))
 			bit_offset++;
 
 		fc = &cd->fc[MLX5DR_DEFINER_FNAME_VPORT_REG_C_0];
@@ -971,7 +974,7 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		DR_CALC_SET_HDR(fc, registers, register_c_0);
 		fc->bit_off = bit_offset;
-		fc->bit_mask = cd->caps->wire_regc_mask >> bit_offset;
+		fc->bit_mask = caps->wire_regc_mask >> bit_offset;
 	} else {
 		DR_LOG(ERR, "Pord ID item mask must specify ID mask");
 		rte_errno = EINVAL;
@@ -1480,7 +1483,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 
 	cd.fc = fc;
 	cd.hl = hl;
-	cd.caps = ctx->caps;
+	cd.ctx = ctx;
 	cd.relaxed = mt->flags & MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH;
 
 	/* Collect all RTE fields to the field array and set header layout */
-- 
2.27.0


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

* [RFC 5/9] net/mlx5/hws: add IPv6 routing extension matching support
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (3 preceding siblings ...)
  2022-12-21  8:42 ` [RFC 4/9] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
@ 2022-12-21  8:43 ` Rongwei Liu
  2022-12-21  8:43 ` [RFC 6/9] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:43 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Add mlx5 HWS logic to match IPv6 routing extension header.

Once detecting IPv6 matching extension items in pattern template
create callback, PMD allocates a flex parser to sample the first
dword of srv6 header.

Only support next_hdr/segments_left/type for now.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 doc/guides/nics/features/mlx5.ini     |   1 +
 doc/guides/nics/mlx5.rst              |   1 +
 drivers/net/mlx5/hws/mlx5dr.h         |  21 ++++++
 drivers/net/mlx5/hws/mlx5dr_context.c |  81 +++++++++++++++++++-
 drivers/net/mlx5/hws/mlx5dr_context.h |   1 +
 drivers/net/mlx5/hws/mlx5dr_definer.c | 103 ++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h               |  10 +++
 drivers/net/mlx5/mlx5_flow.h          |   3 +
 drivers/net/mlx5/mlx5_flow_hw.c       |  39 ++++++++--
 9 files changed, 250 insertions(+), 10 deletions(-)

diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index 62fd330e2b..bd911a467b 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -87,6 +87,7 @@ vlan                 = Y
 vxlan                = Y
 vxlan_gpe            = Y
 represented_port     = Y
+ipv6_routing_ext     = Y
 
 [rte_flow actions]
 age                  = I
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 51f51259e3..98dcf9af16 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -106,6 +106,7 @@ Features
 - Sub-Function representors.
 - Sub-Function.
 - Matching on represented port.
+- Matching on IPv6 routing extension header.
 
 
 Limitations
diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index f8de27c615..ba1566de9f 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -592,4 +592,25 @@ int mlx5dr_send_queue_action(struct mlx5dr_context *ctx,
  */
 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f);
 
+/* Allocate an internal flex parser for srv6 option.
+ *
+ * @param[in] dr_ctx
+ *	The dr_context which the flex parser belongs to.
+ * @param[in] config
+ *	Devx configuration per port.
+ * @param[in] ctx
+ *	Device contex
+ * @return zero on success non zero otherwise.
+ */
+int mlx5dr_alloc_srh_flex_parser(struct mlx5dr_context *dr_ctx,
+				 struct mlx5_common_dev_config *config,
+				 void *ctx);
+
+/* Free srv6 flex parser.
+ *
+ * @param[in] dr_ctx
+ *	The dr_context which the flex parser belongs to.
+ * @return zero on success non zero otherwise.
+ */
+int mlx5dr_free_srh_flex_parser(struct mlx5dr_context *dr_ctx);
 #endif
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.c b/drivers/net/mlx5/hws/mlx5dr_context.c
index 76ada7bb7f..6329271ff6 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.c
+++ b/drivers/net/mlx5/hws/mlx5dr_context.c
@@ -178,6 +178,76 @@ static void mlx5dr_context_uninit_hws(struct mlx5dr_context *ctx)
 	mlx5dr_context_uninit_pd(ctx);
 }
 
+int mlx5dr_alloc_srh_flex_parser(struct mlx5dr_context *dr_ctx,
+				 struct mlx5_common_dev_config *config,
+				 void *ctx)
+{
+	struct mlx5_devx_graph_node_attr node = {
+		.modify_field_select = 0,
+	};
+	struct mlx5_ext_sample_id ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	int ret;
+
+	memset(ids, 0xff, sizeof(ids));
+	if (!config->hca_attr.parse_graph_flex_node) {
+		DR_LOG(ERR, "Dynamic flex parser is not supported");
+		return -ENOTSUP;
+	}
+	if (__atomic_add_fetch(&dr_ctx->srh_flex_parser->refcnt, 1, __ATOMIC_RELAXED) > 1)
+		return 0;
+
+	node.header_length_mode = MLX5_GRAPH_NODE_LEN_FIELD;
+	/* Srv6 first two DW are not counted in. */
+	node.header_length_base_value = 0x8;
+	/* The unit is uint64_t. */
+	node.header_length_field_shift = 0x3;
+	/* Header length is the 2nd byte. */
+	node.header_length_field_offset = 0x8;
+	node.header_length_field_mask = 0xF;
+	/* One byte next header protocol. */
+	node.next_header_field_size = 0x8;
+	node.in[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IP;
+	node.in[0].compare_condition_value = IPPROTO_ROUTING;
+	node.sample[0].flow_match_sample_en = 1;
+	/* First come first serve not matter inner or outer. */
+	node.sample[0].flow_match_sample_tunnel_mode = MLX5_GRAPH_SAMPLE_TUNNEL_FIRST;
+	node.out[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_TCP;
+	node.out[0].compare_condition_value = IPPROTO_TCP;
+	node.out[1].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_UDP;
+	node.out[1].compare_condition_value = IPPROTO_UDP;
+	node.out[2].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IPV6;
+	node.out[2].compare_condition_value = IPPROTO_IPV6;
+
+	dr_ctx->srh_flex_parser->fp = mlx5_devx_cmd_create_flex_parser(ctx, &node);
+	if (!dr_ctx->srh_flex_parser->fp) {
+		DR_LOG(ERR, "Failed to create flex parser node object.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	dr_ctx->srh_flex_parser->num = 1;
+	ret = mlx5_devx_cmd_query_parse_samples(dr_ctx->srh_flex_parser->fp, ids,
+						dr_ctx->srh_flex_parser->num,
+						&dr_ctx->srh_flex_parser->anchor_id);
+	if (ret) {
+		DR_LOG(ERR, "Failed to query sample IDs.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	dr_ctx->srh_flex_parser->offset[0] = 0x0;
+	dr_ctx->srh_flex_parser->ids[0].id = ids[0].id;
+	return 0;
+}
+
+int mlx5dr_free_srh_flex_parser(struct mlx5dr_context *dr_ctx)
+{
+	struct mlx5_internal_flex_parser_profile *fp = dr_ctx->srh_flex_parser;
+
+	if (__atomic_sub_fetch(&fp->refcnt, 1, __ATOMIC_RELAXED))
+		return 0;
+	if (fp->fp)
+		mlx5_devx_cmd_destroy(fp->fp);
+	fp->fp = NULL;
+	return 0;
+}
+
 struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 					   struct mlx5dr_context_attr *attr)
 {
@@ -197,16 +267,22 @@ struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 	if (!ctx->caps)
 		goto free_ctx;
 
+	ctx->srh_flex_parser = simple_calloc(1, sizeof(*ctx->srh_flex_parser));
+	if (!ctx->srh_flex_parser)
+		goto free_caps;
+
 	ret = mlx5dr_cmd_query_caps(ibv_ctx, ctx->caps);
 	if (ret)
-		goto free_caps;
+		goto free_flex;
 
 	ret = mlx5dr_context_init_hws(ctx, attr);
 	if (ret)
-		goto free_caps;
+		goto free_flex;
 
 	return ctx;
 
+free_flex:
+	simple_free(ctx->srh_flex_parser);
 free_caps:
 	simple_free(ctx->caps);
 free_ctx:
@@ -217,6 +293,7 @@ struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
 int mlx5dr_context_close(struct mlx5dr_context *ctx)
 {
 	mlx5dr_context_uninit_hws(ctx);
+	simple_free(ctx->srh_flex_parser);
 	simple_free(ctx->caps);
 	pthread_spin_destroy(&ctx->ctrl_lock);
 	simple_free(ctx);
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.h b/drivers/net/mlx5/hws/mlx5dr_context.h
index b0c7802daf..c1c627aced 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.h
+++ b/drivers/net/mlx5/hws/mlx5dr_context.h
@@ -35,6 +35,7 @@ struct mlx5dr_context {
 	struct mlx5dr_send_engine *send_queue;
 	size_t queues;
 	LIST_HEAD(table_head, mlx5dr_table) head;
+	struct mlx5_internal_flex_parser_profile *srh_flex_parser;
 };
 
 #endif /* MLX5DR_CONTEXT_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 10b1e43d6e..09acd5d719 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -125,6 +125,7 @@ struct mlx5dr_definer_conv_data {
 	X(SET_BE16,	ipv4_frag,		v->fragment_offset,	rte_ipv4_hdr) \
 	X(SET_BE16,	ipv6_payload_len,	v->hdr.payload_len,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_proto,		v->hdr.proto,		rte_flow_item_ipv6) \
+	X(SET,		ipv6_routing_hdr,	IPPROTO_ROUTING,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_hop_limits,	v->hdr.hop_limits,	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_127_96,	&v->hdr.src_addr[0],	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_95_64,	&v->hdr.src_addr[4],	rte_flow_item_ipv6) \
@@ -293,6 +294,18 @@ mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc,
 	DR_SET(tag, ok1_bits, fc->byte_off, fc->bit_off, fc->bit_mask);
 }
 
+static void
+mlx5dr_definer_ipv6_routing_ext_set(struct mlx5dr_definer_fc *fc,
+				    const void *item,
+				    uint8_t *tag)
+{
+	const struct rte_flow_item_ipv6_routing_ext *v = item;
+	uint32_t val = 0;
+
+	val = v->hdr.nexthdr << 24 | v->hdr.type << 8 | v->hdr.segments_left;
+	DR_SET_BE32(tag, RTE_BE32(val), fc->byte_off, 0, fc->bit_mask);
+}
+
 static void
 mlx5dr_definer_gre_key_set(struct mlx5dr_definer_fc *fc,
 			   const void *item_spec,
@@ -1468,6 +1481,91 @@ mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd,
 	return 0;
 }
 
+static int
+mlx5dr_definer_conv_item_ipv6_routing_ext(struct mlx5dr_definer_conv_data *cd,
+					  struct rte_flow_item *item,
+					  int item_idx)
+{
+	struct mlx5_internal_flex_parser_profile *fp = cd->ctx->srh_flex_parser;
+	enum mlx5dr_definer_fname i = MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
+	const struct rte_flow_item_ipv6_routing_ext *m = item->mask;
+	uint32_t byte_off = fp->ids[0].format_select_dw * 4;
+	struct mlx5dr_definer_fc *fc;
+	bool inner = cd->tunnel;
+
+	if (!m)
+		return 0;
+
+	if (!fp->num)
+		return -1;
+
+	if (!cd->relaxed) {
+		fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_version_set;
+		fc->tag_mask_set = &mlx5dr_definer_ones_set;
+		DR_CALC_SET(fc, eth_l2, l3_type, inner);
+
+		/* Overwrite - Unset ethertype if present */
+		memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
+		fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
+		if (!fc->tag_set) {
+			fc->item_idx = item_idx;
+			fc->tag_set = &mlx5dr_definer_ipv6_routing_hdr_set;
+			fc->tag_mask_set = &mlx5dr_definer_ones_set;
+			DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
+		}
+	}
+
+	if (m->hdr.nexthdr || m->hdr.type || m->hdr.segments_left) {
+		for (; i <= MLX5DR_DEFINER_FNAME_FLEX_PARSER_7; i++) {
+			switch (i) {
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_0:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_0];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_0);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_1:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_1];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_1);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_2:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_2];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_2);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_3:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_3];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_3);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_4:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_4];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_4);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_5:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_5];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_5);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_6:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_6];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_6);
+				break;
+			case MLX5DR_DEFINER_FNAME_FLEX_PARSER_7:
+			default:
+				fc = &cd->fc[MLX5DR_DEFINER_FNAME_FLEX_PARSER_7];
+				DR_CALC_SET_HDR(fc, flex_parser, flex_parser_7);
+				break;
+			}
+			if (fc->byte_off == byte_off)
+				break;
+		}
+		if (i > MLX5DR_DEFINER_FNAME_FLEX_PARSER_7)
+			return -ENOTSUP;
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_routing_ext_set;
+		fc->fname = i;
+	}
+	return 0;
+}
+
 static int
 mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 				struct mlx5dr_match_template *mt,
@@ -1584,6 +1682,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 			ret = mlx5dr_definer_conv_item_meter_color(&cd, items, i);
 			item_flags |= MLX5_FLOW_ITEM_METER_COLOR;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ret = mlx5dr_definer_conv_item_ipv6_routing_ext(&cd, items, i);
+			item_flags |= cd.tunnel ? MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT :
+						  MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT;
+			break;
 		default:
 			DR_LOG(ERR, "Unsupported item type %d", items->type);
 			rte_errno = ENOTSUP;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 1c11b77ac3..6dbd5f9622 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -543,6 +543,16 @@ struct mlx5_counter_stats_raw {
 	volatile struct flow_counter_stats *data;
 };
 
+/* Mlx5 internal flex parser profile structure. */
+struct mlx5_internal_flex_parser_profile {
+	uint32_t num;/* Actual number of samples. */
+	struct mlx5_ext_sample_id ids[MLX5_FLEX_ITEM_MAPPING_NUM];/* Sample IDs for this profile. */
+	uint32_t offset[MLX5_FLEX_ITEM_MAPPING_NUM];/* Each ID sample offset. */
+	uint8_t anchor_id;
+	uint32_t refcnt;
+	void *fp; /* DevX flex parser object. */
+};
+
 TAILQ_HEAD(mlx5_counter_pools, mlx5_flow_counter_pool);
 
 /* Counter global management structure. */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 1f57ecd6e1..81e2bc47a0 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -218,6 +218,9 @@ enum mlx5_feature_name {
 
 /* Meter color item */
 #define MLX5_FLOW_ITEM_METER_COLOR (UINT64_C(1) << 44)
+/* IPv6 routing extension item */
+#define MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT (UINT64_C(1) << 45)
+#define MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT (UINT64_C(1) << 46)
 
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 20c71ff7f0..ff52eb28f0 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -213,23 +213,25 @@ flow_hw_hashfields_set(struct mlx5_flow_rss_desc *rss_desc,
 }
 
 /**
- * Generate the pattern item flags.
+ * Generate the matching pattern item flags.
  * Will be used for shared RSS action.
  *
  * @param[in] items
  *   Pointer to the list of items.
+ * @param[out] flags
+ *   Flags superset including non-RSS items.
  *
  * @return
- *   Item flags.
+ *   RSS Item flags.
  */
 static uint64_t
-flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
+flow_hw_matching_item_flags_get(const struct rte_flow_item items[], uint64_t *flags)
 {
-	uint64_t item_flags = 0;
 	uint64_t last_item = 0;
 
+	*flags = 0;
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
-		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
+		int tunnel = !!(*flags & MLX5_FLOW_LAYER_TUNNEL);
 		int item_type = items->type;
 
 		switch (item_type) {
@@ -249,6 +251,10 @@ flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
 			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
 					     MLX5_FLOW_LAYER_OUTER_L4_UDP;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			last_item = tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
+					     MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
+			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			last_item = MLX5_FLOW_LAYER_GRE;
 			break;
@@ -273,9 +279,10 @@ flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
 		default:
 			break;
 		}
-		item_flags |= last_item;
+		*flags |= last_item;
 	}
-	return item_flags;
+	return *flags & ~(MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT |
+			  MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT);
 }
 
 /**
@@ -4732,6 +4739,7 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_ICMP:
 		case RTE_FLOW_ITEM_TYPE_ICMP6:
 		case RTE_FLOW_ITEM_TYPE_CONNTRACK:
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
 			break;
 		case RTE_FLOW_ITEM_TYPE_INTEGRITY:
 			/*
@@ -4809,6 +4817,8 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 		.mask = &tag_m,
 		.last = NULL
 	};
+	struct mlx5dr_context *dr_ctx = priv->dr_ctx;
+	uint64_t flags;
 
 	if (flow_hw_pattern_validate(dev, attr, items, error))
 		return NULL;
@@ -4860,7 +4870,7 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 				   "cannot create match template");
 		return NULL;
 	}
-	it->item_flags = flow_hw_rss_item_flags_get(tmpl_items);
+	it->item_flags = flow_hw_matching_item_flags_get(tmpl_items, &flags);
 	if (copied_items) {
 		if (attr->ingress)
 			it->implicit_port = true;
@@ -4868,6 +4878,15 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 			it->implicit_tag = true;
 		mlx5_free(copied_items);
 	}
+	if (flags & (MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT |
+		     MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT)) {
+		if (mlx5dr_alloc_srh_flex_parser(dr_ctx, &priv->sh->cdev->config,
+						 priv->sh->cdev->ctx)) {
+			claim_zero(mlx5dr_match_template_destroy(it->mt));
+			mlx5_free(it);
+			return NULL;
+		}
+	}
 	__atomic_fetch_add(&it->refcnt, 1, __ATOMIC_RELAXED);
 	LIST_INSERT_HEAD(&priv->flow_hw_itt, it, next);
 	return it;
@@ -4891,6 +4910,9 @@ flow_hw_pattern_template_destroy(struct rte_eth_dev *dev __rte_unused,
 			      struct rte_flow_pattern_template *template,
 			      struct rte_flow_error *error __rte_unused)
 {
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5dr_context *dr_ctx = priv->dr_ctx;
+
 	if (__atomic_load_n(&template->refcnt, __ATOMIC_RELAXED) > 1) {
 		DRV_LOG(WARNING, "Item template %p is still in use.",
 			(void *)template);
@@ -4899,6 +4921,7 @@ flow_hw_pattern_template_destroy(struct rte_eth_dev *dev __rte_unused,
 				   NULL,
 				   "item template in using");
 	}
+	mlx5dr_free_srh_flex_parser(dr_ctx);
 	LIST_REMOVE(template, next);
 	claim_zero(mlx5dr_match_template_destroy(template->mt));
 	mlx5_free(template);
-- 
2.27.0


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

* [RFC 6/9] app/testpmd: add IPv6 routing extension header in raw encap
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (4 preceding siblings ...)
  2022-12-21  8:43 ` [RFC 5/9] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
@ 2022-12-21  8:43 ` Rongwei Liu
  2022-12-21  8:43 ` [RFC 7/9] ethdev: add modify IPv6 protocol field Rongwei Liu
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:43 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang; +Cc: dev, rasland

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 70685aafb1..24fdb260e9 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10920,6 +10920,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.nexthdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11022,6 +11029,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11176,6 +11186,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11196,6 +11207,12 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			size = sizeof(struct rte_ipv6_routing_ext) + (ext->hdr.segments_left << 4);
+			ext->hdr.hdrlen = ext->hdr.segments_left << 1;
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* [RFC 7/9] ethdev: add modify IPv6 protocol field
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (5 preceding siblings ...)
  2022-12-21  8:43 ` [RFC 6/9] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
@ 2022-12-21  8:43 ` Rongwei Liu
  2023-01-16 16:20   ` Ori Kam
  2022-12-21  8:43 ` [RFC 8/9] app/testpmd: add modify IPv6 protocol command line Rongwei Liu
  2022-12-21  8:43 ` [RFC 9/9] net/mlx5/hws: add modify IPv6 protocol implementation Rongwei Liu
  8 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:43 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Ferruh Yigit, Andrew Rybchenko
  Cc: dev, rasland

Add IPv6 protocol modify field definition.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 lib/ethdev/rte_flow.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index f8f1d6f9dd..b1240b0cb0 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3567,6 +3567,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [RFC 8/9] app/testpmd: add modify IPv6 protocol command line
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (6 preceding siblings ...)
  2022-12-21  8:43 ` [RFC 7/9] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2022-12-21  8:43 ` Rongwei Liu
  2022-12-21  8:43 ` [RFC 9/9] net/mlx5/hws: add modify IPv6 protocol implementation Rongwei Liu
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:43 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang; +Cc: dev, rasland

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 24fdb260e9..374c89d434 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
-- 
2.27.0


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

* [RFC 9/9] net/mlx5/hws: add modify IPv6 protocol implementation
  2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
                   ` (7 preceding siblings ...)
  2022-12-21  8:43 ` [RFC 8/9] app/testpmd: add modify IPv6 protocol command line Rongwei Liu
@ 2022-12-21  8:43 ` Rongwei Liu
  8 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2022-12-21  8:43 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Add HWS modify IPv6 protocol implementation.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h  |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 1545b929b6..c57d49e079 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -753,6 +753,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x82,
 };
 
 /* Total number of metadata reg_c's. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 7ca909999b..e972a2dc5a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1357,6 +1357,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
 	case RTE_FLOW_FIELD_IPV6_SRC:
 	case RTE_FLOW_FIELD_IPV6_DST:
@@ -1883,6 +1884,15 @@ mlx5_flow_field_id_to_modify_info
 				info[idx].offset = data->offset;
 		}
 		break;
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IPV6_NEXT_HDR};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_POINTER:
 	case RTE_FLOW_FIELD_VALUE:
 	default:
-- 
2.27.0


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

* RE: [RFC 1/9] ethdev: add IPv6 routing extension header definition
  2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-16 16:15   ` Ori Kam
  2023-01-17  2:50     ` Rongwei Liu
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
  1 sibling, 1 reply; 67+ messages in thread
From: Ori Kam @ 2023-01-16 16:15 UTC (permalink / raw)
  To: Rongwei Liu, Matan Azrad, Slava Ovsiienko,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz
  Cc: dev, Raslan Darawsheh

Hi Rongwei,


> -----Original Message-----
> From: Rongwei Liu <rongweil@nvidia.com>
> Sent: Wednesday, 21 December 2022 10:43
> 
> Add IPv6 routing extension header definition and no
> TLV support for now.
> At rte_flow layer, there are new items defined for matching
> type/nexthdr/segment_left field.
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst     |  9 ++++++
>  doc/guides/rel_notes/release_22_03.rst |  5 ++++
>  lib/ethdev/rte_flow.c                  | 15 ++++++++++
>  lib/ethdev/rte_flow.h                  | 39 ++++++++++++++++++++++++++
>  lib/net/rte_ip.h                       | 21 ++++++++++++++
>  5 files changed, 89 insertions(+)
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index 3e6242803d..1ebc159893 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
> 
>  - ``color``: Metering color marker.
> 
> +Item: ``IPV6_ROUTING_EXT``
> +^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches ipv6 routing extension header.
> +
> +- ``nexthdr``: Next layer header type.
> +- ``type``: IPv6 routing extension header type.
> +- ``segments_left``: How many IPv6 destination addresses carries on
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_22_03.rst
> b/doc/guides/rel_notes/release_22_03.rst
> index 0923707cb8..cc050ff3e7 100644
> --- a/doc/guides/rel_notes/release_22_03.rst
> +++ b/doc/guides/rel_notes/release_22_03.rst
> @@ -207,6 +207,11 @@ API Changes
>  * ethdev: Old public macros and enumeration constants without
> ``RTE_ETH_`` prefix,
>    which are kept for backward compatibility, are marked as deprecated.
> 
> +* ethdev: added a new structure:
> +
> +    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
> +      ``rte_ipv6_routing_ext``
> +
>  * cryptodev: The asymmetric session handling was modified to use a single
>    mempool object. An API ``rte_cryptodev_asym_session_pool_create`` was
> added
>    to create a mempool with element size big enough to hold the generic
> asymmetric
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 7d0c24366c..e08b690300 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -76,6 +76,19 @@ rte_flow_item_flex_conv(void *buf, const void *data)
>  	return src->length;
>  }
> 
> +static size_t
> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
> +{
> +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> +
> +	if (buf)
> +		rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
> +			   src->hdr.segments,
> +			   src->hdr.segments_left << 4);
> +	return src->hdr.segments_left << 4;
> +}
> +
>  /** Generate flow_item[] entry. */
>  #define MK_FLOW_ITEM(t, s) \
>  	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
> @@ -157,6 +170,8 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>  	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  	MK_FLOW_ITEM(METER_COLOR, sizeof(struct
> rte_flow_item_meter_color)),
> +	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct
> rte_flow_item_ipv6_routing_ext),
> +			rte_flow_item_ipv6_routing_ext_conv),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index b60987db4b..f8f1d6f9dd 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -624,6 +624,33 @@ enum rte_flow_item_type {
>  	 * See struct rte_flow_item_meter_color.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_METER_COLOR,
> +	/**
> +	 * Matches the presence of IPv6 routing extension header.
> +	 *
> +	 * See struct rte_flow_item_ipv6_routing_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
> +
> +	/**
> +	 * Matches IPv6 routing extension header next header.
> +	 *
> +	 * See struct rte_flow_item_ipv6_routing_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_NEXT_HDR,

Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?

> +
> +	/**
> +	 * Matches IPv6 routing extension header type.
> +	 *
> +	 * See struct rte_flow_item_ipv6_routing_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_TYPE,
> +

Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?

> +	/**
> +	 * Matches IPv6 routing extension header segment left.
> +	 *
> +	 * See struct rte_flow_item_ipv6_routing_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_SEG_LEFT,

Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?

>  };
> 
>  /**
> @@ -873,6 +900,18 @@ struct rte_flow_item_ipv6 {
>  	uint32_t reserved:23;
>  };
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> + *
> + * Matches an IPv6 routing extension header.
> + */
> +struct rte_flow_item_ipv6_routing_ext {
> +	struct rte_ipv6_routing_ext hdr;
> +};
> +
>  /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
>  #ifndef __cplusplus
>  static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
> index 9c8e8206f0..2b9a65dfcb 100644
> --- a/lib/net/rte_ip.h
> +++ b/lib/net/rte_ip.h
> @@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
>  	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
>  } __rte_packed;
> 
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t nexthdr;			/**< Protocol, next header.
> */
> +	uint8_t hdrlen;				/**< Header length. */
> +	uint8_t type;				/**< Extension header type.
> */
> +	uint8_t segments_left;			/**< Valid segments number.
> */
> +	__extension__
> +	union {
> +		uint32_t flags;
> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of
> SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			uint16_t tag;		/**< Packet tag. */
> +		};
> +	};
> +	__extension__
> +	uint32_t segments[0];			/**< Each hop IPv6 address.
> */
> +} __rte_packed;
> +
>  /* IPv6 vtc_flow: IPv / TC / flow_label */
>  #define RTE_IPV6_HDR_FL_SHIFT 0
>  #define RTE_IPV6_HDR_TC_SHIFT 20
> --
> 2.27.0

Best,
Ori

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

* RE: [RFC 7/9] ethdev: add modify IPv6 protocol field
  2022-12-21  8:43 ` [RFC 7/9] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-01-16 16:20   ` Ori Kam
  0 siblings, 0 replies; 67+ messages in thread
From: Ori Kam @ 2023-01-16 16:20 UTC (permalink / raw)
  To: Rongwei Liu, Matan Azrad, Slava Ovsiienko,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko
  Cc: dev, Raslan Darawsheh

Hi Rongwei,

> -----Original Message-----
> From: Rongwei Liu <rongweil@nvidia.com>
> Sent: Wednesday, 21 December 2022 10:43
> 
> Add IPv6 protocol modify field definition.
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> ---
>  lib/ethdev/rte_flow.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index f8f1d6f9dd..b1240b0cb0 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -3567,6 +3567,7 @@ enum rte_flow_field_id {
>  	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
>  	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
>  	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
> +	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
>  };
> 
>  /**
> --
> 2.27.0

Acked-by: Ori Kam <orika@nvidia.com>
Best,
Ori

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

* RE: [RFC 1/9] ethdev: add IPv6 routing extension header definition
  2023-01-16 16:15   ` Ori Kam
@ 2023-01-17  2:50     ` Rongwei Liu
  0 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-17  2:50 UTC (permalink / raw)
  To: Ori Kam, Matan Azrad, Slava Ovsiienko,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz
  Cc: dev, Raslan Darawsheh

HI Ori:
	Those three matching items are redundant. Has been removed already.
	Do I need to send RFC v2?

BR
Rongwei

> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Tuesday, January 17, 2023 00:15
> To: Rongwei Liu <rongweil@nvidia.com>; Matan Azrad <matan@nvidia.com>;
> Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Thomas Monjalon
> (EXTERNAL) <thomas@monjalon.net>; Ferruh Yigit <ferruh.yigit@amd.com>;
> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Olivier Matz
> <olivier.matz@6wind.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: RE: [RFC 1/9] ethdev: add IPv6 routing extension header definition
> 
> Hi Rongwei,
> 
> 
> > -----Original Message-----
> > From: Rongwei Liu <rongweil@nvidia.com>
> > Sent: Wednesday, 21 December 2022 10:43
> >
> > Add IPv6 routing extension header definition and no TLV support for
> > now.
> > At rte_flow layer, there are new items defined for matching
> > type/nexthdr/segment_left field.
> >
> > Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> > ---
> >  doc/guides/prog_guide/rte_flow.rst     |  9 ++++++
> >  doc/guides/rel_notes/release_22_03.rst |  5 ++++
> >  lib/ethdev/rte_flow.c                  | 15 ++++++++++
> >  lib/ethdev/rte_flow.h                  | 39 ++++++++++++++++++++++++++
> >  lib/net/rte_ip.h                       | 21 ++++++++++++++
> >  5 files changed, 89 insertions(+)
> >
> > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index 3e6242803d..1ebc159893 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
> >
> >  - ``color``: Metering color marker.
> >
> > +Item: ``IPV6_ROUTING_EXT``
> > +^^^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches ipv6 routing extension header.
> > +
> > +- ``nexthdr``: Next layer header type.
> > +- ``type``: IPv6 routing extension header type.
> > +- ``segments_left``: How many IPv6 destination addresses carries on
> > +
> >  Actions
> >  ~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_22_03.rst
> > b/doc/guides/rel_notes/release_22_03.rst
> > index 0923707cb8..cc050ff3e7 100644
> > --- a/doc/guides/rel_notes/release_22_03.rst
> > +++ b/doc/guides/rel_notes/release_22_03.rst
> > @@ -207,6 +207,11 @@ API Changes
> >  * ethdev: Old public macros and enumeration constants without
> > ``RTE_ETH_`` prefix,
> >    which are kept for backward compatibility, are marked as deprecated.
> >
> > +* ethdev: added a new structure:
> > +
> > +    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
> > +      ``rte_ipv6_routing_ext``
> > +
> >  * cryptodev: The asymmetric session handling was modified to use a single
> >    mempool object. An API ``rte_cryptodev_asym_session_pool_create``
> > was added
> >    to create a mempool with element size big enough to hold the
> > generic asymmetric diff --git a/lib/ethdev/rte_flow.c
> > b/lib/ethdev/rte_flow.c index 7d0c24366c..e08b690300 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -76,6 +76,19 @@ rte_flow_item_flex_conv(void *buf, const void *data)
> >  	return src->length;
> >  }
> >
> > +static size_t
> > +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data) {
> > +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> > +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> > +
> > +	if (buf)
> > +		rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
> > +			   src->hdr.segments,
> > +			   src->hdr.segments_left << 4);
> > +	return src->hdr.segments_left << 4;
> > +}
> > +
> >  /** Generate flow_item[] entry. */
> >  #define MK_FLOW_ITEM(t, s) \
> >  	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
> > @@ -157,6 +170,8 @@ static const struct rte_flow_desc_data
> > rte_flow_desc_item[] = {
> >  	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> >  	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >  	MK_FLOW_ITEM(METER_COLOR, sizeof(struct
> rte_flow_item_meter_color)),
> > +	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct
> > rte_flow_item_ipv6_routing_ext),
> > +			rte_flow_item_ipv6_routing_ext_conv),
> >  };
> >
> >  /** Generate flow_action[] entry. */
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > b60987db4b..f8f1d6f9dd 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -624,6 +624,33 @@ enum rte_flow_item_type {
> >  	 * See struct rte_flow_item_meter_color.
> >  	 */
> >  	RTE_FLOW_ITEM_TYPE_METER_COLOR,
> > +	/**
> > +	 * Matches the presence of IPv6 routing extension header.
> > +	 *
> > +	 * See struct rte_flow_item_ipv6_routing_ext.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
> > +
> > +	/**
> > +	 * Matches IPv6 routing extension header next header.
> > +	 *
> > +	 * See struct rte_flow_item_ipv6_routing_ext.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_NEXT_HDR,
> 
> Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?
Will remove in the patch.
> 
> > +
> > +	/**
> > +	 * Matches IPv6 routing extension header type.
> > +	 *
> > +	 * See struct rte_flow_item_ipv6_routing_ext.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_TYPE,
> > +
> 
> Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?
Will remove in the patch.
> 
> > +	/**
> > +	 * Matches IPv6 routing extension header segment left.
> > +	 *
> > +	 * See struct rte_flow_item_ipv6_routing_ext.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT_SEG_LEFT,
> 
> Why do we need this item? Isn't it part of the rte_ipv6_routing_ext?
Will remove in the patch.
> 
> >  };
> >
> >  /**
> > @@ -873,6 +900,18 @@ struct rte_flow_item_ipv6 {
> >  	uint32_t reserved:23;
> >  };
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + *
> > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > + *
> > + * Matches an IPv6 routing extension header.
> > + */
> > +struct rte_flow_item_ipv6_routing_ext {
> > +	struct rte_ipv6_routing_ext hdr;
> > +};
> > +
> >  /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */  #ifndef __cplusplus
> > static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> > diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h index
> > 9c8e8206f0..2b9a65dfcb 100644
> > --- a/lib/net/rte_ip.h
> > +++ b/lib/net/rte_ip.h
> > @@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
> >  	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
> >  } __rte_packed;
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +	uint8_t nexthdr;			/**< Protocol, next header.
> > */
> > +	uint8_t hdrlen;				/**< Header length. */
> > +	uint8_t type;				/**< Extension header type.
> > */
> > +	uint8_t segments_left;			/**< Valid segments
> number.
> > */
> > +	__extension__
> > +	union {
> > +		uint32_t flags;
> > +		struct {
> > +			uint8_t last_entry;	/**< The last_entry field of
> > SRH */
> > +			uint8_t flag;		/**< Packet flag. */
> > +			uint16_t tag;		/**< Packet tag. */
> > +		};
> > +	};
> > +	__extension__
> > +	uint32_t segments[0];			/**< Each hop IPv6 address.
> > */
> > +} __rte_packed;
> > +
> >  /* IPv6 vtc_flow: IPv / TC / flow_label */  #define
> > RTE_IPV6_HDR_FL_SHIFT 0  #define RTE_IPV6_HDR_TC_SHIFT 20
> > --
> > 2.27.0
> 
> Best,
> Ori

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

* [PATCH v2 0/8] add IPv6 routing extension support
  2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-16 16:15   ` Ori Kam
@ 2023-01-19  3:11   ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
                       ` (7 more replies)
  1 sibling, 8 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Support IPv6 routing extension header matching with new rte_flow item.
Add encapsulation support for IPv6 routing extension header.

v2: remove redundant rte_flow items. include the commit from Gregory
    to pass the compilation.

Gregory Etelson (1):
  net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data

Rongwei Liu (7):
  ethdev: add IPv6 routing extension header definition
  net/mlx5: adopt IPv6 routing extension prm definition
  net/mlx5/hws: add IPv6 routing extension matching support
  app/testpmd: add IPv6 routing extension header in raw encap
  ethdev: add modify IPv6 protocol field
  net/mlx5/hws: add modify IPv6 protocol implementation
  doc/mlx5: add IPv6 routing extension matching docs

 app/test-pmd/cmdline_flow.c            |  72 ++++++++++++-
 doc/guides/nics/features/default.ini   |   1 +
 doc/guides/nics/features/mlx5.ini      |   1 +
 doc/guides/nics/mlx5.rst               |   2 +
 doc/guides/prog_guide/rte_flow.rst     |   9 ++
 doc/guides/rel_notes/release_23_03.rst |  10 ++
 drivers/common/mlx5/mlx5_devx_cmds.c   |  17 +++-
 drivers/common/mlx5/mlx5_devx_cmds.h   |   7 +-
 drivers/common/mlx5/mlx5_prm.h         |  29 +++++-
 drivers/net/mlx5/hws/mlx5dr_definer.c  | 133 +++++++++++++++++++++----
 drivers/net/mlx5/hws/mlx5dr_definer.h  |  15 +++
 drivers/net/mlx5/mlx5.c                | 103 ++++++++++++++++++-
 drivers/net/mlx5/mlx5.h                |  19 +++-
 drivers/net/mlx5/mlx5_flow.h           |  28 ++++++
 drivers/net/mlx5/mlx5_flow_dv.c        |  10 ++
 drivers/net/mlx5/mlx5_flow_flex.c      |  14 ++-
 drivers/net/mlx5/mlx5_flow_hw.c        |  29 +++++-
 lib/ethdev/rte_flow.c                  |  16 +++
 lib/ethdev/rte_flow.h                  |  20 ++++
 lib/net/rte_ip.h                       |  21 ++++
 20 files changed, 515 insertions(+), 41 deletions(-)

-- 
2.27.0


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

* [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-20  9:20       ` Andrew Rybchenko
  2023-01-19  3:11     ` [PATCH v2 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
                       ` (6 subsequent siblings)
  7 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz
  Cc: dev, rasland

Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst | 10 ++++++
 lib/ethdev/rte_flow.c                  | 16 +++++++++
 lib/ethdev/rte_flow.h                  | 19 +++++++++++
 lib/net/rte_ip.h                       | 21 ++++++++++++
 6 files changed, 121 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..ae99036be0 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches ipv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..2a794d598e 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header
+
 
 Removed Items
 -------------
@@ -84,6 +89,11 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: added a new structure:
+
+    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
+      ``rte_ipv6_routing_ext``
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..4074b475c8 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -76,6 +76,20 @@ rte_flow_item_flex_conv(void *buf, const void *data)
 	return src->length;
 }
 
+static size_t
+rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
+{
+	struct rte_flow_item_ipv6_routing_ext *dst = buf;
+	const struct rte_flow_item_ipv6_routing_ext *src = data;
+	size_t len;
+
+	len = src->hdr.hdr_len ? src->hdr.hdr_len << 3 : src->hdr.segments_left << 4;
+	if (buf)
+		rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
+			   src->hdr.segments, len);
+	return len;
+}
+
 /** Generate flow_item[] entry. */
 #define MK_FLOW_ITEM(t, s) \
 	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
@@ -157,6 +171,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
+			rte_flow_item_ipv6_routing_ext_conv),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..0120d3e7d2 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * See struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..158a2f83ce 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		uint32_t flags;
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			uint16_t tag;		/**< Packet tag. */
+		};
+	};
+	__extension__
+	uint32_t segments[0];			/**< Each hop IPv6 address. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [PATCH v2 2/8] net/mlx5: adopt IPv6 routing extension prm definition
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
                       ` (5 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Per newest PRM definition, sample_id stands for 3 parts
of information instead of single uint32_t id: sample_id +
modify_filed_id + format_select_dw.

Also new FW capability bits have been introduces to identify
the new capability.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 14 +++++++++++---
 drivers/common/mlx5/mlx5_devx_cmds.h |  7 ++++++-
 drivers/common/mlx5/mlx5_prm.h       | 28 ++++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5.c              | 15 +++++++++++----
 drivers/net/mlx5/mlx5.h              |  3 ++-
 drivers/net/mlx5/mlx5_flow_flex.c    | 14 +++++++++++---
 6 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index e3a4927d0f..1f65ea7dcb 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -607,7 +607,8 @@ mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
 
 int
 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				  uint32_t ids[], uint32_t num)
+				  struct mlx5_ext_sample_id ids[],
+				  uint32_t num, uint8_t *anchor)
 {
 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
 	uint32_t out[MLX5_ST_SZ_DW(create_flex_parser_out)] = {0};
@@ -636,6 +637,7 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			(void *)flex_obj);
 		return -rte_errno;
 	}
+	*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
 	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
 		void *s_off = (void *)((char *)sample + i *
 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
@@ -645,8 +647,8 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			      flow_match_sample_en);
 		if (!en)
 			continue;
-		ids[idx++] = MLX5_GET(parse_graph_flow_match_sample, s_off,
-				  flow_match_sample_field_id);
+		ids[idx++].id = MLX5_GET(parse_graph_flow_match_sample, s_off,
+					 flow_match_sample_field_id);
 	}
 	if (num != idx) {
 		rte_errno = EINVAL;
@@ -794,6 +796,12 @@ mlx5_devx_cmd_query_hca_parse_graph_node_cap
 					 max_num_arc_out);
 	attr->max_num_sample = MLX5_GET(parse_graph_node_cap, hcattr,
 					max_num_sample);
+	attr->anchor_en = MLX5_GET(parse_graph_node_cap, hcattr, anchor_en);
+	attr->ext_sample_id = MLX5_GET(parse_graph_node_cap, hcattr, ext_sample_id);
+	attr->sample_tunnel_inner2 = MLX5_GET(parse_graph_node_cap, hcattr,
+					      sample_tunnel_inner2);
+	attr->zero_size_supported = MLX5_GET(parse_graph_node_cap, hcattr,
+					     zero_size_supported);
 	attr->sample_id_in_out = MLX5_GET(parse_graph_node_cap, hcattr,
 					  sample_id_in_out);
 	attr->max_base_header_length = MLX5_GET(parse_graph_node_cap, hcattr,
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index c94b9eac06..5b33010155 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -114,6 +114,10 @@ struct mlx5_hca_flex_attr {
 	uint8_t  max_num_arc_out;
 	uint8_t  max_num_sample;
 	uint8_t  max_num_prog_sample:5;	/* From HCA CAP 2 */
+	uint8_t  anchor_en:1;
+	uint8_t  ext_sample_id:1;
+	uint8_t  sample_tunnel_inner2:1;
+	uint8_t  zero_size_supported:1;
 	uint8_t  sample_id_in_out:1;
 	uint16_t max_base_header_length;
 	uint8_t  max_sample_base_offset;
@@ -706,7 +710,8 @@ int mlx5_devx_cmd_modify_tir(struct mlx5_devx_obj *tir,
 			     struct mlx5_devx_modify_tir_attr *tir_attr);
 __rte_internal
 int mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				      uint32_t ids[], uint32_t num);
+				      struct mlx5_ext_sample_id ids[],
+				      uint32_t num, uint8_t *anchor);
 
 __rte_internal
 struct mlx5_devx_obj *
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 3790dc84b8..ce6cd98fd7 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1893,7 +1893,11 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 max_num_arc_in[0x08];
 	u8 max_num_arc_out[0x08];
 	u8 max_num_sample[0x08];
-	u8 reserved_at_78[0x07];
+	u8 reserved_at_78[0x03];
+	u8 anchor_en[0x1];
+	u8 ext_sample_id[0x1];
+	u8 sample_tunnel_inner2[0x1];
+	u8 zero_size_supported[0x1];
 	u8 sample_id_in_out[0x1];
 	u8 max_base_header_length[0x10];
 	u8 reserved_at_90[0x08];
@@ -1903,6 +1907,24 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 header_length_mask_width[0x08];
 };
 
+/* ext_sample_id structure, see PRM Table: Flow Match Sample ID Format. */
+struct mlx5_ext_sample_id {
+	union {
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			uint32_t format_select_dw:8;
+			uint32_t modify_field_id:12;
+			uint32_t sample_id:12;
+#else
+			uint32_t sample_id:12;
+			uint32_t modify_field_id:12;
+			uint32_t format_select_dw:8;
+#endif
+		};
+		uint32_t id;
+	};
+};
+
 struct mlx5_ifc_flow_table_prop_layout_bits {
 	u8 ft_support[0x1];
 	u8 flow_tag[0x1];
@@ -4522,7 +4544,9 @@ struct mlx5_ifc_parse_graph_flex_bits {
 	u8 header_length_mode[0x4];
 	u8 header_length_field_offset[0x10];
 	u8 next_header_field_offset[0x10];
-	u8 reserved_at_160[0x1b];
+	u8 reserved_at_160[0x12];
+	u8 head_anchor_id[0x6];
+	u8 reserved_at_178[0x3];
 	u8 next_header_field_size[0x5];
 	u8 header_length_field_mask[0x20];
 	u8 reserved_at_224[0x20];
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b8643cebdd..0b97c4e78d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -964,11 +964,13 @@ int
 mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_ecpri_parser_profile *prf =	&priv->sh->ecpri_parser;
 	struct mlx5_devx_graph_node_attr node = {
 		.modify_field_select = 0,
 	};
-	uint32_t ids[8];
+	struct mlx5_ext_sample_id ids[8];
+	uint8_t anchor_id;
 	int ret;
 
 	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
@@ -1004,15 +1006,20 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->num = 2;
-	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num);
+	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, &anchor_id);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to query sample IDs.");
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->offset[0] = 0x0;
 	prf->offset[1] = sizeof(uint32_t);
-	prf->ids[0] = ids[0];
-	prf->ids[1] = ids[1];
+	if (attr->ext_sample_id) {
+		prf->ids[0] = ids[0].sample_id;
+		prf->ids[1] = ids[1].sample_id;
+	} else {
+		prf->ids[0] = ids[0].id;
+		prf->ids[1] = ids[1].id;
+	}
 	return 0;
 }
 
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 16b33e1548..83fb316ad8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1307,9 +1307,10 @@ struct mlx5_lag {
 struct mlx5_flex_parser_devx {
 	struct mlx5_list_entry entry;  /* List element at the beginning. */
 	uint32_t num_samples;
+	uint8_t anchor_id;
 	void *devx_obj;
 	struct mlx5_devx_graph_node_attr devx_conf;
-	uint32_t sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	struct mlx5_ext_sample_id sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
 };
 
 /* Pattern field descriptor - how to translate flex pattern into samples. */
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c b/drivers/net/mlx5/mlx5_flow_flex.c
index fb08910ddb..35f2a9923d 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -226,15 +226,18 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 	void *misc4_m = MLX5_ADDR_OF(fte_match_param, matcher,
 				     misc_parameters_4);
 	void *misc4_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_4);
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_flex_item *tp;
 	uint32_t i, pos = 0;
+	uint32_t sample_id;
 
 	RTE_SET_USED(dev);
 	MLX5_ASSERT(item->spec && item->mask);
 	spec = item->spec;
 	mask = item->mask;
 	tp = (struct mlx5_flex_item *)spec->handle;
-	MLX5_ASSERT(mlx5_flex_index(dev->data->dev_private, tp) >= 0);
+	MLX5_ASSERT(mlx5_flex_index(priv, tp) >= 0);
 	for (i = 0; i < tp->mapnum; i++) {
 		struct mlx5_flex_pattern_field *map = tp->map + i;
 		uint32_t id = map->reg_id;
@@ -257,9 +260,13 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 			MLX5_ASSERT(id < num_samples);
 			id += num_samples;
 		}
+		if (attr->ext_sample_id)
+			sample_id = tp->devx_fp->sample_ids[id].sample_id;
+		else
+			sample_id = tp->devx_fp->sample_ids[id].id;
 		mlx5_flex_set_match_sample(misc4_m, misc4_v,
 					   def, msk & def, val & msk & def,
-					   tp->devx_fp->sample_ids[id], id);
+					   sample_id, id);
 		pos += map->width;
 	}
 }
@@ -1298,7 +1305,8 @@ mlx5_flex_parser_create_cb(void *list_ctx, void *ctx)
 	/* Query the firmware assigned sample ids. */
 	ret = mlx5_devx_cmd_query_parse_samples(fp->devx_obj,
 						fp->sample_ids,
-						fp->num_samples);
+						fp->num_samples,
+						&fp->anchor_id);
 	if (ret)
 		goto error;
 	DRV_LOG(DEBUG, "DEVx flex parser %p created, samples num: %u",
-- 
2.27.0


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

* [PATCH v2 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas
  Cc: dev, rasland, Gregory Etelson, Alex Vesker

From: Gregory Etelson <getelson@nvidia.com>

New mlx5dr_context member replaces mlx5dr_cmd_query_caps.
Capabilities structure is a member of mlx5dr_context.

Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Reviewed-by: Alex Vesker <valex@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_definer.c | 42 ++++++++++++++-------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 6b98eb8c96..0f1cab7e07 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -100,7 +100,7 @@ struct mlx5dr_definer_sel_ctrl {
 };
 
 struct mlx5dr_definer_conv_data {
-	struct mlx5dr_cmd_query_caps *caps;
+	struct mlx5dr_context *ctx;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t relaxed;
 	uint8_t tunnel;
@@ -815,6 +815,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 			     struct rte_flow_item *item,
 			     int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
@@ -836,7 +837,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 	}
 
 	if (m->teid) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -844,11 +845,11 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->item_idx = item_idx;
 		fc->tag_set = &mlx5dr_definer_gtp_teid_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, teid);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_1 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_1 * DW_SIZE;
 	}
 
 	if (m->v_pt_rsv_flags) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -857,12 +858,12 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_flag_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 
 	if (m->msg_type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -871,7 +872,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_msg_type_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, msg_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -882,12 +883,13 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 				 struct rte_flow_item *item,
 				 int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp_psc *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
 	/* Overwrite GTP extension flag to be 1 */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -896,12 +898,12 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	/* Overwrite next extension header type */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -911,14 +913,14 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_opt_gtp, next_ext_hdr_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_opt_gtp, next_ext_hdr_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_2 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_2 * DW_SIZE;
 	}
 
 	if (!m)
 		return 0;
 
 	if (m->hdr.type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -927,11 +929,11 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_pdu_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, pdu_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, pdu_type);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	if (m->hdr.qfi) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -940,7 +942,7 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_qfi_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, qfi);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, qfi);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -951,18 +953,19 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 			      struct rte_flow_item *item,
 			      int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_ethdev *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t bit_offset = 0;
 
 	if (m->port_id) {
-		if (!cd->caps->wire_regc_mask) {
+		if (!caps->wire_regc_mask) {
 			DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask");
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
 
-		while (!(cd->caps->wire_regc_mask & (1 << bit_offset)))
+		while (!(caps->wire_regc_mask & (1 << bit_offset)))
 			bit_offset++;
 
 		fc = &cd->fc[MLX5DR_DEFINER_FNAME_VPORT_REG_C_0];
@@ -971,7 +974,7 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		DR_CALC_SET_HDR(fc, registers, register_c_0);
 		fc->bit_off = bit_offset;
-		fc->bit_mask = cd->caps->wire_regc_mask >> bit_offset;
+		fc->bit_mask = caps->wire_regc_mask >> bit_offset;
 	} else {
 		DR_LOG(ERR, "Pord ID item mask must specify ID mask");
 		rte_errno = EINVAL;
@@ -1479,8 +1482,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 	int ret;
 
 	cd.fc = fc;
-	cd.hl = hl;
-	cd.caps = ctx->caps;
+	cd.ctx = ctx;
 	cd.relaxed = mt->flags & MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH;
 
 	/* Collect all RTE fields to the field array and set header layout */
-- 
2.27.0


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

* [PATCH v2 4/8] net/mlx5/hws: add IPv6 routing extension matching support
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
                       ` (2 preceding siblings ...)
  2023-01-19  3:11     ` [PATCH v2 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
                       ` (3 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland, Alex Vesker

Add mlx5 HWS logic to match IPv6 routing extension header.

Once detecting IPv6 matching extension items in pattern template
create callback, PMD allocates a flex parser to sample the first
dword of srv6 header.

Only support next_hdr/segments_left/type for now.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Reviewed-by: Alex Vesker <valex@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c  |  7 +-
 drivers/net/mlx5/hws/mlx5dr_definer.c | 91 ++++++++++++++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_definer.h | 15 +++++
 drivers/net/mlx5/mlx5.c               | 92 ++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5.h               | 16 +++++
 drivers/net/mlx5/mlx5_flow.h          | 28 ++++++++
 drivers/net/mlx5/mlx5_flow_hw.c       | 29 +++++++--
 7 files changed, 268 insertions(+), 10 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 1f65ea7dcb..22a94c1e1a 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -607,7 +607,7 @@ mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
 
 int
 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				  struct mlx5_ext_sample_id ids[],
+				  struct mlx5_ext_sample_id *ids,
 				  uint32_t num, uint8_t *anchor)
 {
 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
@@ -637,8 +637,9 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			(void *)flex_obj);
 		return -rte_errno;
 	}
-	*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
-	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
+	if (anchor)
+		*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
+	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM && idx <= num; i++) {
 		void *s_off = (void *)((char *)sample + i *
 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
 		uint32_t en;
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 0f1cab7e07..142fc545eb 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -125,6 +125,7 @@ struct mlx5dr_definer_conv_data {
 	X(SET_BE16,	ipv4_frag,		v->fragment_offset,	rte_ipv4_hdr) \
 	X(SET_BE16,	ipv6_payload_len,	v->hdr.payload_len,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_proto,		v->hdr.proto,		rte_flow_item_ipv6) \
+	X(SET,		ipv6_routing_hdr,	IPPROTO_ROUTING,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_hop_limits,	v->hdr.hop_limits,	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_127_96,	&v->hdr.src_addr[0],	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_95_64,	&v->hdr.src_addr[4],	rte_flow_item_ipv6) \
@@ -293,6 +294,21 @@ mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc,
 	DR_SET(tag, ok1_bits, fc->byte_off, fc->bit_off, fc->bit_mask);
 }
 
+static void
+mlx5dr_definer_ipv6_routing_ext_set(struct mlx5dr_definer_fc *fc,
+				    const void *item,
+				    uint8_t *tag)
+{
+	const struct rte_flow_item_ipv6_routing_ext *v = item;
+	uint32_t val;
+
+	val = v->hdr.next_hdr << __mlx5_dw_bit_off(header_ipv6_routing_ext, next_hdr);
+	val |= v->hdr.type << __mlx5_dw_bit_off(header_ipv6_routing_ext, type);
+	val |= v->hdr.segments_left <<
+		__mlx5_dw_bit_off(header_ipv6_routing_ext, segments_left);
+	DR_SET(tag, val, fc->byte_off, 0, fc->bit_mask);
+}
+
 static void
 mlx5dr_definer_gre_key_set(struct mlx5dr_definer_fc *fc,
 			   const void *item_spec,
@@ -1468,6 +1484,76 @@ mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd,
 	return 0;
 }
 
+static struct mlx5dr_definer_fc *
+mlx5dr_definer_get_flex_parser_fc(struct mlx5dr_definer_conv_data *cd, uint32_t byte_off)
+{
+	uint32_t byte_off_fp7 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_7);
+	uint32_t byte_off_fp0 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_0);
+	enum mlx5dr_definer_fname fname = MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
+	struct mlx5dr_definer_fc *fc;
+	uint32_t idx;
+
+	if (byte_off < byte_off_fp7 || byte_off > byte_off_fp0) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+	idx = (byte_off_fp0 - byte_off) / (sizeof(uint32_t));
+	fname += (enum mlx5dr_definer_fname)idx;
+	fc = &cd->fc[fname];
+	fc->byte_off = byte_off;
+	fc->bit_mask = UINT32_MAX;
+	return fc;
+}
+
+static int
+mlx5dr_definer_conv_item_ipv6_routing_ext(struct mlx5dr_definer_conv_data *cd,
+					  struct rte_flow_item *item,
+					  int item_idx)
+{
+	const struct rte_flow_item_ipv6_routing_ext *m = item->mask;
+	struct mlx5dr_definer_fc *fc;
+	bool inner = cd->tunnel;
+	uint32_t byte_off;
+
+	if (!cd->relaxed) {
+		fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_version_set;
+		fc->tag_mask_set = &mlx5dr_definer_ones_set;
+		DR_CALC_SET(fc, eth_l2, l3_type, inner);
+
+		/* Overwrite - Unset ethertype if present */
+		memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
+
+		fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
+		if (!fc->tag_set) {
+			fc->item_idx = item_idx;
+			fc->tag_set = &mlx5dr_definer_ipv6_routing_hdr_set;
+			fc->tag_mask_set = &mlx5dr_definer_ones_set;
+			DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
+		}
+	}
+
+	if (!m)
+		return 0;
+
+	if (m->hdr.hdr_len || m->hdr.flags) {
+		rte_errno = ENOTSUP;
+		return rte_errno;
+	}
+
+	if (m->hdr.next_hdr || m->hdr.type || m->hdr.segments_left) {
+		byte_off = flow_hw_get_srh_flex_parser_byte_off_from_ctx(cd->ctx);
+		fc = mlx5dr_definer_get_flex_parser_fc(cd, byte_off);
+		if (!fc)
+			return rte_errno;
+
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_routing_ext_set;
+	}
+	return 0;
+}
+
 static int
 mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 				struct mlx5dr_match_template *mt,
@@ -1583,6 +1669,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 			ret = mlx5dr_definer_conv_item_meter_color(&cd, items, i);
 			item_flags |= MLX5_FLOW_ITEM_METER_COLOR;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ret = mlx5dr_definer_conv_item_ipv6_routing_ext(&cd, items, i);
+			item_flags |= cd.tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
+						  MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
+			break;
 		default:
 			DR_LOG(ERR, "Unsupported item type %d", items->type);
 			rte_errno = ENOTSUP;
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h
index d52c6b0627..c857848a28 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.h
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.h
@@ -511,6 +511,21 @@ struct mlx5_ifc_header_ipv6_vtc_bits {
 	u8 flow_label[0x14];
 };
 
+struct mlx5_ifc_header_ipv6_routing_ext_bits {
+	u8 next_hdr[0x8];
+	u8 hdr_len[0x8];
+	u8 type[0x8];
+	u8 segments_left[0x8];
+	union {
+		u8 flags[0x20];
+		struct {
+			u8 last_entry[0x8];
+			u8 flag[0x8];
+			u8 tag[0x10];
+		};
+	};
+};
+
 struct mlx5_ifc_header_vxlan_bits {
 	u8 flags[0x8];
 	u8 reserved1[0x18];
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 0b97c4e78d..94fd5a91e3 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -970,7 +970,6 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		.modify_field_select = 0,
 	};
 	struct mlx5_ext_sample_id ids[8];
-	uint8_t anchor_id;
 	int ret;
 
 	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
@@ -1006,7 +1005,7 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->num = 2;
-	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, &anchor_id);
+	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, NULL);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to query sample IDs.");
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
@@ -1041,6 +1040,95 @@ mlx5_flex_parser_ecpri_release(struct rte_eth_dev *dev)
 	prf->obj = NULL;
 }
 
+/*
+ * Allocation of a flex parser for srh. Once refcnt is zero, the resources held
+ * by this parser will be freed.
+ * @param dev
+ *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev)
+{
+	struct mlx5_devx_graph_node_attr node = {
+		.modify_field_select = 0,
+	};
+	struct mlx5_ext_sample_id ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_common_dev_config *config = &priv->sh->cdev->config;
+	void *ibv_ctx = priv->sh->cdev->ctx;
+	int ret;
+
+	memset(ids, 0xff, sizeof(ids));
+	if (!config->hca_attr.parse_graph_flex_node) {
+		DRV_LOG(ERR, "Dynamic flex parser is not supported");
+		return -ENOTSUP;
+	}
+	if (__atomic_add_fetch(&priv->sh->srh_flex_parser.refcnt, 1, __ATOMIC_RELAXED) > 1)
+		return 0;
+
+	node.header_length_mode = MLX5_GRAPH_NODE_LEN_FIELD;
+	/* Srv6 first two DW are not counted in. */
+	node.header_length_base_value = 0x8;
+	/* The unit is uint64_t. */
+	node.header_length_field_shift = 0x3;
+	/* Header length is the 2nd byte. */
+	node.header_length_field_offset = 0x8;
+	node.header_length_field_mask = 0xF;
+	/* One byte next header protocol. */
+	node.next_header_field_size = 0x8;
+	node.in[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IP;
+	node.in[0].compare_condition_value = IPPROTO_ROUTING;
+	node.sample[0].flow_match_sample_en = 1;
+	/* First come first serve no matter inner or outer. */
+	node.sample[0].flow_match_sample_tunnel_mode = MLX5_GRAPH_SAMPLE_TUNNEL_FIRST;
+	node.out[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_TCP;
+	node.out[0].compare_condition_value = IPPROTO_TCP;
+	node.out[1].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_UDP;
+	node.out[1].compare_condition_value = IPPROTO_UDP;
+	node.out[2].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IPV6;
+	node.out[2].compare_condition_value = IPPROTO_IPV6;
+	priv->sh->srh_flex_parser.fp = mlx5_devx_cmd_create_flex_parser(ibv_ctx, &node);
+	if (!priv->sh->srh_flex_parser.fp) {
+		DRV_LOG(ERR, "Failed to create flex parser node object.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	priv->sh->srh_flex_parser.num = 1;
+	ret = mlx5_devx_cmd_query_parse_samples(priv->sh->srh_flex_parser.fp, ids,
+						priv->sh->srh_flex_parser.num,
+						&priv->sh->srh_flex_parser.anchor_id);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to query sample IDs.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	priv->sh->srh_flex_parser.offset[0] = 0x0;
+	priv->sh->srh_flex_parser.ids[0].id = ids[0].id;
+	return 0;
+}
+
+/*
+ * Destroy the flex parser node, including the parser itself, input / output
+ * arcs and DW samples. Resources could be reused then.
+ *
+ * @param dev
+ *   Pointer to Ethernet device structure
+ */
+void
+mlx5_free_srh_flex_parser(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_internal_flex_parser_profile *fp = &priv->sh->srh_flex_parser;
+
+	if (__atomic_sub_fetch(&fp->refcnt, 1, __ATOMIC_RELAXED))
+		return;
+	if (fp->fp)
+		mlx5_devx_cmd_destroy(fp->fp);
+	fp->fp = NULL;
+	fp->num = 0;
+}
+
 uint32_t
 mlx5_get_supported_sw_parsing_offloads(const struct mlx5_hca_attr *attr)
 {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 83fb316ad8..bea1f62ea8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -543,6 +543,17 @@ struct mlx5_counter_stats_raw {
 	volatile struct flow_counter_stats *data;
 };
 
+/* Mlx5 internal flex parser profile structure. */
+struct mlx5_internal_flex_parser_profile {
+	uint32_t num;/* Actual number of samples. */
+	/* Sample IDs for this profile. */
+	struct mlx5_ext_sample_id ids[MLX5_FLEX_ITEM_MAPPING_NUM];
+	uint32_t offset[MLX5_FLEX_ITEM_MAPPING_NUM]; /* Each ID sample offset. */
+	uint8_t anchor_id;
+	uint32_t refcnt;
+	void *fp; /* DevX flex parser object. */
+};
+
 TAILQ_HEAD(mlx5_counter_pools, mlx5_flow_counter_pool);
 
 /* Counter global management structure. */
@@ -1436,6 +1447,7 @@ struct mlx5_dev_ctx_shared {
 	struct mlx5_uar rx_uar; /* DevX UAR for Rx. */
 	struct mlx5_proc_priv *pppriv; /* Pointer to primary private process. */
 	struct mlx5_ecpri_parser_profile ecpri_parser;
+	struct mlx5_internal_flex_parser_profile srh_flex_parser; /* srh flex parser structure. */
 	/* Flex parser profiles information. */
 	LIST_HEAD(shared_rxqs, mlx5_rxq_ctrl) shared_rxqs; /* Shared RXQs. */
 	struct mlx5_aso_age_mng *aso_age_mng;
@@ -2258,4 +2270,8 @@ struct mlx5_list_entry *mlx5_flex_parser_clone_cb(void *list_ctx,
 						  void *ctx);
 void mlx5_flex_parser_clone_free_cb(void *tool_ctx,
 				    struct mlx5_list_entry *entry);
+
+int mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev);
+
+void mlx5_free_srh_flex_parser(struct rte_eth_dev *dev);
 #endif /* RTE_PMD_MLX5_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index e376dcae93..1f359cfb12 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -219,6 +219,10 @@ enum mlx5_feature_name {
 /* Meter color item */
 #define MLX5_FLOW_ITEM_METER_COLOR (UINT64_C(1) << 44)
 
+/* IPv6 routing extension item */
+#define MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT (UINT64_C(1) << 45)
+#define MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT (UINT64_C(1) << 46)
+
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
 	(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
@@ -2611,4 +2615,28 @@ int mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 			   enum rte_flow_field_id field, int inherit,
 			   const struct rte_flow_attr *attr,
 			   struct rte_flow_error *error);
+
+static __rte_always_inline int
+flow_hw_get_srh_flex_parser_byte_off_from_ctx(void *dr_ctx __rte_unused)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+	uint16_t port;
+
+	MLX5_ETH_FOREACH_DEV(port, NULL) {
+		struct mlx5_priv *priv;
+		struct mlx5_hca_flex_attr *attr;
+
+		priv = rte_eth_devices[port].data->dev_private;
+		attr = &priv->sh->cdev->config.hca_attr.flex;
+		if (priv->dr_ctx == dr_ctx && attr->ext_sample_id) {
+			if (priv->sh->srh_flex_parser.num)
+				return priv->sh->srh_flex_parser.ids[0].format_select_dw *
+					sizeof(uint32_t);
+			else
+				return UINT32_MAX;
+		}
+	}
+#endif
+	return UINT32_MAX;
+}
 #endif /* RTE_PMD_MLX5_FLOW_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 20c71ff7f0..c6542bdee9 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -213,17 +213,17 @@ flow_hw_hashfields_set(struct mlx5_flow_rss_desc *rss_desc,
 }
 
 /**
- * Generate the pattern item flags.
- * Will be used for shared RSS action.
+ * Generate the matching pattern item flags.
  *
  * @param[in] items
  *   Pointer to the list of items.
  *
  * @return
- *   Item flags.
+ *   Matching item flags. RSS hash field function
+ *   silently ignores the flags which are unsupported.
  */
 static uint64_t
-flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
+flow_hw_matching_item_flags_get(const struct rte_flow_item items[])
 {
 	uint64_t item_flags = 0;
 	uint64_t last_item = 0;
@@ -249,6 +249,10 @@ flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
 			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
 					     MLX5_FLOW_LAYER_OUTER_L4_UDP;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			last_item = tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
+					     MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
+			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			last_item = MLX5_FLOW_LAYER_GRE;
 			break;
@@ -4732,6 +4736,7 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_ICMP:
 		case RTE_FLOW_ITEM_TYPE_ICMP6:
 		case RTE_FLOW_ITEM_TYPE_CONNTRACK:
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
 			break;
 		case RTE_FLOW_ITEM_TYPE_INTEGRITY:
 			/*
@@ -4860,7 +4865,7 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 				   "cannot create match template");
 		return NULL;
 	}
-	it->item_flags = flow_hw_rss_item_flags_get(tmpl_items);
+	it->item_flags = flow_hw_matching_item_flags_get(tmpl_items);
 	if (copied_items) {
 		if (attr->ingress)
 			it->implicit_port = true;
@@ -4868,6 +4873,17 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 			it->implicit_tag = true;
 		mlx5_free(copied_items);
 	}
+	/* Either inner or outer, can't both. */
+	if (it->item_flags & (MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT |
+			      MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT)) {
+		if (((it->item_flags & MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT) &&
+		     (it->item_flags & MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT)) ||
+		    (mlx5_alloc_srh_flex_parser(dev))) {
+			claim_zero(mlx5dr_match_template_destroy(it->mt));
+			mlx5_free(it);
+			return NULL;
+		}
+	}
 	__atomic_fetch_add(&it->refcnt, 1, __ATOMIC_RELAXED);
 	LIST_INSERT_HEAD(&priv->flow_hw_itt, it, next);
 	return it;
@@ -4899,6 +4915,9 @@ flow_hw_pattern_template_destroy(struct rte_eth_dev *dev __rte_unused,
 				   NULL,
 				   "item template in using");
 	}
+	if (template->item_flags & (MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT |
+				    MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT))
+		mlx5_free_srh_flex_parser(dev);
 	LIST_REMOVE(template, next);
 	claim_zero(mlx5dr_match_template_destroy(template->mt));
 	mlx5_free(template);
-- 
2.27.0


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

* [PATCH v2 5/8] app/testpmd: add IPv6 routing extension header in raw encap
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
                       ` (3 preceding siblings ...)
  2023-01-19  3:11     ` [PATCH v2 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang; +Cc: dev, rasland

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7a8516829c..4bdb46e89a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10925,6 +10925,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.next_hdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11027,6 +11034,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11181,6 +11191,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11201,6 +11212,18 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			if (!ext->hdr.hdr_len) {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.segments_left << 4);
+				ext->hdr.hdr_len = ext->hdr.segments_left << 1;
+			} else {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.hdr_len << 3);
+			}
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* [PATCH v2 6/8] ethdev: add modify IPv6 protocol field
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
                       ` (4 preceding siblings ...)
  2023-01-19  3:11     ` [PATCH v2 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko
  Cc: dev, rasland

Add IPv6 protocol modify field definition.

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 lib/ethdev/rte_flow.h       | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4bdb46e89a..1340cf3a9b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 0120d3e7d2..05a90c8201 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3547,6 +3547,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [PATCH v2 7/8] net/mlx5: add modify IPv6 protocol implementation
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
                       ` (5 preceding siblings ...)
  2023-01-19  3:11     ` [PATCH v2 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  2023-01-19  3:11     ` [PATCH v2 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Add HWS modify IPv6 protocol implementation.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h  |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index ce6cd98fd7..497f2622b2 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -759,6 +759,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x4A,
 };
 
 /* Total number of metadata reg_c's. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 7ca909999b..e972a2dc5a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1357,6 +1357,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
 	case RTE_FLOW_FIELD_IPV6_SRC:
 	case RTE_FLOW_FIELD_IPV6_DST:
@@ -1883,6 +1884,15 @@ mlx5_flow_field_id_to_modify_info
 				info[idx].offset = data->offset;
 		}
 		break;
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IPV6_NEXT_HDR};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_POINTER:
 	case RTE_FLOW_FIELD_VALUE:
 	default:
-- 
2.27.0


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

* [PATCH v2 8/8] doc/mlx5: add IPv6 routing extension matching docs
  2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
                       ` (6 preceding siblings ...)
  2023-01-19  3:11     ` [PATCH v2 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
@ 2023-01-19  3:11     ` Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-19  3:11 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Ferruh Yigit; +Cc: dev, rasland

Update mlx5 related document on IPv6 routing extension header
matching.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 doc/guides/nics/features/default.ini | 1 +
 doc/guides/nics/features/mlx5.ini    | 1 +
 doc/guides/nics/mlx5.rst             | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 510cc6679d..3d0744a243 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -141,6 +141,7 @@ udp                  =
 vlan                 =
 vxlan                =
 vxlan_gpe            =
+ipv6_routing_ext     =
 
 [rte_flow actions]
 age                  =
diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index 62fd330e2b..bd911a467b 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -87,6 +87,7 @@ vlan                 = Y
 vxlan                = Y
 vxlan_gpe            = Y
 represented_port     = Y
+ipv6_routing_ext     = Y
 
 [rte_flow actions]
 age                  = I
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index f137f156f9..966f1bd83f 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -106,6 +106,7 @@ Features
 - Sub-Function representors.
 - Sub-Function.
 - Matching on represented port.
+- Matching on IPv6 routing extension header.
 
 
 Limitations
@@ -174,6 +175,7 @@ Limitations
 
     - ``-EAGAIN`` for ``rte_eth_dev_start()``.
     - ``-EBUSY`` for ``rte_eth_dev_stop()``.
+  - Matching on ICMP6 following IPv6 routing extension header, should match ipv6_routing_ext_next_hdr instead of ICMP6.
 
 - When using Verbs flow engine (``dv_flow_en`` = 0), flow pattern without any
   specific VLAN will match for VLAN packets as well:
-- 
2.27.0


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

* Re: [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-19  3:11     ` [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-20  9:20       ` Andrew Rybchenko
  2023-01-30  3:46         ` Rongwei Liu
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
  0 siblings, 2 replies; 67+ messages in thread
From: Andrew Rybchenko @ 2023-01-20  9:20 UTC (permalink / raw)
  To: Rongwei Liu, matan, viacheslavo, orika, thomas, Aman Singh,
	Yuying Zhang, Ferruh Yigit, Olivier Matz
  Cc: dev, rasland

On 1/19/23 06:11, Rongwei Liu wrote:
> Add IPv6 routing extension header definition and no
> TLV support for now.
> 
> At rte_flow layer, there are new items defined for matching
> type/nexthdr/segments_left field.
> 
> Add command line support for IPv6 routing extension header
> matching: type/nexthdr/segment_list.
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>

[snip]

> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index 3e6242803d..ae99036be0 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
>   
>   - ``color``: Metering color marker.
>   
> +Item: ``IPV6_ROUTING_EXT``
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches ipv6 routing extension header.

ipv6 -> IPv6

> +
> +- ``next_hdr``: Next layer header type.
> +- ``type``: IPv6 routing extension header type.
> +- ``segments_left``: How many IPv6 destination addresses carries on

Why are only 3 fields mentioned above?

> +
>   Actions
>   ~~~~~~~
>   
> diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
> index b8c5b68d6c..2a794d598e 100644
> --- a/doc/guides/rel_notes/release_23_03.rst
> +++ b/doc/guides/rel_notes/release_23_03.rst
> @@ -55,6 +55,11 @@ New Features
>        Also, make sure to start the actual text at the margin.
>        =======================================================
>   
> +* **Added rte_flow support for matching IPv6 routing extension header fields.**
> +
> +  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
> +  header

Missing full stop above.

> +
>   
>   Removed Items
>   -------------
> @@ -84,6 +89,11 @@ API Changes
>      Also, make sure to start the actual text at the margin.
>      =======================================================
>   
> +* ethdev: added a new structure:
> +
> +    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
> +      ``rte_ipv6_routing_ext``
> +

If I'm not mistaken, additions should not be here. It is not an
API change.

>   
>   ABI Changes
>   -----------
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 7d0c24366c..4074b475c8 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -76,6 +76,20 @@ rte_flow_item_flex_conv(void *buf, const void *data)
>   	return src->length;
>   }
>   
> +static size_t
> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
> +{
> +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> +	size_t len;
> +
> +	len = src->hdr.hdr_len ? src->hdr.hdr_len << 3 : src->hdr.segments_left << 4;

Compare hdr_len vs 0 explicitly.
Also I'd add parenthesis around ternary operator
values to make it simpler to understand.

> +	if (buf)

Please, compare vs NULL explicitly. May be 'dst' would be
better here?

> +		rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
> +			   src->hdr.segments, len);
> +	return len;
> +}
> +
>   /** Generate flow_item[] entry. */
>   #define MK_FLOW_ITEM(t, s) \
>   	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
> @@ -157,6 +171,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>   	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>   	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>   	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
> +	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
> +			rte_flow_item_ipv6_routing_ext_conv),
>   };
>   
>   /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index b60987db4b..0120d3e7d2 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -624,6 +624,13 @@ enum rte_flow_item_type {
>   	 * See struct rte_flow_item_meter_color.
>   	 */
>   	RTE_FLOW_ITEM_TYPE_METER_COLOR,
> +
> +	/**
> +	 * Matches the presence of IPv6 routing extension header.
> +	 *
> +	 * See struct rte_flow_item_ipv6_routing_ext.

@see

> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
>   };
>   
>   /**
> @@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
>   	uint32_t reserved:23;
>   };
>   
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> + *
> + * Matches an IPv6 routing extension header.
> + */
> +struct rte_flow_item_ipv6_routing_ext {
> +	struct rte_ipv6_routing_ext hdr;
> +};
> +

What about default mask?

>   /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
>   #ifndef __cplusplus
>   static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
> index 9c8e8206f0..158a2f83ce 100644
> --- a/lib/net/rte_ip.h
> +++ b/lib/net/rte_ip.h
> @@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
>   	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
>   } __rte_packed;
>   
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t next_hdr;			/**< Protocol, next header. */
> +	uint8_t hdr_len;			/**< Header length. */
> +	uint8_t type;				/**< Extension header type. */
> +	uint8_t segments_left;			/**< Valid segments number. */
> +	__extension__
> +	union {
> +		uint32_t flags;

rte_be32_t ?

> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			uint16_t tag;		/**< Packet tag. */

rte_be16_t

> +		};
> +	};
> +	__extension__
> +	uint32_t segments[0];			/**< Each hop IPv6 address. */

rte_be32_t

> +} __rte_packed;
> +
>   /* IPv6 vtc_flow: IPv / TC / flow_label */
>   #define RTE_IPV6_HDR_FL_SHIFT 0
>   #define RTE_IPV6_HDR_TC_SHIFT 20


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

* RE: [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-20  9:20       ` Andrew Rybchenko
@ 2023-01-30  3:46         ` Rongwei Liu
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
  1 sibling, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:46 UTC (permalink / raw)
  To: Andrew Rybchenko, Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz
  Cc: dev, Raslan Darawsheh

HI Andrew

BR
Rongwei

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, January 20, 2023 17:21
> To: Rongwei Liu <rongweil@nvidia.com>; Matan Azrad <matan@nvidia.com>;
> Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>;
> NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman
> Singh <aman.deep.singh@intel.com>; Yuying Zhang
> <yuying.zhang@intel.com>; Ferruh Yigit <ferruh.yigit@amd.com>; Olivier
> Matz <olivier.matz@6wind.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v2 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On 1/19/23 06:11, Rongwei Liu wrote:
> > Add IPv6 routing extension header definition and no TLV support for
> > now.
> >
> > At rte_flow layer, there are new items defined for matching
> > type/nexthdr/segments_left field.
> >
> > Add command line support for IPv6 routing extension header
> > matching: type/nexthdr/segment_list.
> >
> > Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> > Acked-by: Ori Kam <orika@nvidia.com>
> 
> [snip]
> 
> > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index 3e6242803d..ae99036be0 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
> >
> >   - ``color``: Metering color marker.
> >
> > +Item: ``IPV6_ROUTING_EXT``
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches ipv6 routing extension header.
> 
> ipv6 -> IPv6
Sure.
> 
> > +
> > +- ``next_hdr``: Next layer header type.
> > +- ``type``: IPv6 routing extension header type.
> > +- ``segments_left``: How many IPv6 destination addresses carries on
> 
> Why are only 3 fields mentioned above?
> 
This is the 1st phase to matching the 1st uint32 of IPv6 routing extension. 
No need to match hdr_len since TLV is ignored.
> > +
> >   Actions
> >   ~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_23_03.rst
> > b/doc/guides/rel_notes/release_23_03.rst
> > index b8c5b68d6c..2a794d598e 100644
> > --- a/doc/guides/rel_notes/release_23_03.rst
> > +++ b/doc/guides/rel_notes/release_23_03.rst
> > @@ -55,6 +55,11 @@ New Features
> >        Also, make sure to start the actual text at the margin.
> >        =======================================================
> >
> > +* **Added rte_flow support for matching IPv6 routing extension header
> > +fields.**
> > +
> > +  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing
> > + extension  header
> 
> Missing full stop above.
> 
Sure
> > +
> >
> >   Removed Items
> >   -------------
> > @@ -84,6 +89,11 @@ API Changes
> >      Also, make sure to start the actual text at the margin.
> >      =======================================================
> >
> > +* ethdev: added a new structure:
> > +
> > +    - IPv6 routing extension header ``rte_flow_item_ipv6_routing_ext`` and
> > +      ``rte_ipv6_routing_ext``
> > +
> 
> If I'm not mistaken, additions should not be here. It is not an API change.
> 
Checked existing release doc, "ihl" and "version" of IPv4 header is added here but with "net:" prefix.
Do you think it' good to follow? 
> >
> >   ABI Changes
> >   -----------
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> > 7d0c24366c..4074b475c8 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -76,6 +76,20 @@ rte_flow_item_flex_conv(void *buf, const void *data)
> >       return src->length;
> >   }
> >
> > +static size_t
> > +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data) {
> > +     struct rte_flow_item_ipv6_routing_ext *dst = buf;
> > +     const struct rte_flow_item_ipv6_routing_ext *src = data;
> > +     size_t len;
> > +
> > +     len = src->hdr.hdr_len ? src->hdr.hdr_len << 3 :
> > + src->hdr.segments_left << 4;
> 
> Compare hdr_len vs 0 explicitly.
> Also I'd add parenthesis around ternary operator values to make it simpler to
> understand.
Sure.
> 
> > +     if (buf)
> 
> Please, compare vs NULL explicitly. May be 'dst' would be better here?
> 
> > +             rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)),
> > +                        src->hdr.segments, len);
> > +     return len;
> > +}
> > +
Sure.
> >   /** Generate flow_item[] entry. */
> >   #define MK_FLOW_ITEM(t, s) \
> >       [RTE_FLOW_ITEM_TYPE_ ## t] = { \ @@ -157,6 +171,8 @@ static
> > const struct rte_flow_desc_data rte_flow_desc_item[] = {
> >       MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> >       MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >       MK_FLOW_ITEM(METER_COLOR, sizeof(struct
> > rte_flow_item_meter_color)),
> > +     MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct
> rte_flow_item_ipv6_routing_ext),
> > +                     rte_flow_item_ipv6_routing_ext_conv),
> >   };
> >
> >   /** Generate flow_action[] entry. */ diff --git
> > a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > b60987db4b..0120d3e7d2 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -624,6 +624,13 @@ enum rte_flow_item_type {
> >        * See struct rte_flow_item_meter_color.
> >        */
> >       RTE_FLOW_ITEM_TYPE_METER_COLOR,
> > +
> > +     /**
> > +      * Matches the presence of IPv6 routing extension header.
> > +      *
> > +      * See struct rte_flow_item_ipv6_routing_ext.
> 
> @see
> 
Sure. Looks like there are so many existing wrong usages "See struct" in this file.
> > +      */
> > +     RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
> >   };
> >
> >   /**
> > @@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
> >       uint32_t reserved:23;
> >   };
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + *
> > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > + *
> > + * Matches an IPv6 routing extension header.
> > + */
> > +struct rte_flow_item_ipv6_routing_ext {
> > +     struct rte_ipv6_routing_ext hdr; };
> > +
> 
> What about default mask?
Tried to add default mask declaration in this file but got "unused variable" warning.
Moved it to "cmdline_flow.c" since it' only used in testpmd encap logic.
> 
> >   /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
> >   #ifndef __cplusplus
> >   static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> > diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h index
> > 9c8e8206f0..158a2f83ce 100644
> > --- a/lib/net/rte_ip.h
> > +++ b/lib/net/rte_ip.h
> > @@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
> >       uint8_t  dst_addr[16];  /**< IP address of destination host(s). */
> >   } __rte_packed;
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             uint32_t flags;
> 
> rte_be32_t ?
Sure.
> 
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     uint16_t tag;           /**< Packet tag. */
> 
> rte_be16_t
Sure.
> 
> > +             };
> > +     };
> > +     __extension__
> > +     uint32_t segments[0];                   /**< Each hop IPv6 address. */
> 
> rte_be32_t
Sure.
> 
> > +} __rte_packed;
> > +
> >   /* IPv6 vtc_flow: IPv / TC / flow_label */
> >   #define RTE_IPV6_HDR_FL_SHIFT 0
> >   #define RTE_IPV6_HDR_TC_SHIFT 20


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

* [PATCH v3 0/8] add IPv6 routing extension support
  2023-01-20  9:20       ` Andrew Rybchenko
  2023-01-30  3:46         ` Rongwei Liu
@ 2023-01-30  3:59         ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
                             ` (7 more replies)
  1 sibling, 8 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Support IPv6 routing extension header matching with new rte_flow item.
Add encapsulation support for IPv6 routing extension header.

v3: enhance the format and use be32/be16 in network header structure.
v2: remove redundant rte_flow items. include the commit from Gregory
    to pass the compilation.

Gregory Etelson (1):
  net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data

Rongwei Liu (7):
  ethdev: add IPv6 routing extension header definition
  net/mlx5: adopt IPv6 routing extension prm definition
  net/mlx5/hws: add IPv6 routing extension matching support
  app/testpmd: add IPv6 routing extension header in raw encap
  ethdev: add modify IPv6 protocol field
  net/mlx5/hws: add modify IPv6 protocol implementation
  doc/mlx5: add IPv6 routing extension matching docs

 app/test-pmd/cmdline_flow.c            |  72 ++++++++++++-
 doc/guides/nics/features/default.ini   |   1 +
 doc/guides/nics/features/mlx5.ini      |   1 +
 doc/guides/nics/mlx5.rst               |   2 +
 doc/guides/prog_guide/rte_flow.rst     |   9 ++
 doc/guides/rel_notes/release_23_03.rst |   9 ++
 drivers/common/mlx5/mlx5_devx_cmds.c   |  17 +++-
 drivers/common/mlx5/mlx5_devx_cmds.h   |   7 +-
 drivers/common/mlx5/mlx5_prm.h         |  29 +++++-
 drivers/net/mlx5/hws/mlx5dr_definer.c  | 133 +++++++++++++++++++++----
 drivers/net/mlx5/hws/mlx5dr_definer.h  |  15 +++
 drivers/net/mlx5/mlx5.c                | 103 ++++++++++++++++++-
 drivers/net/mlx5/mlx5.h                |  19 +++-
 drivers/net/mlx5/mlx5_flow.h           |  28 ++++++
 drivers/net/mlx5/mlx5_flow_dv.c        |  10 ++
 drivers/net/mlx5/mlx5_flow_flex.c      |  14 ++-
 drivers/net/mlx5/mlx5_flow_hw.c        |  29 +++++-
 lib/ethdev/rte_flow.c                  |  19 ++++
 lib/ethdev/rte_flow.h                  |  20 ++++
 lib/net/rte_ip.h                       |  21 ++++
 20 files changed, 517 insertions(+), 41 deletions(-)

-- 
2.27.0


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

* [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30 16:47             ` Stephen Hemminger
                               ` (2 more replies)
  2023-01-30  3:59           ` [PATCH v3 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
                             ` (6 subsequent siblings)
  7 siblings, 3 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz
  Cc: dev, rasland

Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst |  9 +++++
 lib/ethdev/rte_flow.c                  | 19 +++++++++++
 lib/ethdev/rte_flow.h                  | 19 +++++++++++
 lib/net/rte_ip.h                       | 21 ++++++++++++
 6 files changed, 123 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..602fab29d3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches IPv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..8f482301f7 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header.
+
 
 Removed Items
 -------------
@@ -84,6 +89,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* net: added a new structure:
+
+    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..5c423db160 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -76,6 +76,23 @@ rte_flow_item_flex_conv(void *buf, const void *data)
 	return src->length;
 }
 
+static size_t
+rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
+{
+	struct rte_flow_item_ipv6_routing_ext *dst = buf;
+	const struct rte_flow_item_ipv6_routing_ext *src = data;
+	size_t len;
+
+	if (src->hdr.hdr_len)
+		len = src->hdr.hdr_len << 3;
+	else
+		len = src->hdr.segments_left << 4;
+	if (dst == NULL)
+		return 0;
+	rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments, len);
+	return len;
+}
+
 /** Generate flow_item[] entry. */
 #define MK_FLOW_ITEM(t, s) \
 	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
@@ -157,6 +174,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
+			rte_flow_item_ipv6_routing_ext_conv),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..9b9018cba2 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * @see struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..56c151372a 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,27 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		rte_be32_t flags;
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			rte_be16_t tag;		/**< Packet tag. */
+		};
+	};
+	__extension__
+	rte_be32_t segments[0];			/**< Each hop IPv6 address. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [PATCH v3 2/8] net/mlx5: adopt IPv6 routing extension prm definition
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
                             ` (5 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Per newest PRM definition, sample_id stands for 3 parts
of information instead of single uint32_t id: sample_id +
modify_filed_id + format_select_dw.

Also new FW capability bits have been introduces to identify
the new capability.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 14 +++++++++++---
 drivers/common/mlx5/mlx5_devx_cmds.h |  7 ++++++-
 drivers/common/mlx5/mlx5_prm.h       | 28 ++++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5.c              | 15 +++++++++++----
 drivers/net/mlx5/mlx5.h              |  3 ++-
 drivers/net/mlx5/mlx5_flow_flex.c    | 14 +++++++++++---
 6 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index e3a4927d0f..1f65ea7dcb 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -607,7 +607,8 @@ mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
 
 int
 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				  uint32_t ids[], uint32_t num)
+				  struct mlx5_ext_sample_id ids[],
+				  uint32_t num, uint8_t *anchor)
 {
 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
 	uint32_t out[MLX5_ST_SZ_DW(create_flex_parser_out)] = {0};
@@ -636,6 +637,7 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			(void *)flex_obj);
 		return -rte_errno;
 	}
+	*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
 	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
 		void *s_off = (void *)((char *)sample + i *
 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
@@ -645,8 +647,8 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			      flow_match_sample_en);
 		if (!en)
 			continue;
-		ids[idx++] = MLX5_GET(parse_graph_flow_match_sample, s_off,
-				  flow_match_sample_field_id);
+		ids[idx++].id = MLX5_GET(parse_graph_flow_match_sample, s_off,
+					 flow_match_sample_field_id);
 	}
 	if (num != idx) {
 		rte_errno = EINVAL;
@@ -794,6 +796,12 @@ mlx5_devx_cmd_query_hca_parse_graph_node_cap
 					 max_num_arc_out);
 	attr->max_num_sample = MLX5_GET(parse_graph_node_cap, hcattr,
 					max_num_sample);
+	attr->anchor_en = MLX5_GET(parse_graph_node_cap, hcattr, anchor_en);
+	attr->ext_sample_id = MLX5_GET(parse_graph_node_cap, hcattr, ext_sample_id);
+	attr->sample_tunnel_inner2 = MLX5_GET(parse_graph_node_cap, hcattr,
+					      sample_tunnel_inner2);
+	attr->zero_size_supported = MLX5_GET(parse_graph_node_cap, hcattr,
+					     zero_size_supported);
 	attr->sample_id_in_out = MLX5_GET(parse_graph_node_cap, hcattr,
 					  sample_id_in_out);
 	attr->max_base_header_length = MLX5_GET(parse_graph_node_cap, hcattr,
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index c94b9eac06..5b33010155 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -114,6 +114,10 @@ struct mlx5_hca_flex_attr {
 	uint8_t  max_num_arc_out;
 	uint8_t  max_num_sample;
 	uint8_t  max_num_prog_sample:5;	/* From HCA CAP 2 */
+	uint8_t  anchor_en:1;
+	uint8_t  ext_sample_id:1;
+	uint8_t  sample_tunnel_inner2:1;
+	uint8_t  zero_size_supported:1;
 	uint8_t  sample_id_in_out:1;
 	uint16_t max_base_header_length;
 	uint8_t  max_sample_base_offset;
@@ -706,7 +710,8 @@ int mlx5_devx_cmd_modify_tir(struct mlx5_devx_obj *tir,
 			     struct mlx5_devx_modify_tir_attr *tir_attr);
 __rte_internal
 int mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				      uint32_t ids[], uint32_t num);
+				      struct mlx5_ext_sample_id ids[],
+				      uint32_t num, uint8_t *anchor);
 
 __rte_internal
 struct mlx5_devx_obj *
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 3790dc84b8..ce6cd98fd7 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1893,7 +1893,11 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 max_num_arc_in[0x08];
 	u8 max_num_arc_out[0x08];
 	u8 max_num_sample[0x08];
-	u8 reserved_at_78[0x07];
+	u8 reserved_at_78[0x03];
+	u8 anchor_en[0x1];
+	u8 ext_sample_id[0x1];
+	u8 sample_tunnel_inner2[0x1];
+	u8 zero_size_supported[0x1];
 	u8 sample_id_in_out[0x1];
 	u8 max_base_header_length[0x10];
 	u8 reserved_at_90[0x08];
@@ -1903,6 +1907,24 @@ struct mlx5_ifc_parse_graph_node_cap_bits {
 	u8 header_length_mask_width[0x08];
 };
 
+/* ext_sample_id structure, see PRM Table: Flow Match Sample ID Format. */
+struct mlx5_ext_sample_id {
+	union {
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			uint32_t format_select_dw:8;
+			uint32_t modify_field_id:12;
+			uint32_t sample_id:12;
+#else
+			uint32_t sample_id:12;
+			uint32_t modify_field_id:12;
+			uint32_t format_select_dw:8;
+#endif
+		};
+		uint32_t id;
+	};
+};
+
 struct mlx5_ifc_flow_table_prop_layout_bits {
 	u8 ft_support[0x1];
 	u8 flow_tag[0x1];
@@ -4522,7 +4544,9 @@ struct mlx5_ifc_parse_graph_flex_bits {
 	u8 header_length_mode[0x4];
 	u8 header_length_field_offset[0x10];
 	u8 next_header_field_offset[0x10];
-	u8 reserved_at_160[0x1b];
+	u8 reserved_at_160[0x12];
+	u8 head_anchor_id[0x6];
+	u8 reserved_at_178[0x3];
 	u8 next_header_field_size[0x5];
 	u8 header_length_field_mask[0x20];
 	u8 reserved_at_224[0x20];
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b8643cebdd..0b97c4e78d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -964,11 +964,13 @@ int
 mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_ecpri_parser_profile *prf =	&priv->sh->ecpri_parser;
 	struct mlx5_devx_graph_node_attr node = {
 		.modify_field_select = 0,
 	};
-	uint32_t ids[8];
+	struct mlx5_ext_sample_id ids[8];
+	uint8_t anchor_id;
 	int ret;
 
 	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
@@ -1004,15 +1006,20 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->num = 2;
-	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num);
+	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, &anchor_id);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to query sample IDs.");
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->offset[0] = 0x0;
 	prf->offset[1] = sizeof(uint32_t);
-	prf->ids[0] = ids[0];
-	prf->ids[1] = ids[1];
+	if (attr->ext_sample_id) {
+		prf->ids[0] = ids[0].sample_id;
+		prf->ids[1] = ids[1].sample_id;
+	} else {
+		prf->ids[0] = ids[0].id;
+		prf->ids[1] = ids[1].id;
+	}
 	return 0;
 }
 
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 16b33e1548..83fb316ad8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1307,9 +1307,10 @@ struct mlx5_lag {
 struct mlx5_flex_parser_devx {
 	struct mlx5_list_entry entry;  /* List element at the beginning. */
 	uint32_t num_samples;
+	uint8_t anchor_id;
 	void *devx_obj;
 	struct mlx5_devx_graph_node_attr devx_conf;
-	uint32_t sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	struct mlx5_ext_sample_id sample_ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
 };
 
 /* Pattern field descriptor - how to translate flex pattern into samples. */
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c b/drivers/net/mlx5/mlx5_flow_flex.c
index fb08910ddb..35f2a9923d 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -226,15 +226,18 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 	void *misc4_m = MLX5_ADDR_OF(fte_match_param, matcher,
 				     misc_parameters_4);
 	void *misc4_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_4);
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	struct mlx5_flex_item *tp;
 	uint32_t i, pos = 0;
+	uint32_t sample_id;
 
 	RTE_SET_USED(dev);
 	MLX5_ASSERT(item->spec && item->mask);
 	spec = item->spec;
 	mask = item->mask;
 	tp = (struct mlx5_flex_item *)spec->handle;
-	MLX5_ASSERT(mlx5_flex_index(dev->data->dev_private, tp) >= 0);
+	MLX5_ASSERT(mlx5_flex_index(priv, tp) >= 0);
 	for (i = 0; i < tp->mapnum; i++) {
 		struct mlx5_flex_pattern_field *map = tp->map + i;
 		uint32_t id = map->reg_id;
@@ -257,9 +260,13 @@ mlx5_flex_flow_translate_item(struct rte_eth_dev *dev,
 			MLX5_ASSERT(id < num_samples);
 			id += num_samples;
 		}
+		if (attr->ext_sample_id)
+			sample_id = tp->devx_fp->sample_ids[id].sample_id;
+		else
+			sample_id = tp->devx_fp->sample_ids[id].id;
 		mlx5_flex_set_match_sample(misc4_m, misc4_v,
 					   def, msk & def, val & msk & def,
-					   tp->devx_fp->sample_ids[id], id);
+					   sample_id, id);
 		pos += map->width;
 	}
 }
@@ -1298,7 +1305,8 @@ mlx5_flex_parser_create_cb(void *list_ctx, void *ctx)
 	/* Query the firmware assigned sample ids. */
 	ret = mlx5_devx_cmd_query_parse_samples(fp->devx_obj,
 						fp->sample_ids,
-						fp->num_samples);
+						fp->num_samples,
+						&fp->anchor_id);
 	if (ret)
 		goto error;
 	DRV_LOG(DEBUG, "DEVx flex parser %p created, samples num: %u",
-- 
2.27.0


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

* [PATCH v3 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
                             ` (4 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland, Gregory Etelson

From: Gregory Etelson <getelson@nvidia.com>

New mlx5dr_context member replaces mlx5dr_cmd_query_caps.
Capabilities structure is a member of mlx5dr_context.

Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_definer.c | 42 ++++++++++++++-------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 6b98eb8c96..0f1cab7e07 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -100,7 +100,7 @@ struct mlx5dr_definer_sel_ctrl {
 };
 
 struct mlx5dr_definer_conv_data {
-	struct mlx5dr_cmd_query_caps *caps;
+	struct mlx5dr_context *ctx;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t relaxed;
 	uint8_t tunnel;
@@ -815,6 +815,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 			     struct rte_flow_item *item,
 			     int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
@@ -836,7 +837,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 	}
 
 	if (m->teid) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_TEID_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -844,11 +845,11 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->item_idx = item_idx;
 		fc->tag_set = &mlx5dr_definer_gtp_teid_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, teid);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_1 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_1 * DW_SIZE;
 	}
 
 	if (m->v_pt_rsv_flags) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -857,12 +858,12 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_flag_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 
 	if (m->msg_type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -871,7 +872,7 @@ mlx5dr_definer_conv_item_gtp(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_msg_type_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, msg_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -882,12 +883,13 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 				 struct rte_flow_item *item,
 				 int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_gtp_psc *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 
 	/* Overwrite GTP extension flag to be 1 */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -896,12 +898,12 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_gtp, ext_hdr_flag);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp, ext_hdr_flag);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE;
 	}
 
 	/* Overwrite next extension header type */
 	if (!cd->relaxed) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_DW_2_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -911,14 +913,14 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		fc->bit_mask = __mlx5_mask(header_opt_gtp, next_ext_hdr_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_opt_gtp, next_ext_hdr_type);
-		fc->byte_off = cd->caps->format_select_gtpu_dw_2 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_dw_2 * DW_SIZE;
 	}
 
 	if (!m)
 		return 0;
 
 	if (m->hdr.type) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -927,11 +929,11 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_pdu_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, pdu_type);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, pdu_type);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	if (m->hdr.qfi) {
-		if (!(cd->caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
+		if (!(caps->flex_protocols & MLX5_HCA_FLEX_GTPU_FIRST_EXT_DW_0_ENABLED)) {
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
@@ -940,7 +942,7 @@ mlx5dr_definer_conv_item_gtp_psc(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_set = &mlx5dr_definer_gtp_ext_hdr_qfi_set;
 		fc->bit_mask = __mlx5_mask(header_gtp_psc, qfi);
 		fc->bit_off = __mlx5_dw_bit_off(header_gtp_psc, qfi);
-		fc->byte_off = cd->caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
+		fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE;
 	}
 
 	return 0;
@@ -951,18 +953,19 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 			      struct rte_flow_item *item,
 			      int item_idx)
 {
+	struct mlx5dr_cmd_query_caps *caps = cd->ctx->caps;
 	const struct rte_flow_item_ethdev *m = item->mask;
 	struct mlx5dr_definer_fc *fc;
 	uint8_t bit_offset = 0;
 
 	if (m->port_id) {
-		if (!cd->caps->wire_regc_mask) {
+		if (!caps->wire_regc_mask) {
 			DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask");
 			rte_errno = ENOTSUP;
 			return rte_errno;
 		}
 
-		while (!(cd->caps->wire_regc_mask & (1 << bit_offset)))
+		while (!(caps->wire_regc_mask & (1 << bit_offset)))
 			bit_offset++;
 
 		fc = &cd->fc[MLX5DR_DEFINER_FNAME_VPORT_REG_C_0];
@@ -971,7 +974,7 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd,
 		fc->tag_mask_set = &mlx5dr_definer_ones_set;
 		DR_CALC_SET_HDR(fc, registers, register_c_0);
 		fc->bit_off = bit_offset;
-		fc->bit_mask = cd->caps->wire_regc_mask >> bit_offset;
+		fc->bit_mask = caps->wire_regc_mask >> bit_offset;
 	} else {
 		DR_LOG(ERR, "Pord ID item mask must specify ID mask");
 		rte_errno = EINVAL;
@@ -1479,8 +1482,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 	int ret;
 
 	cd.fc = fc;
-	cd.hl = hl;
-	cd.caps = ctx->caps;
+	cd.ctx = ctx;
 	cd.relaxed = mt->flags & MLX5DR_MATCH_TEMPLATE_FLAG_RELAXED_MATCH;
 
 	/* Collect all RTE fields to the field array and set header layout */
-- 
2.27.0


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

* [PATCH v3 4/8] net/mlx5/hws: add IPv6 routing extension matching support
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
                             ` (2 preceding siblings ...)
  2023-01-30  3:59           ` [PATCH v3 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
                             ` (3 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland, Alex Vesker

Add mlx5 HWS logic to match IPv6 routing extension header.

Once detecting IPv6 matching extension items in pattern template
create callback, PMD allocates a flex parser to sample the first
dword of srv6 header.

Only support next_hdr/segments_left/type for now.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Reviewed-by: Alex Vesker <valex@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c  |  7 +-
 drivers/net/mlx5/hws/mlx5dr_definer.c | 91 ++++++++++++++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_definer.h | 15 +++++
 drivers/net/mlx5/mlx5.c               | 92 ++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5.h               | 16 +++++
 drivers/net/mlx5/mlx5_flow.h          | 28 ++++++++
 drivers/net/mlx5/mlx5_flow_hw.c       | 29 +++++++--
 7 files changed, 268 insertions(+), 10 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 1f65ea7dcb..22a94c1e1a 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -607,7 +607,7 @@ mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
 
 int
 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
-				  struct mlx5_ext_sample_id ids[],
+				  struct mlx5_ext_sample_id *ids,
 				  uint32_t num, uint8_t *anchor)
 {
 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
@@ -637,8 +637,9 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
 			(void *)flex_obj);
 		return -rte_errno;
 	}
-	*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
-	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
+	if (anchor)
+		*anchor = MLX5_GET(parse_graph_flex, flex, head_anchor_id);
+	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM && idx <= num; i++) {
 		void *s_off = (void *)((char *)sample + i *
 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
 		uint32_t en;
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c
index 0f1cab7e07..142fc545eb 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -125,6 +125,7 @@ struct mlx5dr_definer_conv_data {
 	X(SET_BE16,	ipv4_frag,		v->fragment_offset,	rte_ipv4_hdr) \
 	X(SET_BE16,	ipv6_payload_len,	v->hdr.payload_len,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_proto,		v->hdr.proto,		rte_flow_item_ipv6) \
+	X(SET,		ipv6_routing_hdr,	IPPROTO_ROUTING,	rte_flow_item_ipv6) \
 	X(SET,		ipv6_hop_limits,	v->hdr.hop_limits,	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_127_96,	&v->hdr.src_addr[0],	rte_flow_item_ipv6) \
 	X(SET_BE32P,	ipv6_src_addr_95_64,	&v->hdr.src_addr[4],	rte_flow_item_ipv6) \
@@ -293,6 +294,21 @@ mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc,
 	DR_SET(tag, ok1_bits, fc->byte_off, fc->bit_off, fc->bit_mask);
 }
 
+static void
+mlx5dr_definer_ipv6_routing_ext_set(struct mlx5dr_definer_fc *fc,
+				    const void *item,
+				    uint8_t *tag)
+{
+	const struct rte_flow_item_ipv6_routing_ext *v = item;
+	uint32_t val;
+
+	val = v->hdr.next_hdr << __mlx5_dw_bit_off(header_ipv6_routing_ext, next_hdr);
+	val |= v->hdr.type << __mlx5_dw_bit_off(header_ipv6_routing_ext, type);
+	val |= v->hdr.segments_left <<
+		__mlx5_dw_bit_off(header_ipv6_routing_ext, segments_left);
+	DR_SET(tag, val, fc->byte_off, 0, fc->bit_mask);
+}
+
 static void
 mlx5dr_definer_gre_key_set(struct mlx5dr_definer_fc *fc,
 			   const void *item_spec,
@@ -1468,6 +1484,76 @@ mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd,
 	return 0;
 }
 
+static struct mlx5dr_definer_fc *
+mlx5dr_definer_get_flex_parser_fc(struct mlx5dr_definer_conv_data *cd, uint32_t byte_off)
+{
+	uint32_t byte_off_fp7 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_7);
+	uint32_t byte_off_fp0 = MLX5_BYTE_OFF(definer_hl, flex_parser.flex_parser_0);
+	enum mlx5dr_definer_fname fname = MLX5DR_DEFINER_FNAME_FLEX_PARSER_0;
+	struct mlx5dr_definer_fc *fc;
+	uint32_t idx;
+
+	if (byte_off < byte_off_fp7 || byte_off > byte_off_fp0) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+	idx = (byte_off_fp0 - byte_off) / (sizeof(uint32_t));
+	fname += (enum mlx5dr_definer_fname)idx;
+	fc = &cd->fc[fname];
+	fc->byte_off = byte_off;
+	fc->bit_mask = UINT32_MAX;
+	return fc;
+}
+
+static int
+mlx5dr_definer_conv_item_ipv6_routing_ext(struct mlx5dr_definer_conv_data *cd,
+					  struct rte_flow_item *item,
+					  int item_idx)
+{
+	const struct rte_flow_item_ipv6_routing_ext *m = item->mask;
+	struct mlx5dr_definer_fc *fc;
+	bool inner = cd->tunnel;
+	uint32_t byte_off;
+
+	if (!cd->relaxed) {
+		fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)];
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_version_set;
+		fc->tag_mask_set = &mlx5dr_definer_ones_set;
+		DR_CALC_SET(fc, eth_l2, l3_type, inner);
+
+		/* Overwrite - Unset ethertype if present */
+		memset(&cd->fc[DR_CALC_FNAME(ETH_TYPE, inner)], 0, sizeof(*fc));
+
+		fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)];
+		if (!fc->tag_set) {
+			fc->item_idx = item_idx;
+			fc->tag_set = &mlx5dr_definer_ipv6_routing_hdr_set;
+			fc->tag_mask_set = &mlx5dr_definer_ones_set;
+			DR_CALC_SET(fc, eth_l3, protocol_next_header, inner);
+		}
+	}
+
+	if (!m)
+		return 0;
+
+	if (m->hdr.hdr_len || m->hdr.flags) {
+		rte_errno = ENOTSUP;
+		return rte_errno;
+	}
+
+	if (m->hdr.next_hdr || m->hdr.type || m->hdr.segments_left) {
+		byte_off = flow_hw_get_srh_flex_parser_byte_off_from_ctx(cd->ctx);
+		fc = mlx5dr_definer_get_flex_parser_fc(cd, byte_off);
+		if (!fc)
+			return rte_errno;
+
+		fc->item_idx = item_idx;
+		fc->tag_set = &mlx5dr_definer_ipv6_routing_ext_set;
+	}
+	return 0;
+}
+
 static int
 mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 				struct mlx5dr_match_template *mt,
@@ -1583,6 +1669,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
 			ret = mlx5dr_definer_conv_item_meter_color(&cd, items, i);
 			item_flags |= MLX5_FLOW_ITEM_METER_COLOR;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ret = mlx5dr_definer_conv_item_ipv6_routing_ext(&cd, items, i);
+			item_flags |= cd.tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
+						  MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
+			break;
 		default:
 			DR_LOG(ERR, "Unsupported item type %d", items->type);
 			rte_errno = ENOTSUP;
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h
index d52c6b0627..c857848a28 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.h
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.h
@@ -511,6 +511,21 @@ struct mlx5_ifc_header_ipv6_vtc_bits {
 	u8 flow_label[0x14];
 };
 
+struct mlx5_ifc_header_ipv6_routing_ext_bits {
+	u8 next_hdr[0x8];
+	u8 hdr_len[0x8];
+	u8 type[0x8];
+	u8 segments_left[0x8];
+	union {
+		u8 flags[0x20];
+		struct {
+			u8 last_entry[0x8];
+			u8 flag[0x8];
+			u8 tag[0x10];
+		};
+	};
+};
+
 struct mlx5_ifc_header_vxlan_bits {
 	u8 flags[0x8];
 	u8 reserved1[0x18];
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 0b97c4e78d..94fd5a91e3 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -970,7 +970,6 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		.modify_field_select = 0,
 	};
 	struct mlx5_ext_sample_id ids[8];
-	uint8_t anchor_id;
 	int ret;
 
 	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
@@ -1006,7 +1005,7 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
 	}
 	prf->num = 2;
-	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, &anchor_id);
+	ret = mlx5_devx_cmd_query_parse_samples(prf->obj, ids, prf->num, NULL);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to query sample IDs.");
 		return (rte_errno == 0) ? -ENODEV : -rte_errno;
@@ -1041,6 +1040,95 @@ mlx5_flex_parser_ecpri_release(struct rte_eth_dev *dev)
 	prf->obj = NULL;
 }
 
+/*
+ * Allocation of a flex parser for srh. Once refcnt is zero, the resources held
+ * by this parser will be freed.
+ * @param dev
+ *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev)
+{
+	struct mlx5_devx_graph_node_attr node = {
+		.modify_field_select = 0,
+	};
+	struct mlx5_ext_sample_id ids[MLX5_GRAPH_NODE_SAMPLE_NUM];
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_common_dev_config *config = &priv->sh->cdev->config;
+	void *ibv_ctx = priv->sh->cdev->ctx;
+	int ret;
+
+	memset(ids, 0xff, sizeof(ids));
+	if (!config->hca_attr.parse_graph_flex_node) {
+		DRV_LOG(ERR, "Dynamic flex parser is not supported");
+		return -ENOTSUP;
+	}
+	if (__atomic_add_fetch(&priv->sh->srh_flex_parser.refcnt, 1, __ATOMIC_RELAXED) > 1)
+		return 0;
+
+	node.header_length_mode = MLX5_GRAPH_NODE_LEN_FIELD;
+	/* Srv6 first two DW are not counted in. */
+	node.header_length_base_value = 0x8;
+	/* The unit is uint64_t. */
+	node.header_length_field_shift = 0x3;
+	/* Header length is the 2nd byte. */
+	node.header_length_field_offset = 0x8;
+	node.header_length_field_mask = 0xF;
+	/* One byte next header protocol. */
+	node.next_header_field_size = 0x8;
+	node.in[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IP;
+	node.in[0].compare_condition_value = IPPROTO_ROUTING;
+	node.sample[0].flow_match_sample_en = 1;
+	/* First come first serve no matter inner or outer. */
+	node.sample[0].flow_match_sample_tunnel_mode = MLX5_GRAPH_SAMPLE_TUNNEL_FIRST;
+	node.out[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_TCP;
+	node.out[0].compare_condition_value = IPPROTO_TCP;
+	node.out[1].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_UDP;
+	node.out[1].compare_condition_value = IPPROTO_UDP;
+	node.out[2].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IPV6;
+	node.out[2].compare_condition_value = IPPROTO_IPV6;
+	priv->sh->srh_flex_parser.fp = mlx5_devx_cmd_create_flex_parser(ibv_ctx, &node);
+	if (!priv->sh->srh_flex_parser.fp) {
+		DRV_LOG(ERR, "Failed to create flex parser node object.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	priv->sh->srh_flex_parser.num = 1;
+	ret = mlx5_devx_cmd_query_parse_samples(priv->sh->srh_flex_parser.fp, ids,
+						priv->sh->srh_flex_parser.num,
+						&priv->sh->srh_flex_parser.anchor_id);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to query sample IDs.");
+		return (rte_errno == 0) ? -ENODEV : -rte_errno;
+	}
+	priv->sh->srh_flex_parser.offset[0] = 0x0;
+	priv->sh->srh_flex_parser.ids[0].id = ids[0].id;
+	return 0;
+}
+
+/*
+ * Destroy the flex parser node, including the parser itself, input / output
+ * arcs and DW samples. Resources could be reused then.
+ *
+ * @param dev
+ *   Pointer to Ethernet device structure
+ */
+void
+mlx5_free_srh_flex_parser(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_internal_flex_parser_profile *fp = &priv->sh->srh_flex_parser;
+
+	if (__atomic_sub_fetch(&fp->refcnt, 1, __ATOMIC_RELAXED))
+		return;
+	if (fp->fp)
+		mlx5_devx_cmd_destroy(fp->fp);
+	fp->fp = NULL;
+	fp->num = 0;
+}
+
 uint32_t
 mlx5_get_supported_sw_parsing_offloads(const struct mlx5_hca_attr *attr)
 {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 83fb316ad8..bea1f62ea8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -543,6 +543,17 @@ struct mlx5_counter_stats_raw {
 	volatile struct flow_counter_stats *data;
 };
 
+/* Mlx5 internal flex parser profile structure. */
+struct mlx5_internal_flex_parser_profile {
+	uint32_t num;/* Actual number of samples. */
+	/* Sample IDs for this profile. */
+	struct mlx5_ext_sample_id ids[MLX5_FLEX_ITEM_MAPPING_NUM];
+	uint32_t offset[MLX5_FLEX_ITEM_MAPPING_NUM]; /* Each ID sample offset. */
+	uint8_t anchor_id;
+	uint32_t refcnt;
+	void *fp; /* DevX flex parser object. */
+};
+
 TAILQ_HEAD(mlx5_counter_pools, mlx5_flow_counter_pool);
 
 /* Counter global management structure. */
@@ -1436,6 +1447,7 @@ struct mlx5_dev_ctx_shared {
 	struct mlx5_uar rx_uar; /* DevX UAR for Rx. */
 	struct mlx5_proc_priv *pppriv; /* Pointer to primary private process. */
 	struct mlx5_ecpri_parser_profile ecpri_parser;
+	struct mlx5_internal_flex_parser_profile srh_flex_parser; /* srh flex parser structure. */
 	/* Flex parser profiles information. */
 	LIST_HEAD(shared_rxqs, mlx5_rxq_ctrl) shared_rxqs; /* Shared RXQs. */
 	struct mlx5_aso_age_mng *aso_age_mng;
@@ -2258,4 +2270,8 @@ struct mlx5_list_entry *mlx5_flex_parser_clone_cb(void *list_ctx,
 						  void *ctx);
 void mlx5_flex_parser_clone_free_cb(void *tool_ctx,
 				    struct mlx5_list_entry *entry);
+
+int mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev);
+
+void mlx5_free_srh_flex_parser(struct rte_eth_dev *dev);
 #endif /* RTE_PMD_MLX5_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index e376dcae93..1f359cfb12 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -219,6 +219,10 @@ enum mlx5_feature_name {
 /* Meter color item */
 #define MLX5_FLOW_ITEM_METER_COLOR (UINT64_C(1) << 44)
 
+/* IPv6 routing extension item */
+#define MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT (UINT64_C(1) << 45)
+#define MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT (UINT64_C(1) << 46)
+
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
 	(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
@@ -2611,4 +2615,28 @@ int mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 			   enum rte_flow_field_id field, int inherit,
 			   const struct rte_flow_attr *attr,
 			   struct rte_flow_error *error);
+
+static __rte_always_inline int
+flow_hw_get_srh_flex_parser_byte_off_from_ctx(void *dr_ctx __rte_unused)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+	uint16_t port;
+
+	MLX5_ETH_FOREACH_DEV(port, NULL) {
+		struct mlx5_priv *priv;
+		struct mlx5_hca_flex_attr *attr;
+
+		priv = rte_eth_devices[port].data->dev_private;
+		attr = &priv->sh->cdev->config.hca_attr.flex;
+		if (priv->dr_ctx == dr_ctx && attr->ext_sample_id) {
+			if (priv->sh->srh_flex_parser.num)
+				return priv->sh->srh_flex_parser.ids[0].format_select_dw *
+					sizeof(uint32_t);
+			else
+				return UINT32_MAX;
+		}
+	}
+#endif
+	return UINT32_MAX;
+}
 #endif /* RTE_PMD_MLX5_FLOW_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 20c71ff7f0..c6542bdee9 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -213,17 +213,17 @@ flow_hw_hashfields_set(struct mlx5_flow_rss_desc *rss_desc,
 }
 
 /**
- * Generate the pattern item flags.
- * Will be used for shared RSS action.
+ * Generate the matching pattern item flags.
  *
  * @param[in] items
  *   Pointer to the list of items.
  *
  * @return
- *   Item flags.
+ *   Matching item flags. RSS hash field function
+ *   silently ignores the flags which are unsupported.
  */
 static uint64_t
-flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
+flow_hw_matching_item_flags_get(const struct rte_flow_item items[])
 {
 	uint64_t item_flags = 0;
 	uint64_t last_item = 0;
@@ -249,6 +249,10 @@ flow_hw_rss_item_flags_get(const struct rte_flow_item items[])
 			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
 					     MLX5_FLOW_LAYER_OUTER_L4_UDP;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			last_item = tunnel ? MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT :
+					     MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT;
+			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			last_item = MLX5_FLOW_LAYER_GRE;
 			break;
@@ -4732,6 +4736,7 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_ICMP:
 		case RTE_FLOW_ITEM_TYPE_ICMP6:
 		case RTE_FLOW_ITEM_TYPE_CONNTRACK:
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
 			break;
 		case RTE_FLOW_ITEM_TYPE_INTEGRITY:
 			/*
@@ -4860,7 +4865,7 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 				   "cannot create match template");
 		return NULL;
 	}
-	it->item_flags = flow_hw_rss_item_flags_get(tmpl_items);
+	it->item_flags = flow_hw_matching_item_flags_get(tmpl_items);
 	if (copied_items) {
 		if (attr->ingress)
 			it->implicit_port = true;
@@ -4868,6 +4873,17 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
 			it->implicit_tag = true;
 		mlx5_free(copied_items);
 	}
+	/* Either inner or outer, can't both. */
+	if (it->item_flags & (MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT |
+			      MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT)) {
+		if (((it->item_flags & MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT) &&
+		     (it->item_flags & MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT)) ||
+		    (mlx5_alloc_srh_flex_parser(dev))) {
+			claim_zero(mlx5dr_match_template_destroy(it->mt));
+			mlx5_free(it);
+			return NULL;
+		}
+	}
 	__atomic_fetch_add(&it->refcnt, 1, __ATOMIC_RELAXED);
 	LIST_INSERT_HEAD(&priv->flow_hw_itt, it, next);
 	return it;
@@ -4899,6 +4915,9 @@ flow_hw_pattern_template_destroy(struct rte_eth_dev *dev __rte_unused,
 				   NULL,
 				   "item template in using");
 	}
+	if (template->item_flags & (MLX5_FLOW_ITEM_OUTER_IPV6_ROUTING_EXT |
+				    MLX5_FLOW_ITEM_INNER_IPV6_ROUTING_EXT))
+		mlx5_free_srh_flex_parser(dev);
 	LIST_REMOVE(template, next);
 	claim_zero(mlx5dr_match_template_destroy(template->mt));
 	mlx5_free(template);
-- 
2.27.0


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

* [PATCH v3 5/8] app/testpmd: add IPv6 routing extension header in raw encap
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
                             ` (3 preceding siblings ...)
  2023-01-30  3:59           ` [PATCH v3 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
                             ` (2 subsequent siblings)
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang; +Cc: dev, rasland

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7a8516829c..4bdb46e89a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10925,6 +10925,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.next_hdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11027,6 +11034,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11181,6 +11191,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11201,6 +11212,18 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			if (!ext->hdr.hdr_len) {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.segments_left << 4);
+				ext->hdr.hdr_len = ext->hdr.segments_left << 1;
+			} else {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.hdr_len << 3);
+			}
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* [PATCH v3 6/8] ethdev: add modify IPv6 protocol field
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
                             ` (4 preceding siblings ...)
  2023-01-30  3:59           ` [PATCH v3 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko
  Cc: dev, rasland

Add IPv6 protocol modify field definition.

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 lib/ethdev/rte_flow.h       | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4bdb46e89a..1340cf3a9b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 9b9018cba2..f4797682b7 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3547,6 +3547,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [PATCH v3 7/8] net/mlx5: add modify IPv6 protocol implementation
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
                             ` (5 preceding siblings ...)
  2023-01-30  3:59           ` [PATCH v3 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  2023-01-30  3:59           ` [PATCH v3 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas; +Cc: dev, rasland

Add HWS modify IPv6 protocol implementation.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h  |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index ce6cd98fd7..497f2622b2 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -759,6 +759,7 @@ enum mlx5_modification_field {
 	MLX5_MODI_OUT_IP_ECN = 0x73,
 	MLX5_MODI_TUNNEL_HDR_DW_1 = 0x75,
 	MLX5_MODI_GTPU_FIRST_EXT_DW_0 = 0x76,
+	MLX5_MODI_OUT_IPV6_NEXT_HDR = 0x4A,
 };
 
 /* Total number of metadata reg_c's. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 7ca909999b..e972a2dc5a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1357,6 +1357,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
 	case RTE_FLOW_FIELD_IPV6_DSCP:
 		return 6;
 	case RTE_FLOW_FIELD_IPV6_HOPLIMIT:
+	case RTE_FLOW_FIELD_IPV6_PROTO:
 		return 8;
 	case RTE_FLOW_FIELD_IPV6_SRC:
 	case RTE_FLOW_FIELD_IPV6_DST:
@@ -1883,6 +1884,15 @@ mlx5_flow_field_id_to_modify_info
 				info[idx].offset = data->offset;
 		}
 		break;
+	case RTE_FLOW_FIELD_IPV6_PROTO:
+		MLX5_ASSERT(data->offset + width <= 8);
+		off_be = 8 - (data->offset + width);
+		info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IPV6_NEXT_HDR};
+		if (mask)
+			mask[idx] = flow_modify_info_mask_8(width, off_be);
+		else
+			info[idx].offset = off_be;
+		break;
 	case RTE_FLOW_FIELD_POINTER:
 	case RTE_FLOW_FIELD_VALUE:
 	default:
-- 
2.27.0


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

* [PATCH v3 8/8] doc/mlx5: add IPv6 routing extension matching docs
  2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
                             ` (6 preceding siblings ...)
  2023-01-30  3:59           ` [PATCH v3 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
@ 2023-01-30  3:59           ` Rongwei Liu
  7 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-30  3:59 UTC (permalink / raw)
  To: matan, viacheslavo, orika, thomas, Ferruh Yigit; +Cc: dev, rasland

Update mlx5 related document on IPv6 routing extension header
matching.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 doc/guides/nics/features/default.ini | 1 +
 doc/guides/nics/features/mlx5.ini    | 1 +
 doc/guides/nics/mlx5.rst             | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 510cc6679d..3d0744a243 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -141,6 +141,7 @@ udp                  =
 vlan                 =
 vxlan                =
 vxlan_gpe            =
+ipv6_routing_ext     =
 
 [rte_flow actions]
 age                  =
diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini
index 62fd330e2b..bd911a467b 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -87,6 +87,7 @@ vlan                 = Y
 vxlan                = Y
 vxlan_gpe            = Y
 represented_port     = Y
+ipv6_routing_ext     = Y
 
 [rte_flow actions]
 age                  = I
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index b23ca35b8f..fb8001faef 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -106,6 +106,7 @@ Features
 - Sub-Function representors.
 - Sub-Function.
 - Matching on represented port.
+- Matching on IPv6 routing extension header.
 
 
 Limitations
@@ -174,6 +175,7 @@ Limitations
 
     - ``-EAGAIN`` for ``rte_eth_dev_start()``.
     - ``-EBUSY`` for ``rte_eth_dev_stop()``.
+  - Matching on ICMP6 following IPv6 routing extension header, should match ipv6_routing_ext_next_hdr instead of ICMP6.
 
 - When using Verbs flow engine (``dv_flow_en`` = 0), flow pattern without any
   specific VLAN will match for VLAN packets as well:
-- 
2.27.0


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

* Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-30 16:47             ` Stephen Hemminger
  2023-01-31  2:03               ` Rongwei Liu
  2023-01-31  2:27               ` Rongwei Liu
  2023-01-30 16:50             ` Stephen Hemminger
  2023-01-31  3:02             ` Stephen Hemminger
  2 siblings, 2 replies; 67+ messages in thread
From: Stephen Hemminger @ 2023-01-30 16:47 UTC (permalink / raw)
  To: Rongwei Liu
  Cc: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz, dev, rasland

On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

>  
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t next_hdr;			/**< Protocol, next header. */
> +	uint8_t hdr_len;			/**< Header length. */
> +	uint8_t type;				/**< Extension header type. */
> +	uint8_t segments_left;			/**< Valid segments number. */
> +	__extension__
> +	union {
> +		rte_be32_t flags;
> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			rte_be16_t tag;		/**< Packet tag. */
> +		};
> +	};
> +	__extension__
> +	rte_be32_t segments[0];			/**< Each hop IPv6 address. */

Use flex array rather than zero size.
Zero size arrays cause warnings with later compilers.

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

* Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-30 16:47             ` Stephen Hemminger
@ 2023-01-30 16:50             ` Stephen Hemminger
  2023-01-31  2:05               ` Rongwei Liu
  2023-01-31  3:02             ` Stephen Hemminger
  2 siblings, 1 reply; 67+ messages in thread
From: Stephen Hemminger @ 2023-01-30 16:50 UTC (permalink / raw)
  To: Rongwei Liu
  Cc: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz, dev, rasland

On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

> +static size_t
> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)

> +{
> +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> +	size_t len;
> +
> +	if (src->hdr.hdr_len)
> +		len = src->hdr.hdr_len << 3;
> +	else
> +		len = src->hdr.segments_left << 4;
> +	if (dst == NULL)
> +		return 0;
> +	rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments, len);
> +	return len;

Why use rte_memcpy for such a small size? Please just use normal memcpy which
will cause more compiler and static scan checking.

That cast is unnecessary in C because "segments" is an array and any valid
pointer type can be passed as void *.

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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30 16:47             ` Stephen Hemminger
@ 2023-01-31  2:03               ` Rongwei Liu
  2023-01-31  2:27               ` Rongwei Liu
  1 sibling, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  2:03 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko,
	Olivier Matz, dev, Raslan Darawsheh

HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:48
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             rte_be32_t flags;
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     rte_be16_t tag;         /**< Packet tag. */
> > +             };
> > +     };
> > +     __extension__
> > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> 
> Use flex array rather than zero size.
> Zero size arrays cause warnings with later compilers.
Sure. Thanks.

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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30 16:50             ` Stephen Hemminger
@ 2023-01-31  2:05               ` Rongwei Liu
  0 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  2:05 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko,
	Olivier Matz, dev, Raslan Darawsheh

HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:50
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > +static size_t
> > +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
> 
> > +{
> > +     struct rte_flow_item_ipv6_routing_ext *dst = buf;
> > +     const struct rte_flow_item_ipv6_routing_ext *src = data;
> > +     size_t len;
> > +
> > +     if (src->hdr.hdr_len)
> > +             len = src->hdr.hdr_len << 3;
> > +     else
> > +             len = src->hdr.segments_left << 4;
> > +     if (dst == NULL)
> > +             return 0;
> > +     rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments,
> len);
> > +     return len;
> 
> Why use rte_memcpy for such a small size? Please just use normal memcpy
> which will cause more compiler and static scan checking.
> 
Following existing routine, rte_flow_item_***_conv(). Change to memcpy() in the next version
> That cast is unnecessary in C because "segments" is an array and any valid
> pointer type can be passed as void *.
Sure

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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30 16:47             ` Stephen Hemminger
  2023-01-31  2:03               ` Rongwei Liu
@ 2023-01-31  2:27               ` Rongwei Liu
  2023-01-31  2:55                 ` Stephen Hemminger
  1 sibling, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  2:27 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko,
	Olivier Matz, dev, Raslan Darawsheh

HI Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:48
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             rte_be32_t flags;
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     rte_be16_t tag;         /**< Packet tag. */
> > +             };
> > +     };
> > +     __extension__
> > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> 
> Use flex array rather than zero size.
> Zero size arrays cause warnings with later compilers.
Using flex array helps improve this network header definition but caused warning in the rte_flow_item_**
struct rte_flow_item_ipv6_routing_ext {
       struct rte_ipv6_routing_ext hdr;                                                                                                                                                                                                                    
}; 
"invalid use of structure with flexible array member [-Werror=pedantic]"

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

* Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  2:27               ` Rongwei Liu
@ 2023-01-31  2:55                 ` Stephen Hemminger
  2023-01-31  3:20                   ` Rongwei Liu
  0 siblings, 1 reply; 67+ messages in thread
From: Stephen Hemminger @ 2023-01-31  2:55 UTC (permalink / raw)
  To: Rongwei Liu
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko,
	Olivier Matz, dev, Raslan Darawsheh

On Tue, 31 Jan 2023 02:27:56 +0000
Rongwei Liu <rongweil@nvidia.com> wrote:

> HI Stephen
> 
> BR
> Rongwei
> 
> > -----Original Message-----
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Sent: Tuesday, January 31, 2023 00:48
> > To: Rongwei Liu <rongweil@nvidia.com>
> > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> > dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> > definition
> > 
> > External email: Use caution opening links or attachments
> > 
> > 
> > On Mon, 30 Jan 2023 05:59:33 +0200
> > Rongwei Liu <rongweil@nvidia.com> wrote:
> >   
> > >
> > > +/**
> > > + * IPv6 Routing Extension Header
> > > + */
> > > +struct rte_ipv6_routing_ext {
> > > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > > +     uint8_t hdr_len;                        /**< Header length. */
> > > +     uint8_t type;                           /**< Extension header type. */
> > > +     uint8_t segments_left;                  /**< Valid segments number. */
> > > +     __extension__
> > > +     union {
> > > +             rte_be32_t flags;
> > > +             struct {
> > > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > > +                     uint8_t flag;           /**< Packet flag. */
> > > +                     rte_be16_t tag;         /**< Packet tag. */
> > > +             };
> > > +     };
> > > +     __extension__
> > > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */  
> > 
> > Use flex array rather than zero size.
> > Zero size arrays cause warnings with later compilers.  
> Using flex array helps improve this network header definition but caused warning in the rte_flow_item_**
> struct rte_flow_item_ipv6_routing_ext {
>        struct rte_ipv6_routing_ext hdr;                                                                                                                                                                                                                    
> }; 
> "invalid use of structure with flexible array member [-Werror=pedantic]"

Not sure, only Nvidia/Mellanox messes with pedantic

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

* Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-30 16:47             ` Stephen Hemminger
  2023-01-30 16:50             ` Stephen Hemminger
@ 2023-01-31  3:02             ` Stephen Hemminger
  2023-01-31  3:24               ` Rongwei Liu
  2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
  2 siblings, 2 replies; 67+ messages in thread
From: Stephen Hemminger @ 2023-01-31  3:02 UTC (permalink / raw)
  To: Rongwei Liu
  Cc: matan, viacheslavo, orika, thomas, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Andrew Rybchenko, Olivier Matz, dev, rasland

On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> + *
> + * Matches an IPv6 routing extension header.
> + */
> +struct rte_flow_item_ipv6_routing_ext {
> +	struct rte_ipv6_routing_ext hdr;
> +};

The problem with nesting a variable length structure inside
another structure is not allowed.

The issue is that the applicaiton would have to pass a variable
length structure in for the flow definition. The flow item is
variable length for this type? all the others are fixed length.

One option would be to get rid of the wrapper structure.

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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  2:55                 ` Stephen Hemminger
@ 2023-01-31  3:20                   ` Rongwei Liu
  0 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  3:20 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko,
	Olivier Matz, dev, Raslan Darawsheh

HI Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 10:56
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Tue, 31 Jan 2023 02:27:56 +0000
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > HI Stephen
> >
> > BR
> > Rongwei
> >
> > > -----Original Message-----
> > > From: Stephen Hemminger <stephen@networkplumber.org>
> > > Sent: Tuesday, January 31, 2023 00:48
> > > To: Rongwei Liu <rongweil@nvidia.com>
> > > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz
> > > <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> > > <rasland@nvidia.com>
> > > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension
> > > header definition
> > >
> > > External email: Use caution opening links or attachments
> > >
> > >
> > > On Mon, 30 Jan 2023 05:59:33 +0200
> > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > >
> > > >
> > > > +/**
> > > > + * IPv6 Routing Extension Header
> > > > + */
> > > > +struct rte_ipv6_routing_ext {
> > > > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > > > +     uint8_t hdr_len;                        /**< Header length. */
> > > > +     uint8_t type;                           /**< Extension header type. */
> > > > +     uint8_t segments_left;                  /**< Valid segments number. */
> > > > +     __extension__
> > > > +     union {
> > > > +             rte_be32_t flags;
> > > > +             struct {
> > > > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > > > +                     uint8_t flag;           /**< Packet flag. */
> > > > +                     rte_be16_t tag;         /**< Packet tag. */
> > > > +             };
> > > > +     };
> > > > +     __extension__
> > > > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> > >
> > > Use flex array rather than zero size.
> > > Zero size arrays cause warnings with later compilers.
> > Using flex array helps improve this network header definition but
> > caused warning in the rte_flow_item_** struct
> rte_flow_item_ipv6_routing_ext {
> >        struct rte_ipv6_routing_ext hdr; }; "invalid use of structure
> > with flexible array member [-Werror=pedantic]"
> 
> Not sure, only Nvidia/Mellanox messes with pedantic
This is caused by failsafe driver.
In file included from ../drivers/net/failsafe/failsafe_ether.c:8:
../lib/ethdev/rte_flow.h:892:44: error: invalid use of structure with flexible array member [-Werror=pedantic]
  __extension__ struct rte_ipv6_routing_ext hdr;
                                            ^~~

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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  3:02             ` Stephen Hemminger
@ 2023-01-31  3:24               ` Rongwei Liu
  2023-01-31  9:18                 ` Rongwei Liu
  2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
  1 sibling, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  3:24 UTC (permalink / raw)
  To: Stephen Hemminger, Andrew Rybchenko
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz, dev,
	Raslan Darawsheh

Hi Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 11:02
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + *
> > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > + *
> > + * Matches an IPv6 routing extension header.
> > + */
> > +struct rte_flow_item_ipv6_routing_ext {
> > +     struct rte_ipv6_routing_ext hdr; };
> 
> The problem with nesting a variable length structure inside another structure
> is not allowed.
> 
> The issue is that the applicaiton would have to pass a variable length structure
> in for the flow definition. The flow item is variable length for this type? all the
> others are fixed length.
> 
Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
It stands for intermediate routing nodes between src and dst nodes.
> One option would be to get rid of the wrapper structure.
Yeah, it works. @Andrew Rybchenko  Can you share your preference here?


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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  3:24               ` Rongwei Liu
@ 2023-01-31  9:18                 ` Rongwei Liu
  2023-01-31  9:42                   ` Thomas Monjalon
  0 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  9:18 UTC (permalink / raw)
  To: Stephen Hemminger, Andrew Rybchenko
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz, dev,
	Raslan Darawsheh

HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Rongwei Liu
> Sent: Tuesday, January 31, 2023 11:25
> To: Stephen Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Olivier Matz
> <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> <rasland@nvidia.com>
> Subject: RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> Hi Stephen
> 
> BR
> Rongwei
> 
> > -----Original Message-----
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Sent: Tuesday, January 31, 2023 11:02
> > To: Rongwei Liu <rongweil@nvidia.com>
> > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz
> > <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> > <rasland@nvidia.com>
> > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> > definition
> >
> > External email: Use caution opening links or attachments
> >
> >
> > On Mon, 30 Jan 2023 05:59:33 +0200
> > Rongwei Liu <rongweil@nvidia.com> wrote:
> >
> > > +/**
> > > + * @warning
> > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > + *
> > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > + *
> > > + * Matches an IPv6 routing extension header.
> > > + */
> > > +struct rte_flow_item_ipv6_routing_ext {
> > > +     struct rte_ipv6_routing_ext hdr; };
> >
> > The problem with nesting a variable length structure inside another
> > structure is not allowed.
> >
> > The issue is that the applicaiton would have to pass a variable length
> > structure in for the flow definition. The flow item is variable length
> > for this type? all the others are fixed length.
> >
> Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
> It stands for intermediate routing nodes between src and dst nodes.
> > One option would be to get rid of the wrapper structure.
> Yeah, it works. @Andrew Rybchenko  Can you share your preference here?
I want to propose "moving flex array" out of the "struct rte_ipv6_routing_ext " and present in " struct rte_flow_item_ipv6_routing_ext"
Sounds good?

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

* [PATCH v4 0/3]  add IPv6 routing extension support
  2023-01-31  3:02             ` Stephen Hemminger
  2023-01-31  3:24               ` Rongwei Liu
@ 2023-01-31  9:36               ` Rongwei Liu
  2023-01-31  9:36                 ` [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
                                   ` (2 more replies)
  1 sibling, 3 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  9:36 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland

Support IPv6 routing extension header matching with new rte_flow item.
Add encapsulation support for IPv6 routing extension header.

v4: use flex array to define variable length segments and move PMD
    implementation out.
v3: enhance the format and use be32/be16 in network header structure.
v2: remove redundant rte_flow items.

Rongwei Liu (3):
  ethdev: add IPv6 routing extension header definition
  ethdev: add modify IPv6 protocol field
  app/testpmd: add IPv6 routing extension header in raw encap

 app/test-pmd/cmdline_flow.c            | 72 +++++++++++++++++++++++++-
 doc/guides/prog_guide/rte_flow.rst     |  9 ++++
 doc/guides/rel_notes/release_23_03.rst |  9 ++++
 lib/ethdev/rte_flow.c                  | 19 +++++++
 lib/ethdev/rte_flow.h                  | 22 ++++++++
 lib/net/rte_ip.h                       | 19 +++++++
 6 files changed, 149 insertions(+), 1 deletion(-)

-- 
2.27.0


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

* [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition
  2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
@ 2023-01-31  9:36                 ` Rongwei Liu
  2023-02-01  9:21                   ` Andrew Rybchenko
  2023-01-31  9:36                 ` [PATCH v4 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
  2023-01-31  9:36                 ` [PATCH v4 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
  2 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  9:36 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit,
	Andrew Rybchenko, Olivier Matz

Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst |  9 +++++
 lib/ethdev/rte_flow.c                  | 19 +++++++++++
 lib/ethdev/rte_flow.h                  | 21 ++++++++++++
 lib/net/rte_ip.h                       | 19 +++++++++++
 6 files changed, 123 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..602fab29d3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches IPv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..1337da73b8 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,11 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header.
+
 
 Removed Items
 -------------
@@ -98,6 +103,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* net: added a new structure:
+
+    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..833382c466 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -76,6 +76,23 @@ rte_flow_item_flex_conv(void *buf, const void *data)
 	return src->length;
 }
 
+static size_t
+rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
+{
+	struct rte_flow_item_ipv6_routing_ext *dst = buf;
+	const struct rte_flow_item_ipv6_routing_ext *src = data;
+	size_t len;
+
+	if (src->hdr.hdr_len)
+		len = src->hdr.hdr_len << 3;
+	else
+		len = src->hdr.segments_left << 4;
+	if (dst == NULL)
+		return 0;
+	memcpy(dst->segments, src->segments, len);
+	return len;
+}
+
 /** Generate flow_item[] entry. */
 #define MK_FLOW_ITEM(t, s) \
 	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
@@ -157,6 +174,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
+			rte_flow_item_ipv6_routing_ext_conv),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..ff9270690c 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * @see struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,20 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+	__extension__
+	rte_be32_t segments[]; /**< Each hop IPv6 address. */
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..778fb5ef83 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,25 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		rte_be32_t flags;
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			rte_be16_t tag;		/**< Packet tag. */
+		};
+	};
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [PATCH v4 2/3] ethdev: add modify IPv6 protocol field
  2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
  2023-01-31  9:36                 ` [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-01-31  9:36                 ` Rongwei Liu
  2023-02-01  9:14                   ` Andrew Rybchenko
  2023-01-31  9:36                 ` [PATCH v4 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
  2 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  9:36 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko

Add IPv6 protocol modify field definition.

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 lib/ethdev/rte_flow.h       | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7a8516829c..b8156ebca2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index ff9270690c..70b910b73a 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3549,6 +3549,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [PATCH v4 3/3] app/testpmd: add IPv6 routing extension header in raw encap
  2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
  2023-01-31  9:36                 ` [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-01-31  9:36                 ` [PATCH v4 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-01-31  9:36                 ` Rongwei Liu
  2 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-01-31  9:36 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland, Aman Singh, Yuying Zhang

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index b8156ebca2..1340cf3a9b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10926,6 +10926,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.next_hdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11028,6 +11035,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11182,6 +11192,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11202,6 +11213,18 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			if (!ext->hdr.hdr_len) {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.segments_left << 4);
+				ext->hdr.hdr_len = ext->hdr.segments_left << 1;
+			} else {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.hdr_len << 3);
+			}
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  9:18                 ` Rongwei Liu
@ 2023-01-31  9:42                   ` Thomas Monjalon
  2023-01-31 11:42                     ` Ori Kam
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2023-01-31  9:42 UTC (permalink / raw)
  To: Stephen Hemminger, Andrew Rybchenko, Rongwei Liu
  Cc: Matan Azrad, Slava Ovsiienko, Ori Kam, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Olivier Matz, dev, Raslan Darawsheh

31/01/2023 10:18, Rongwei Liu:
> From: Rongwei Liu
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > >
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > > + *
> > > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > > + *
> > > > + * Matches an IPv6 routing extension header.
> > > > + */
> > > > +struct rte_flow_item_ipv6_routing_ext {
> > > > +     struct rte_ipv6_routing_ext hdr; };
> > >
> > > The problem with nesting a variable length structure inside another
> > > structure is not allowed.
> > >
> > > The issue is that the applicaiton would have to pass a variable length
> > > structure in for the flow definition. The flow item is variable length
> > > for this type? all the others are fixed length.
> > >
> > Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
> > It stands for intermediate routing nodes between src and dst nodes.
> > > One option would be to get rid of the wrapper structure.
> > Yeah, it works. @Andrew Rybchenko  Can you share your preference here?
> I want to propose "moving flex array" out of the "struct rte_ipv6_routing_ext " and present in " struct rte_flow_item_ipv6_routing_ext"
> Sounds good?

For Geneve, we have defined a separate flow item: rte_flow_item_geneve_opt.
I'm OK to move the optional fields in the flow item.
This is what you did in v4.






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

* RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition
  2023-01-31  9:42                   ` Thomas Monjalon
@ 2023-01-31 11:42                     ` Ori Kam
  0 siblings, 0 replies; 67+ messages in thread
From: Ori Kam @ 2023-01-31 11:42 UTC (permalink / raw)
  To: NBU-Contact-Thomas Monjalon (EXTERNAL),
	Stephen Hemminger, Andrew Rybchenko, Rongwei Liu
  Cc: Matan Azrad, Slava Ovsiienko, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Olivier Matz, dev, Raslan Darawsheh



> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, 31 January 2023 11:43
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> 31/01/2023 10:18, Rongwei Liu:
> > From: Rongwei Liu
> > > From: Stephen Hemminger <stephen@networkplumber.org>
> > > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > > >
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > > > + *
> > > > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > > > + *
> > > > > + * Matches an IPv6 routing extension header.
> > > > > + */
> > > > > +struct rte_flow_item_ipv6_routing_ext {
> > > > > +     struct rte_ipv6_routing_ext hdr; };
> > > >
> > > > The problem with nesting a variable length structure inside another
> > > > structure is not allowed.
> > > >
> > > > The issue is that the applicaiton would have to pass a variable length
> > > > structure in for the flow definition. The flow item is variable length
> > > > for this type? all the others are fixed length.
> > > >
> > > Yeah, segments_left is uint8 per definition. RFC doesn't set an upper
> limitation.
> > > It stands for intermediate routing nodes between src and dst nodes.
> > > > One option would be to get rid of the wrapper structure.
> > > Yeah, it works. @Andrew Rybchenko  Can you share your preference
> here?
> > I want to propose "moving flex array" out of the "struct
> rte_ipv6_routing_ext " and present in " struct
> rte_flow_item_ipv6_routing_ext"
> > Sounds good?
> 
> For Geneve, we have defined a separate flow item:
> rte_flow_item_geneve_opt.
> I'm OK to move the optional fields in the flow item.
> This is what you did in v4.
> 

I also think we should just drop the  rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
In any case application must allocate the correct size so maybe we can just remove it.

Best,
Ori
> 
> 
> 


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

* Re: [PATCH v4 2/3] ethdev: add modify IPv6 protocol field
  2023-01-31  9:36                 ` [PATCH v4 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-02-01  9:14                   ` Andrew Rybchenko
  0 siblings, 0 replies; 67+ messages in thread
From: Andrew Rybchenko @ 2023-02-01  9:14 UTC (permalink / raw)
  To: Rongwei Liu, dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit

On 1/31/23 12:36, Rongwei Liu wrote:
> Add IPv6 protocol modify field definition.
> 
> Add new modify field destination type string: "ipv6_proto".
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>



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

* Re: [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition
  2023-01-31  9:36                 ` [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-02-01  9:21                   ` Andrew Rybchenko
  2023-02-01  9:27                     ` Rongwei Liu
  0 siblings, 1 reply; 67+ messages in thread
From: Andrew Rybchenko @ 2023-02-01  9:21 UTC (permalink / raw)
  To: Rongwei Liu, dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz

On 1/31/23 12:36, Rongwei Liu wrote:
> Add IPv6 routing extension header definition and no
> TLV support for now.
> 
> At rte_flow layer, there are new items defined for matching
> type/nexthdr/segments_left field.
> 
> Add command line support for IPv6 routing extension header
> matching: type/nexthdr/segment_list.
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>
> ---
>   app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
>   doc/guides/prog_guide/rte_flow.rst     |  9 +++++
>   doc/guides/rel_notes/release_23_03.rst |  9 +++++
>   lib/ethdev/rte_flow.c                  | 19 +++++++++++
>   lib/ethdev/rte_flow.h                  | 21 ++++++++++++
>   lib/net/rte_ip.h                       | 19 +++++++++++
>   6 files changed, 123 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 88108498e0..7a8516829c 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -298,6 +298,10 @@ enum index {
>   	ITEM_IPV6_SRC,
>   	ITEM_IPV6_DST,
>   	ITEM_IPV6_HAS_FRAG_EXT,
> +	ITEM_IPV6_ROUTING_EXT,
> +	ITEM_IPV6_ROUTING_EXT_TYPE,
> +	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
> +	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
>   	ITEM_ICMP,
>   	ITEM_ICMP_TYPE,
>   	ITEM_ICMP_CODE,
> @@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
>   	ITEM_ARP_ETH_IPV4,
>   	ITEM_IPV6_EXT,
>   	ITEM_IPV6_FRAG_EXT,
> +	ITEM_IPV6_ROUTING_EXT,
>   	ITEM_ICMP6,
>   	ITEM_ICMP6_ND_NS,
>   	ITEM_ICMP6_ND_NA,
> @@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
>   	ITEM_IPV6_SRC,
>   	ITEM_IPV6_DST,
>   	ITEM_IPV6_HAS_FRAG_EXT,
> +	ITEM_IPV6_ROUTING_EXT,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index item_ipv6_routing_ext[] = {
> +	ITEM_IPV6_ROUTING_EXT_TYPE,
> +	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
> +	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
>   	ITEM_NEXT,
>   	ZERO,
>   };
> @@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
>   		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
>   					   has_frag_ext, 1)),
>   	},
> +	[ITEM_IPV6_ROUTING_EXT] = {
> +		.name = "ipv6_routing_ext",
> +		.help = "match IPv6 routing extension header",
> +		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
> +				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
> +		.next = NEXT(item_ipv6_routing_ext),
> +		.call = parse_vc,
> +	},
> +	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
> +		.name = "ext_type",
> +		.help = "match IPv6 routing extension header type",
> +		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
> +					     hdr.type)),
> +	},
> +	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
> +		.name = "ext_next_hdr",
> +		.help = "match IPv6 routing extension header next header type",
> +		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
> +					     hdr.next_hdr)),
> +	},
> +	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
> +		.name = "ext_seg_left",
> +		.help = "match IPv6 routing extension header segment left",
> +		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
> +					     hdr.segments_left)),
> +	},
>   	[ITEM_ICMP] = {
>   		.name = "icmp",
>   		.help = "match ICMP header",
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index 3e6242803d..602fab29d3 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
>   
>   - ``color``: Metering color marker.
>   
> +Item: ``IPV6_ROUTING_EXT``
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches IPv6 routing extension header.
> +
> +- ``next_hdr``: Next layer header type.
> +- ``type``: IPv6 routing extension header type.
> +- ``segments_left``: How many IPv6 destination addresses carries on.
> +
>   Actions
>   ~~~~~~~
>   
> diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
> index c15f6fbb9f..1337da73b8 100644
> --- a/doc/guides/rel_notes/release_23_03.rst
> +++ b/doc/guides/rel_notes/release_23_03.rst
> @@ -69,6 +69,11 @@ New Features
>       ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
>       required for eth_rx, eth_tx, crypto and timer eventdev adapters.
>   
> +* **Added rte_flow support for matching IPv6 routing extension header fields.**
> +
> +  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
> +  header.
> +
>   
>   Removed Items
>   -------------
> @@ -98,6 +103,10 @@ API Changes
>      Also, make sure to start the actual text at the margin.
>      =======================================================
>   
> +* net: added a new structure:
> +
> +    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
> +
>   
>   ABI Changes
>   -----------
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 7d0c24366c..833382c466 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -76,6 +76,23 @@ rte_flow_item_flex_conv(void *buf, const void *data)
>   	return src->length;
>   }
>   
> +static size_t
> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
> +{
> +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> +	size_t len;
> +
> +	if (src->hdr.hdr_len)

Please, compare vs 0

> +		len = src->hdr.hdr_len << 3;
> +	else
> +		len = src->hdr.segments_left << 4;
> +	if (dst == NULL)
> +		return 0;
> +	memcpy(dst->segments, src->segments, len);
> +	return len;
> +}
> +
>   /** Generate flow_item[] entry. */
>   #define MK_FLOW_ITEM(t, s) \
>   	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
> @@ -157,6 +174,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>   	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>   	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>   	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
> +	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
> +			rte_flow_item_ipv6_routing_ext_conv),
>   };
>   
>   /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index b60987db4b..ff9270690c 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -624,6 +624,13 @@ enum rte_flow_item_type {
>   	 * See struct rte_flow_item_meter_color.
>   	 */
>   	RTE_FLOW_ITEM_TYPE_METER_COLOR,
> +
> +	/**
> +	 * Matches the presence of IPv6 routing extension header.
> +	 *
> +	 * @see struct rte_flow_item_ipv6_routing_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
>   };
>   
>   /**
> @@ -873,6 +880,20 @@ struct rte_flow_item_ipv6 {
>   	uint32_t reserved:23;
>   };
>   
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> + *
> + * Matches an IPv6 routing extension header.
> + */
> +struct rte_flow_item_ipv6_routing_ext {
> +	struct rte_ipv6_routing_ext hdr;
> +	__extension__
> +	rte_be32_t segments[]; /**< Each hop IPv6 address. */

Do we really need it? Are you going to support it?
Will testpmd and flow conf work correctly since it uses size of
the structure?

IMHO we should just remove it right now if we're not going to
support it.

> +};
> +
>   /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
>   #ifndef __cplusplus
>   static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
> index 9c8e8206f0..778fb5ef83 100644
> --- a/lib/net/rte_ip.h
> +++ b/lib/net/rte_ip.h
> @@ -539,6 +539,25 @@ struct rte_ipv6_hdr {
>   	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
>   } __rte_packed;
>   
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t next_hdr;			/**< Protocol, next header. */
> +	uint8_t hdr_len;			/**< Header length. */
> +	uint8_t type;				/**< Extension header type. */
> +	uint8_t segments_left;			/**< Valid segments number. */
> +	__extension__
> +	union {
> +		rte_be32_t flags;

flags should be documented as well.

> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			rte_be16_t tag;		/**< Packet tag. */
> +		};
> +	};

May be we should add a comment here that segments follow?

> +} __rte_packed;
> +
>   /* IPv6 vtc_flow: IPv / TC / flow_label */
>   #define RTE_IPV6_HDR_FL_SHIFT 0
>   #define RTE_IPV6_HDR_TC_SHIFT 20


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

* RE: [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-01  9:21                   ` Andrew Rybchenko
@ 2023-02-01  9:27                     ` Rongwei Liu
  2023-02-01  9:31                       ` Andrew Rybchenko
  0 siblings, 1 reply; 67+ messages in thread
From: Rongwei Liu @ 2023-02-01  9:27 UTC (permalink / raw)
  To: Andrew Rybchenko, dev, Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: Raslan Darawsheh, Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz

HI Andrew:

BR
Rongwei

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Wednesday, February 1, 2023 17:21
> To: Rongwei Liu <rongweil@nvidia.com>; dev@dpdk.org; Matan Azrad
> <matan@nvidia.com>; Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam
> <orika@nvidia.com>; NBU-Contact-Thomas Monjalon (EXTERNAL)
> <thomas@monjalon.net>
> Cc: Raslan Darawsheh <rasland@nvidia.com>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Olivier Matz <olivier.matz@6wind.com>
> Subject: Re: [PATCH v4 1/3] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On 1/31/23 12:36, Rongwei Liu wrote:
> > Add IPv6 routing extension header definition and no TLV support for
> > now.
> >
> > At rte_flow layer, there are new items defined for matching
> > type/nexthdr/segments_left field.
> >
> > Add command line support for IPv6 routing extension header
> > matching: type/nexthdr/segment_list.
> >
> > Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> > Acked-by: Ori Kam <orika@nvidia.com>
> > ---
> >   app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
> >   doc/guides/prog_guide/rte_flow.rst     |  9 +++++
> >   doc/guides/rel_notes/release_23_03.rst |  9 +++++
> >   lib/ethdev/rte_flow.c                  | 19 +++++++++++
> >   lib/ethdev/rte_flow.h                  | 21 ++++++++++++
> >   lib/net/rte_ip.h                       | 19 +++++++++++
> >   6 files changed, 123 insertions(+)
> >
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index 88108498e0..7a8516829c 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -298,6 +298,10 @@ enum index {
> >       ITEM_IPV6_SRC,
> >       ITEM_IPV6_DST,
> >       ITEM_IPV6_HAS_FRAG_EXT,
> > +     ITEM_IPV6_ROUTING_EXT,
> > +     ITEM_IPV6_ROUTING_EXT_TYPE,
> > +     ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
> > +     ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
> >       ITEM_ICMP,
> >       ITEM_ICMP_TYPE,
> >       ITEM_ICMP_CODE,
> > @@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
> >       ITEM_ARP_ETH_IPV4,
> >       ITEM_IPV6_EXT,
> >       ITEM_IPV6_FRAG_EXT,
> > +     ITEM_IPV6_ROUTING_EXT,
> >       ITEM_ICMP6,
> >       ITEM_ICMP6_ND_NS,
> >       ITEM_ICMP6_ND_NA,
> > @@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
> >       ITEM_IPV6_SRC,
> >       ITEM_IPV6_DST,
> >       ITEM_IPV6_HAS_FRAG_EXT,
> > +     ITEM_IPV6_ROUTING_EXT,
> > +     ITEM_NEXT,
> > +     ZERO,
> > +};
> > +
> > +static const enum index item_ipv6_routing_ext[] = {
> > +     ITEM_IPV6_ROUTING_EXT_TYPE,
> > +     ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
> > +     ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
> >       ITEM_NEXT,
> >       ZERO,
> >   };
> > @@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
> >               .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
> >                                          has_frag_ext, 1)),
> >       },
> > +     [ITEM_IPV6_ROUTING_EXT] = {
> > +             .name = "ipv6_routing_ext",
> > +             .help = "match IPv6 routing extension header",
> > +             .priv = PRIV_ITEM(IPV6_ROUTING_EXT,
> > +                               sizeof(struct rte_flow_item_ipv6_routing_ext)),
> > +             .next = NEXT(item_ipv6_routing_ext),
> > +             .call = parse_vc,
> > +     },
> > +     [ITEM_IPV6_ROUTING_EXT_TYPE] = {
> > +             .name = "ext_type",
> > +             .help = "match IPv6 routing extension header type",
> > +             .next = NEXT(item_ipv6_routing_ext,
> NEXT_ENTRY(COMMON_UNSIGNED),
> > +                          item_param),
> > +             .args = ARGS(ARGS_ENTRY_HTON(struct
> rte_flow_item_ipv6_routing_ext,
> > +                                          hdr.type)),
> > +     },
> > +     [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
> > +             .name = "ext_next_hdr",
> > +             .help = "match IPv6 routing extension header next header type",
> > +             .next = NEXT(item_ipv6_routing_ext,
> NEXT_ENTRY(COMMON_UNSIGNED),
> > +                          item_param),
> > +             .args = ARGS(ARGS_ENTRY_HTON(struct
> rte_flow_item_ipv6_routing_ext,
> > +                                          hdr.next_hdr)),
> > +     },
> > +     [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
> > +             .name = "ext_seg_left",
> > +             .help = "match IPv6 routing extension header segment left",
> > +             .next = NEXT(item_ipv6_routing_ext,
> NEXT_ENTRY(COMMON_UNSIGNED),
> > +                          item_param),
> > +             .args = ARGS(ARGS_ENTRY_HTON(struct
> rte_flow_item_ipv6_routing_ext,
> > +                                          hdr.segments_left)),
> > +     },
> >       [ITEM_ICMP] = {
> >               .name = "icmp",
> >               .help = "match ICMP header", diff --git
> > a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index 3e6242803d..602fab29d3 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
> >
> >   - ``color``: Metering color marker.
> >
> > +Item: ``IPV6_ROUTING_EXT``
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches IPv6 routing extension header.
> > +
> > +- ``next_hdr``: Next layer header type.
> > +- ``type``: IPv6 routing extension header type.
> > +- ``segments_left``: How many IPv6 destination addresses carries on.
> > +
> >   Actions
> >   ~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_23_03.rst
> > b/doc/guides/rel_notes/release_23_03.rst
> > index c15f6fbb9f..1337da73b8 100644
> > --- a/doc/guides/rel_notes/release_23_03.rst
> > +++ b/doc/guides/rel_notes/release_23_03.rst
> > @@ -69,6 +69,11 @@ New Features
> >       ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
> >       required for eth_rx, eth_tx, crypto and timer eventdev adapters.
> >
> > +* **Added rte_flow support for matching IPv6 routing extension header
> > +fields.**
> > +
> > +  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing
> > + extension  header.
> > +
> >
> >   Removed Items
> >   -------------
> > @@ -98,6 +103,10 @@ API Changes
> >      Also, make sure to start the actual text at the margin.
> >      =======================================================
> >
> > +* net: added a new structure:
> > +
> > +    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
> > +
> >
> >   ABI Changes
> >   -----------
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> > 7d0c24366c..833382c466 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -76,6 +76,23 @@ rte_flow_item_flex_conv(void *buf, const void *data)
> >       return src->length;
> >   }
> >
> > +static size_t
> > +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data) {
> > +     struct rte_flow_item_ipv6_routing_ext *dst = buf;
> > +     const struct rte_flow_item_ipv6_routing_ext *src = data;
> > +     size_t len;
> > +
> > +     if (src->hdr.hdr_len)
> 
> Please, compare vs 0
> 
> > +             len = src->hdr.hdr_len << 3;
> > +     else
> > +             len = src->hdr.segments_left << 4;
> > +     if (dst == NULL)
> > +             return 0;
> > +     memcpy(dst->segments, src->segments, len);
> > +     return len;
> > +}
> > +
> >   /** Generate flow_item[] entry. */
> >   #define MK_FLOW_ITEM(t, s) \
> >       [RTE_FLOW_ITEM_TYPE_ ## t] = { \ @@ -157,6 +174,8 @@ static
> > const struct rte_flow_desc_data rte_flow_desc_item[] = {
> >       MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> >       MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >       MK_FLOW_ITEM(METER_COLOR, sizeof(struct
> > rte_flow_item_meter_color)),
> > +     MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct
> rte_flow_item_ipv6_routing_ext),
> > +                     rte_flow_item_ipv6_routing_ext_conv),
> >   };
> >
> >   /** Generate flow_action[] entry. */ diff --git
> > a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > b60987db4b..ff9270690c 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -624,6 +624,13 @@ enum rte_flow_item_type {
> >        * See struct rte_flow_item_meter_color.
> >        */
> >       RTE_FLOW_ITEM_TYPE_METER_COLOR,
> > +
> > +     /**
> > +      * Matches the presence of IPv6 routing extension header.
> > +      *
> > +      * @see struct rte_flow_item_ipv6_routing_ext.
> > +      */
> > +     RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
> >   };
> >
> >   /**
> > @@ -873,6 +880,20 @@ struct rte_flow_item_ipv6 {
> >       uint32_t reserved:23;
> >   };
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + *
> > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > + *
> > + * Matches an IPv6 routing extension header.
> > + */
> > +struct rte_flow_item_ipv6_routing_ext {
> > +     struct rte_ipv6_routing_ext hdr;
> > +     __extension__
> > +     rte_be32_t segments[]; /**< Each hop IPv6 address. */
> 
> Do we really need it? Are you going to support it?
> Will testpmd and flow conf work correctly since it uses size of the structure?
> 
In the rte_flow.c and testpmd raw_encap() function, it relies on the hdr_len or segment_left fild not sizeof this structure.
> IMHO we should just remove it right now if we're not going to support it.
> 
In matching, we don't support segments field. I am ok to remove it. 
> > +};
> > +
> >   /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
> >   #ifndef __cplusplus
> >   static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
> > diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h index
> > 9c8e8206f0..778fb5ef83 100644
> > --- a/lib/net/rte_ip.h
> > +++ b/lib/net/rte_ip.h
> > @@ -539,6 +539,25 @@ struct rte_ipv6_hdr {
> >       uint8_t  dst_addr[16];  /**< IP address of destination host(s). */
> >   } __rte_packed;
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             rte_be32_t flags;
> 
> flags should be documented as well.
Sure.
> 
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     rte_be16_t tag;         /**< Packet tag. */
> > +             };
> > +     };
> 
> May be we should add a comment here that segments follow?
Sure.
> 
> > +} __rte_packed;
> > +
> >   /* IPv6 vtc_flow: IPv / TC / flow_label */
> >   #define RTE_IPV6_HDR_FL_SHIFT 0
> >   #define RTE_IPV6_HDR_TC_SHIFT 20


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

* Re: [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-01  9:27                     ` Rongwei Liu
@ 2023-02-01  9:31                       ` Andrew Rybchenko
  2023-02-01 11:35                         ` [PATCH v5 0/3] add IPv6 routing extension support Rongwei Liu
  0 siblings, 1 reply; 67+ messages in thread
From: Andrew Rybchenko @ 2023-02-01  9:31 UTC (permalink / raw)
  To: Rongwei Liu, dev, Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: Raslan Darawsheh, Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz

On 2/1/23 12:27, Rongwei Liu wrote:
> HI Andrew:
> 
> BR
> Rongwei
> 
>> -----Original Message-----
>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Sent: Wednesday, February 1, 2023 17:21
>> To: Rongwei Liu <rongweil@nvidia.com>; dev@dpdk.org; Matan Azrad
>> <matan@nvidia.com>; Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam
>> <orika@nvidia.com>; NBU-Contact-Thomas Monjalon (EXTERNAL)
>> <thomas@monjalon.net>
>> Cc: Raslan Darawsheh <rasland@nvidia.com>; Aman Singh
>> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
>> Ferruh Yigit <ferruh.yigit@amd.com>; Olivier Matz <olivier.matz@6wind.com>
>> Subject: Re: [PATCH v4 1/3] ethdev: add IPv6 routing extension header
>> definition
>>
>> External email: Use caution opening links or attachments
>>
>>
>> On 1/31/23 12:36, Rongwei Liu wrote:
>>> Add IPv6 routing extension header definition and no TLV support for
>>> now.
>>>
>>> At rte_flow layer, there are new items defined for matching
>>> type/nexthdr/segments_left field.
>>>
>>> Add command line support for IPv6 routing extension header
>>> matching: type/nexthdr/segment_list.
>>>
>>> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
>>> Acked-by: Ori Kam <orika@nvidia.com>
>>> ---
>>>    app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
>>>    doc/guides/prog_guide/rte_flow.rst     |  9 +++++
>>>    doc/guides/rel_notes/release_23_03.rst |  9 +++++
>>>    lib/ethdev/rte_flow.c                  | 19 +++++++++++
>>>    lib/ethdev/rte_flow.h                  | 21 ++++++++++++
>>>    lib/net/rte_ip.h                       | 19 +++++++++++
>>>    6 files changed, 123 insertions(+)
>>>
>>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
>>> index 88108498e0..7a8516829c 100644
>>> --- a/app/test-pmd/cmdline_flow.c
>>> +++ b/app/test-pmd/cmdline_flow.c
>>> @@ -298,6 +298,10 @@ enum index {
>>>        ITEM_IPV6_SRC,
>>>        ITEM_IPV6_DST,
>>>        ITEM_IPV6_HAS_FRAG_EXT,
>>> +     ITEM_IPV6_ROUTING_EXT,
>>> +     ITEM_IPV6_ROUTING_EXT_TYPE,
>>> +     ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
>>> +     ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
>>>        ITEM_ICMP,
>>>        ITEM_ICMP_TYPE,
>>>        ITEM_ICMP_CODE,
>>> @@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
>>>        ITEM_ARP_ETH_IPV4,
>>>        ITEM_IPV6_EXT,
>>>        ITEM_IPV6_FRAG_EXT,
>>> +     ITEM_IPV6_ROUTING_EXT,
>>>        ITEM_ICMP6,
>>>        ITEM_ICMP6_ND_NS,
>>>        ITEM_ICMP6_ND_NA,
>>> @@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
>>>        ITEM_IPV6_SRC,
>>>        ITEM_IPV6_DST,
>>>        ITEM_IPV6_HAS_FRAG_EXT,
>>> +     ITEM_IPV6_ROUTING_EXT,
>>> +     ITEM_NEXT,
>>> +     ZERO,
>>> +};
>>> +
>>> +static const enum index item_ipv6_routing_ext[] = {
>>> +     ITEM_IPV6_ROUTING_EXT_TYPE,
>>> +     ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
>>> +     ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
>>>        ITEM_NEXT,
>>>        ZERO,
>>>    };
>>> @@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
>>>                .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
>>>                                           has_frag_ext, 1)),
>>>        },
>>> +     [ITEM_IPV6_ROUTING_EXT] = {
>>> +             .name = "ipv6_routing_ext",
>>> +             .help = "match IPv6 routing extension header",
>>> +             .priv = PRIV_ITEM(IPV6_ROUTING_EXT,
>>> +                               sizeof(struct rte_flow_item_ipv6_routing_ext)),
>>> +             .next = NEXT(item_ipv6_routing_ext),
>>> +             .call = parse_vc,
>>> +     },
>>> +     [ITEM_IPV6_ROUTING_EXT_TYPE] = {
>>> +             .name = "ext_type",
>>> +             .help = "match IPv6 routing extension header type",
>>> +             .next = NEXT(item_ipv6_routing_ext,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>>> +                          item_param),
>>> +             .args = ARGS(ARGS_ENTRY_HTON(struct
>> rte_flow_item_ipv6_routing_ext,
>>> +                                          hdr.type)),
>>> +     },
>>> +     [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
>>> +             .name = "ext_next_hdr",
>>> +             .help = "match IPv6 routing extension header next header type",
>>> +             .next = NEXT(item_ipv6_routing_ext,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>>> +                          item_param),
>>> +             .args = ARGS(ARGS_ENTRY_HTON(struct
>> rte_flow_item_ipv6_routing_ext,
>>> +                                          hdr.next_hdr)),
>>> +     },
>>> +     [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
>>> +             .name = "ext_seg_left",
>>> +             .help = "match IPv6 routing extension header segment left",
>>> +             .next = NEXT(item_ipv6_routing_ext,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>>> +                          item_param),
>>> +             .args = ARGS(ARGS_ENTRY_HTON(struct
>> rte_flow_item_ipv6_routing_ext,
>>> +                                          hdr.segments_left)),
>>> +     },
>>>        [ITEM_ICMP] = {
>>>                .name = "icmp",
>>>                .help = "match ICMP header", diff --git
>>> a/doc/guides/prog_guide/rte_flow.rst
>>> b/doc/guides/prog_guide/rte_flow.rst
>>> index 3e6242803d..602fab29d3 100644
>>> --- a/doc/guides/prog_guide/rte_flow.rst
>>> +++ b/doc/guides/prog_guide/rte_flow.rst
>>> @@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
>>>
>>>    - ``color``: Metering color marker.
>>>
>>> +Item: ``IPV6_ROUTING_EXT``
>>> +^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> +
>>> +Matches IPv6 routing extension header.
>>> +
>>> +- ``next_hdr``: Next layer header type.
>>> +- ``type``: IPv6 routing extension header type.
>>> +- ``segments_left``: How many IPv6 destination addresses carries on.
>>> +
>>>    Actions
>>>    ~~~~~~~
>>>
>>> diff --git a/doc/guides/rel_notes/release_23_03.rst
>>> b/doc/guides/rel_notes/release_23_03.rst
>>> index c15f6fbb9f..1337da73b8 100644
>>> --- a/doc/guides/rel_notes/release_23_03.rst
>>> +++ b/doc/guides/rel_notes/release_23_03.rst
>>> @@ -69,6 +69,11 @@ New Features
>>>        ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
>>>        required for eth_rx, eth_tx, crypto and timer eventdev adapters.
>>>
>>> +* **Added rte_flow support for matching IPv6 routing extension header
>>> +fields.**
>>> +
>>> +  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing
>>> + extension  header.
>>> +
>>>
>>>    Removed Items
>>>    -------------
>>> @@ -98,6 +103,10 @@ API Changes
>>>       Also, make sure to start the actual text at the margin.
>>>       =======================================================
>>>
>>> +* net: added a new structure:
>>> +
>>> +    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
>>> +
>>>
>>>    ABI Changes
>>>    -----------
>>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>>> 7d0c24366c..833382c466 100644
>>> --- a/lib/ethdev/rte_flow.c
>>> +++ b/lib/ethdev/rte_flow.c
>>> @@ -76,6 +76,23 @@ rte_flow_item_flex_conv(void *buf, const void *data)
>>>        return src->length;
>>>    }
>>>
>>> +static size_t
>>> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data) {
>>> +     struct rte_flow_item_ipv6_routing_ext *dst = buf;
>>> +     const struct rte_flow_item_ipv6_routing_ext *src = data;
>>> +     size_t len;
>>> +
>>> +     if (src->hdr.hdr_len)
>>
>> Please, compare vs 0
>>
>>> +             len = src->hdr.hdr_len << 3;
>>> +     else
>>> +             len = src->hdr.segments_left << 4;
>>> +     if (dst == NULL)
>>> +             return 0;
>>> +     memcpy(dst->segments, src->segments, len);
>>> +     return len;
>>> +}
>>> +
>>>    /** Generate flow_item[] entry. */
>>>    #define MK_FLOW_ITEM(t, s) \
>>>        [RTE_FLOW_ITEM_TYPE_ ## t] = { \ @@ -157,6 +174,8 @@ static
>>> const struct rte_flow_desc_data rte_flow_desc_item[] = {
>>>        MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>>>        MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>>>        MK_FLOW_ITEM(METER_COLOR, sizeof(struct
>>> rte_flow_item_meter_color)),
>>> +     MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct
>> rte_flow_item_ipv6_routing_ext),
>>> +                     rte_flow_item_ipv6_routing_ext_conv),
>>>    };
>>>
>>>    /** Generate flow_action[] entry. */ diff --git
>>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>> b60987db4b..ff9270690c 100644
>>> --- a/lib/ethdev/rte_flow.h
>>> +++ b/lib/ethdev/rte_flow.h
>>> @@ -624,6 +624,13 @@ enum rte_flow_item_type {
>>>         * See struct rte_flow_item_meter_color.
>>>         */
>>>        RTE_FLOW_ITEM_TYPE_METER_COLOR,
>>> +
>>> +     /**
>>> +      * Matches the presence of IPv6 routing extension header.
>>> +      *
>>> +      * @see struct rte_flow_item_ipv6_routing_ext.
>>> +      */
>>> +     RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
>>>    };
>>>
>>>    /**
>>> @@ -873,6 +880,20 @@ struct rte_flow_item_ipv6 {
>>>        uint32_t reserved:23;
>>>    };
>>>
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this structure may change without prior notice
>>> + *
>>> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
>>> + *
>>> + * Matches an IPv6 routing extension header.
>>> + */
>>> +struct rte_flow_item_ipv6_routing_ext {
>>> +     struct rte_ipv6_routing_ext hdr;
>>> +     __extension__
>>> +     rte_be32_t segments[]; /**< Each hop IPv6 address. */
>>
>> Do we really need it? Are you going to support it?
>> Will testpmd and flow conf work correctly since it uses size of the structure?
>>
> In the rte_flow.c and testpmd raw_encap() function, it relies on the hdr_len or segment_left fild not sizeof this structure.

We still have a number of sizeof() invocations for the
structure in the patch. I worry that related code will
not work fine if someone tries to specify segments.

>> IMHO we should just remove it right now if we're not going to support it.
>>
> In matching, we don't support segments field. I am ok to remove it.

Me too


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

* [PATCH v5 0/3] add IPv6 routing extension support
  2023-02-01  9:31                       ` Andrew Rybchenko
@ 2023-02-01 11:35                         ` Rongwei Liu
  2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
                                             ` (2 more replies)
  0 siblings, 3 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-01 11:35 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland

Support IPv6 routing extension header matching with new rte_flow item.
Add encapsulation support for IPv6 routing extension header.

v5: remove flex array 'segments'.
v4: use flex array to define variable length segments and move PMD
    implementation out.
v3: enhance the format and use be32/be16 in network header structure.
v2: remove redundant rte_flow items.

Rongwei Liu (3):
  ethdev: add IPv6 routing extension header definition
  ethdev: add modify IPv6 protocol field
  app/testpmd: add IPv6 routing extension header in raw encap

 app/test-pmd/cmdline_flow.c            | 72 +++++++++++++++++++++++++-
 doc/guides/prog_guide/rte_flow.rst     |  9 ++++
 doc/guides/rel_notes/release_23_03.rst |  9 ++++
 lib/ethdev/rte_flow.c                  |  1 +
 lib/ethdev/rte_flow.h                  | 20 +++++++
 lib/net/rte_ip.h                       | 20 +++++++
 6 files changed, 130 insertions(+), 1 deletion(-)

-- 
2.27.0


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

* [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-01 11:35                         ` [PATCH v5 0/3] add IPv6 routing extension support Rongwei Liu
@ 2023-02-01 11:35                           ` Rongwei Liu
  2023-02-01 11:39                             ` Andrew Rybchenko
  2023-02-01 13:44                             ` Thomas Monjalon
  2023-02-01 11:35                           ` [PATCH v5 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
  2023-02-01 11:35                           ` [PATCH v5 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
  2 siblings, 2 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-01 11:35 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit,
	Andrew Rybchenko, Olivier Matz

Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst |  9 +++++
 lib/ethdev/rte_flow.c                  |  1 +
 lib/ethdev/rte_flow.h                  | 19 +++++++++++
 lib/net/rte_ip.h                       | 20 +++++++++++
 6 files changed, 104 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..602fab29d3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches IPv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..1337da73b8 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,11 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header.
+
 
 Removed Items
 -------------
@@ -98,6 +103,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* net: added a new structure:
+
+    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..4da581146e 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -157,6 +157,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..9b9018cba2 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * @see struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..1f23e24af5 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,26 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		rte_be32_t flags;		/**< Packet control data per type. */
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			rte_be16_t tag;		/**< Packet tag. */
+		};
+	};
+	/** Following variable number of segments. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [PATCH v5 2/3] ethdev: add modify IPv6 protocol field
  2023-02-01 11:35                         ` [PATCH v5 0/3] add IPv6 routing extension support Rongwei Liu
  2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-02-01 11:35                           ` Rongwei Liu
  2023-02-01 11:39                             ` Andrew Rybchenko
  2023-02-01 16:55                             ` Stephen Hemminger
  2023-02-01 11:35                           ` [PATCH v5 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
  2 siblings, 2 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-01 11:35 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit, Andrew Rybchenko

Add IPv6 protocol modify field definition.

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 lib/ethdev/rte_flow.h       | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7a8516829c..b8156ebca2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 9b9018cba2..f4797682b7 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3547,6 +3547,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [PATCH v5 3/3] app/testpmd: add IPv6 routing extension header in raw encap
  2023-02-01 11:35                         ` [PATCH v5 0/3] add IPv6 routing extension support Rongwei Liu
  2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-02-01 11:35                           ` [PATCH v5 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-02-01 11:35                           ` Rongwei Liu
  2 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-01 11:35 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland, Aman Singh, Yuying Zhang

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index b8156ebca2..1340cf3a9b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10926,6 +10926,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.next_hdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11028,6 +11035,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11182,6 +11192,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11202,6 +11213,18 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			if (!ext->hdr.hdr_len) {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.segments_left << 4);
+				ext->hdr.hdr_len = ext->hdr.segments_left << 1;
+			} else {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.hdr_len << 3);
+			}
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* Re: [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-02-01 11:39                             ` Andrew Rybchenko
  2023-02-01 13:44                             ` Thomas Monjalon
  1 sibling, 0 replies; 67+ messages in thread
From: Andrew Rybchenko @ 2023-02-01 11:39 UTC (permalink / raw)
  To: Rongwei Liu, dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit, Olivier Matz

On 2/1/23 14:35, Rongwei Liu wrote:
> Add IPv6 routing extension header definition and no
> TLV support for now.
> 
> At rte_flow layer, there are new items defined for matching
> type/nexthdr/segments_left field.
> 
> Add command line support for IPv6 routing extension header
> matching: type/nexthdr/segment_list.
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>



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

* Re: [PATCH v5 2/3] ethdev: add modify IPv6 protocol field
  2023-02-01 11:35                           ` [PATCH v5 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-02-01 11:39                             ` Andrew Rybchenko
  2023-02-01 16:55                             ` Stephen Hemminger
  1 sibling, 0 replies; 67+ messages in thread
From: Andrew Rybchenko @ 2023-02-01 11:39 UTC (permalink / raw)
  To: Rongwei Liu, dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit

On 2/1/23 14:35, Rongwei Liu wrote:
> Add IPv6 protocol modify field definition.
> 
> Add new modify field destination type string: "ipv6_proto".
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>

I've already acked it:

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>



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

* Re: [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-02-01 11:39                             ` Andrew Rybchenko
@ 2023-02-01 13:44                             ` Thomas Monjalon
  2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
  1 sibling, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2023-02-01 13:44 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, Rongwei Liu
  Cc: rasland, Aman Singh, Yuying Zhang, Ferruh Yigit,
	Andrew Rybchenko, Olivier Matz

01/02/2023 12:35, Rongwei Liu:
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t next_hdr;			/**< Protocol, next header. */
> +	uint8_t hdr_len;			/**< Header length. */
> +	uint8_t type;				/**< Extension header type. */
> +	uint8_t segments_left;			/**< Valid segments number. */
> +	__extension__
> +	union {
> +		rte_be32_t flags;		/**< Packet control data per type. */
> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			rte_be16_t tag;		/**< Packet tag. */
> +		};
> +	};
> +	/** Following variable number of segments. */

Don't use doxygen here as there is no field following.

Wording suggestion:
"Next are 128-bit IPv6 address fields to describe segments."

> +} __rte_packed;




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

* Re: [PATCH v5 2/3] ethdev: add modify IPv6 protocol field
  2023-02-01 11:35                           ` [PATCH v5 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
  2023-02-01 11:39                             ` Andrew Rybchenko
@ 2023-02-01 16:55                             ` Stephen Hemminger
  2023-02-02  2:12                               ` Rongwei Liu
  1 sibling, 1 reply; 67+ messages in thread
From: Stephen Hemminger @ 2023-02-01 16:55 UTC (permalink / raw)
  To: Rongwei Liu
  Cc: dev, matan, viacheslavo, orika, thomas, rasland, Aman Singh,
	Yuying Zhang, Ferruh Yigit, Andrew Rybchenko

On Wed, 1 Feb 2023 13:35:10 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 7a8516829c..b8156ebca2 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
>  	"udp_port_src", "udp_port_dst",
>  	"vxlan_vni", "geneve_vni", "gtp_teid",
>  	"tag", "mark", "meta", "pointer", "value",
> -	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
> +	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
> +	"ipv6_proto", NULL
>  };
>  

Would it be better to keep the table in alphabetical order here?

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

* RE: [PATCH v5 2/3] ethdev: add modify IPv6 protocol field
  2023-02-01 16:55                             ` Stephen Hemminger
@ 2023-02-02  2:12                               ` Rongwei Liu
  0 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-02  2:12 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, Matan Azrad, Slava Ovsiienko, Ori Kam,
	NBU-Contact-Thomas Monjalon (EXTERNAL),
	Raslan Darawsheh, Aman Singh, Yuying Zhang, Ferruh Yigit,
	Andrew Rybchenko

Hi Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Thursday, February 2, 2023 00:56
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: dev@dpdk.org; Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Raslan Darawsheh
> <rasland@nvidia.com>; Aman Singh <aman.deep.singh@intel.com>; Yuying
> Zhang <yuying.zhang@intel.com>; Ferruh Yigit <ferruh.yigit@amd.com>;
> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Subject: Re: [PATCH v5 2/3] ethdev: add modify IPv6 protocol field
> 
> External email: Use caution opening links or attachments
> 
> 
> On Wed, 1 Feb 2023 13:35:10 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index 7a8516829c..b8156ebca2 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
> >       "udp_port_src", "udp_port_dst",
> >       "vxlan_vni", "geneve_vni", "gtp_teid",
> >       "tag", "mark", "meta", "pointer", "value",
> > -     "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
> > +     "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
> > +     "ipv6_proto", NULL
> >  };
> >
> 
> Would it be better to keep the table in alphabetical order here?
There are two arrays related to modify_filed resources: one for enumeration definition and the other is string for testpmd cli.
The sequence is strictly same.
" keep the table in alphabetical " needs to change both the array and make sure the new comer is the same index.
IMO, current approach is more friendly for new coming fields.

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

* [PATCH v6 0/3] add IPv6 routing extension support
  2023-02-01 13:44                             ` Thomas Monjalon
@ 2023-02-02 10:00                               ` Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
                                                   ` (3 more replies)
  0 siblings, 4 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-02 10:00 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland

Support IPv6 routing extension header matching with new rte_flow item.
Add encapsulation support for IPv6 routing extension header.

v6: use non doxgen style comments for 'segments'.
v5: remove flex array 'segments'.
v4: use flex array to define variable length segments and move PMD
    implementation out.
v3: enhance the format and use be32/be16 in network header
    structure.
v2: remove redundant rte_flow items.

Rongwei Liu (3):
  ethdev: add IPv6 routing extension header definition
  ethdev: add modify IPv6 protocol field
  app/testpmd: add IPv6 routing extension header in raw encap

 app/test-pmd/cmdline_flow.c            | 72 +++++++++++++++++++++++++-
 doc/guides/prog_guide/rte_flow.rst     |  9 ++++
 doc/guides/rel_notes/release_23_03.rst |  9 ++++
 lib/ethdev/rte_flow.c                  |  1 +
 lib/ethdev/rte_flow.h                  | 20 +++++++
 lib/net/rte_ip.h                       | 20 +++++++
 6 files changed, 130 insertions(+), 1 deletion(-)

-- 
2.27.0


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

* [PATCH v6 1/3] ethdev: add IPv6 routing extension header definition
  2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
@ 2023-02-02 10:00                                 ` Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
                                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-02 10:00 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Andrew Rybchenko, Aman Singh, Yuying Zhang,
	Ferruh Yigit, Olivier Matz

Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst |  9 +++++
 lib/ethdev/rte_flow.c                  |  1 +
 lib/ethdev/rte_flow.h                  | 19 +++++++++++
 lib/net/rte_ip.h                       | 20 +++++++++++
 6 files changed, 104 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@ enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@ static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@ static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..602fab29d3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@ Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches IPv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..1337da73b8 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,11 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header.
+
 
 Removed Items
 -------------
@@ -98,6 +103,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* net: added a new structure:
+
+    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..4da581146e 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -157,6 +157,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..9b9018cba2 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@ enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * @see struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,18 @@ struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..a310e9d498 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,26 @@ struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		rte_be32_t flags;		/**< Packet control data per type. */
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			rte_be16_t tag;		/**< Packet tag. */
+		};
+	};
+	/* Next are 128-bit IPv6 address fields to describe segments. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-- 
2.27.0


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

* [PATCH v6 2/3] ethdev: add modify IPv6 protocol field
  2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
@ 2023-02-02 10:00                                 ` Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
  2023-02-03 18:36                                 ` [PATCH v6 0/3] add IPv6 routing extension support Ferruh Yigit
  3 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-02 10:00 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas
  Cc: rasland, Andrew Rybchenko, Aman Singh, Yuying Zhang, Ferruh Yigit

Add IPv6 protocol modify field definition.

Add new modify field destination type string: "ipv6_proto".

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c | 3 ++-
 lib/ethdev/rte_flow.h       | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7a8516829c..b8156ebca2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -811,7 +811,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"ipv6_proto", NULL
 };
 
 static const char *const meter_colors[] = {
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 9b9018cba2..f4797682b7 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3547,6 +3547,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_IPV6_PROTO,	/**< IPv6 next header. */
 };
 
 /**
-- 
2.27.0


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

* [PATCH v6 3/3] app/testpmd: add IPv6 routing extension header in raw encap
  2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
  2023-02-02 10:00                                 ` [PATCH v6 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
@ 2023-02-02 10:00                                 ` Rongwei Liu
  2023-02-03 18:36                                 ` [PATCH v6 0/3] add IPv6 routing extension support Ferruh Yigit
  3 siblings, 0 replies; 67+ messages in thread
From: Rongwei Liu @ 2023-02-02 10:00 UTC (permalink / raw)
  To: dev, matan, viacheslavo, orika, thomas; +Cc: rasland, Aman Singh, Yuying Zhang

Add IPv6 routing extension header support in raw_encap command.
1. No TLV support now.
2. Assume header length equals to the current segment_left.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index b8156ebca2..1340cf3a9b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -10926,6 +10926,13 @@ flow_item_default_mask(const struct rte_flow_item *item)
 {
 	const void *mask = NULL;
 	static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX);
+	static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = {
+		.hdr = {
+			.next_hdr = 0xff,
+			.type = 0xff,
+			.segments_left = 0xff,
+		},
+	};
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_ANY:
@@ -11028,6 +11035,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		mask = &rte_flow_item_meter_color_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+		mask = &ipv6_routing_ext_default_mask;
+		break;
 	default:
 		break;
 	}
@@ -11182,6 +11192,7 @@ cmd_set_raw_parsed(const struct buffer *in)
 	for (i = n - 1 ; i >= 0; --i) {
 		const struct rte_flow_item_gtp *gtp;
 		const struct rte_flow_item_geneve_opt *opt;
+		struct rte_flow_item_ipv6_routing_ext *ext;
 
 		item = in->args.vc.pattern + i;
 		if (item->spec == NULL)
@@ -11202,6 +11213,18 @@ cmd_set_raw_parsed(const struct buffer *in)
 			size = sizeof(struct rte_ipv6_hdr);
 			proto = RTE_ETHER_TYPE_IPV6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT:
+			ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec;
+			if (!ext->hdr.hdr_len) {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.segments_left << 4);
+				ext->hdr.hdr_len = ext->hdr.segments_left << 1;
+			} else {
+				size = sizeof(struct rte_ipv6_routing_ext) +
+					(ext->hdr.hdr_len << 3);
+			}
+			proto = IPPROTO_ROUTING;
+			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			size = sizeof(struct rte_udp_hdr);
 			proto = 0x11;
-- 
2.27.0


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

* Re: [PATCH v6 0/3] add IPv6 routing extension support
  2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
                                                   ` (2 preceding siblings ...)
  2023-02-02 10:00                                 ` [PATCH v6 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
@ 2023-02-03 18:36                                 ` Ferruh Yigit
  3 siblings, 0 replies; 67+ messages in thread
From: Ferruh Yigit @ 2023-02-03 18:36 UTC (permalink / raw)
  To: Rongwei Liu, dev, matan, viacheslavo, orika, thomas; +Cc: rasland

On 2/2/2023 10:00 AM, Rongwei Liu wrote:
> Support IPv6 routing extension header matching with new rte_flow item.
> Add encapsulation support for IPv6 routing extension header.
> 
> v6: use non doxgen style comments for 'segments'.
> v5: remove flex array 'segments'.
> v4: use flex array to define variable length segments and move PMD
>     implementation out.
> v3: enhance the format and use be32/be16 in network header
>     structure.
> v2: remove redundant rte_flow items.
> 
> Rongwei Liu (3):
>   ethdev: add IPv6 routing extension header definition
>   ethdev: add modify IPv6 protocol field
>   app/testpmd: add IPv6 routing extension header in raw encap

Series applied to dpdk-next-net/main, thanks.

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

end of thread, other threads:[~2023-02-03 18:36 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-21  8:42 [RFC 0/9] support ipv6 routing header matching Rongwei Liu
2022-12-21  8:42 ` [RFC 1/9] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-01-16 16:15   ` Ori Kam
2023-01-17  2:50     ` Rongwei Liu
2023-01-19  3:11   ` [PATCH v2 0/8] add IPv6 routing extension support Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-01-20  9:20       ` Andrew Rybchenko
2023-01-30  3:46         ` Rongwei Liu
2023-01-30  3:59         ` [PATCH v3 0/8] add IPv6 routing extension support Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 1/8] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-01-30 16:47             ` Stephen Hemminger
2023-01-31  2:03               ` Rongwei Liu
2023-01-31  2:27               ` Rongwei Liu
2023-01-31  2:55                 ` Stephen Hemminger
2023-01-31  3:20                   ` Rongwei Liu
2023-01-30 16:50             ` Stephen Hemminger
2023-01-31  2:05               ` Rongwei Liu
2023-01-31  3:02             ` Stephen Hemminger
2023-01-31  3:24               ` Rongwei Liu
2023-01-31  9:18                 ` Rongwei Liu
2023-01-31  9:42                   ` Thomas Monjalon
2023-01-31 11:42                     ` Ori Kam
2023-01-31  9:36               ` [PATCH v4 0/3] add IPv6 routing extension support Rongwei Liu
2023-01-31  9:36                 ` [PATCH v4 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-02-01  9:21                   ` Andrew Rybchenko
2023-02-01  9:27                     ` Rongwei Liu
2023-02-01  9:31                       ` Andrew Rybchenko
2023-02-01 11:35                         ` [PATCH v5 0/3] add IPv6 routing extension support Rongwei Liu
2023-02-01 11:35                           ` [PATCH v5 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-02-01 11:39                             ` Andrew Rybchenko
2023-02-01 13:44                             ` Thomas Monjalon
2023-02-02 10:00                               ` [PATCH v6 0/3] add IPv6 routing extension support Rongwei Liu
2023-02-02 10:00                                 ` [PATCH v6 1/3] ethdev: add IPv6 routing extension header definition Rongwei Liu
2023-02-02 10:00                                 ` [PATCH v6 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-02-02 10:00                                 ` [PATCH v6 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2023-02-03 18:36                                 ` [PATCH v6 0/3] add IPv6 routing extension support Ferruh Yigit
2023-02-01 11:35                           ` [PATCH v5 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-02-01 11:39                             ` Andrew Rybchenko
2023-02-01 16:55                             ` Stephen Hemminger
2023-02-02  2:12                               ` Rongwei Liu
2023-02-01 11:35                           ` [PATCH v5 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2023-01-31  9:36                 ` [PATCH v4 2/3] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-02-01  9:14                   ` Andrew Rybchenko
2023-01-31  9:36                 ` [PATCH v4 3/3] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
2023-01-30  3:59           ` [PATCH v3 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 2/8] net/mlx5: adopt IPv6 routing extension prm definition Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 3/8] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 4/8] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 5/8] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 6/8] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 7/8] net/mlx5: add modify IPv6 protocol implementation Rongwei Liu
2023-01-19  3:11     ` [PATCH v2 8/8] doc/mlx5: add IPv6 routing extension matching docs Rongwei Liu
2022-12-21  8:42 ` [RFC 2/9] app/testpmd: add IPv6 routing extension header support Rongwei Liu
2022-12-21  8:42 ` [RFC 3/9] net/mlx5: adopt new flex item definition Rongwei Liu
2022-12-21  8:42 ` [RFC 4/9] net/mlx5/hws: Definer, add mlx5dr context to definer_conv_data Rongwei Liu
2022-12-21  8:43 ` [RFC 5/9] net/mlx5/hws: add IPv6 routing extension matching support Rongwei Liu
2022-12-21  8:43 ` [RFC 6/9] app/testpmd: add IPv6 routing extension header in raw encap Rongwei Liu
2022-12-21  8:43 ` [RFC 7/9] ethdev: add modify IPv6 protocol field Rongwei Liu
2023-01-16 16:20   ` Ori Kam
2022-12-21  8:43 ` [RFC 8/9] app/testpmd: add modify IPv6 protocol command line Rongwei Liu
2022-12-21  8:43 ` [RFC 9/9] net/mlx5/hws: add modify IPv6 protocol implementation Rongwei Liu

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).