|WARNING| pw132068-132072 [PATCH] [v1, 5/5] net/mlx5: implement IPv6 routing push remove

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Thu Sep 28 04:51:05 CEST 2023


Test-Label: iol-testing
Test-Status: WARNING
http://dpdk.org/patch/132068

_apply patch failure_

Submitter: Rongwei Liu <rongweil at nvidia.com>
Date: Thursday, September 28 2023 02:33:40 
Applied on: CommitID:ab23648bdf7c9c581eb3de8eeb3daa1960608ae4
Apply patch set 132068-132072 failed:

Checking patch drivers/net/mlx5/hws/mlx5dr_action.c...
error: while searching for:

	if (!num_of_hdrs) {
		DR_LOG(ERR, "Reformat num_of_hdrs cannot be zero");
		return NULL;
	}


error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:2291
error: while searching for:
						   reformat_hdrs, log_bulk_size);
	if (ret) {
		DR_LOG(ERR, "Failed to create HWS reformat action");
		rte_errno = EINVAL;
		goto free_reformat_hdrs;
	}


error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:2338
Applying patch drivers/net/mlx5/hws/mlx5dr_action.c with 2 rejects...
Rejected hunk #1.
Rejected hunk #2.
hint: Use 'git am --show-current-patch' to see the failed patch
diff a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c	(rejected hunks)
@@ -2291,6 +2291,7 @@ mlx5dr_action_create_insert_header(struct mlx5dr_context *ctx,
 
 	if (!num_of_hdrs) {
 		DR_LOG(ERR, "Reformat num_of_hdrs cannot be zero");
+		rte_errno = EINVAL;
 		return NULL;
 	}
 
@@ -2338,7 +2339,6 @@ mlx5dr_action_create_insert_header(struct mlx5dr_context *ctx,
 						   reformat_hdrs, log_bulk_size);
 	if (ret) {
 		DR_LOG(ERR, "Failed to create HWS reformat action");
-		rte_errno = EINVAL;
 		goto free_reformat_hdrs;
 	}
 
Checking patch drivers/common/mlx5/mlx5_prm.h...
Hunk #1 succeeded at 3492 (offset -144 lines).
Checking patch drivers/net/mlx5/hws/mlx5dr.h...
error: while searching for:
	MLX5DR_ACTION_TYP_DEST_ROOT,
	MLX5DR_ACTION_TYP_DEST_ARRAY,
	MLX5DR_ACTION_TYP_DEST_IPSEC_DECRYPT,
	MLX5DR_ACTION_TYP_MAX,
};


error: patch failed: drivers/net/mlx5/hws/mlx5dr.h:55
Hunk #2 succeeded at 180 (offset -17 lines).
error: while searching for:
					uint8_t log_bulk_sz,
					uint32_t flags);

/* Destroy direct rule action.
 *
 * @param[in] action

error: patch failed: drivers/net/mlx5/hws/mlx5dr.h:897
Checking patch drivers/net/mlx5/hws/mlx5dr_action.c...
error: while searching for:
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
		BIT(MLX5DR_ACTION_TYP_REMOVE_HEADER) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2),
		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
		BIT(MLX5DR_ACTION_TYP_CTR),

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:26
error: while searching for:
		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
		BIT(MLX5DR_ACTION_TYP_TBL) |

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:39
error: while searching for:
		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:63
error: while searching for:
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
		BIT(MLX5DR_ACTION_TYP_REMOVE_HEADER) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2),
		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:77
error: while searching for:
		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:91
error: while searching for:

	if (!mlx5dr_action_is_hws_flags(flags) ||
	    ((flags & MLX5DR_ACTION_FLAG_SHARED) && (log_bulk_size || num_of_hdrs > 1))) {
		DR_LOG(ERR, "Reformat flags don't fit HWS (flags: %x0x)", flags);
		rte_errno = EINVAL;
		goto free_action;
	}

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:1746
error: while searching for:
	return NULL;
}

static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
{
	struct mlx5dr_devx_obj *obj = NULL;

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:2489
error: while searching for:
		mlx5dr_action_destroy_stcs(action);
		mlx5dr_tmp_action_dest_ipsec_destroy_ste_arr(action->dest_ipsec.action_ste);
		break;
	}
}


error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:2566
Checking patch drivers/net/mlx5/hws/mlx5dr_action.h...
error: while searching for:
					uint8_t offset;
					bool encap;
				} reformat;
				struct {
					struct mlx5dr_devx_obj *devx_obj;
					uint8_t return_reg_id;

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.h:143
Checking patch drivers/net/mlx5/hws/mlx5dr_debug.c...
error: while searching for:
	[MLX5DR_ACTION_TYP_INSERT_HEADER] = "INSERT_HEADER",
	[MLX5DR_ACTION_TYP_REMOVE_HEADER] = "REMOVE_HEADER",
	[MLX5DR_ACTION_TYP_DEST_IPSEC_DECRYPT] = "DEST_IPSEC_DECRYPT",
};

static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,

error: patch failed: drivers/net/mlx5/hws/mlx5dr_debug.c:32
Checking patch drivers/net/mlx5/mlx5_flow.h...
Hunk #1 succeeded at 548 (offset -99 lines).
error: while searching for:
	return UINT32_MAX;
}

struct mlx5_list_entry *
flow_dv_sft_create_cb(void *tool_ctx __rte_unused, void *cb_ctx);
int

error: patch failed: drivers/net/mlx5/mlx5_flow.h:3080
Applied patch drivers/common/mlx5/mlx5_prm.h cleanly.
Applying patch drivers/net/mlx5/hws/mlx5dr.h with 2 rejects...
Rejected hunk #1.
Hunk #2 applied cleanly.
Rejected hunk #3.
Applying patch drivers/net/mlx5/hws/mlx5dr_action.c with 8 rejects...
Rejected hunk #1.
Rejected hunk #2.
Rejected hunk #3.
Rejected hunk #4.
Rejected hunk #5.
Rejected hunk #6.
Rejected hunk #7.
Rejected hunk #8.
Applying patch drivers/net/mlx5/hws/mlx5dr_action.h with 1 reject...
Hunk #1 applied cleanly.
Rejected hunk #2.
Applying patch drivers/net/mlx5/hws/mlx5dr_debug.c with 1 reject...
Rejected hunk #1.
Applying patch drivers/net/mlx5/mlx5_flow.h with 1 reject...
Hunk #1 applied cleanly.
Rejected hunk #2.
hint: Use 'git am --show-current-patch' to see the failed patch
diff a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h	(rejected hunks)
@@ -55,6 +55,8 @@ enum mlx5dr_action_type {
 	MLX5DR_ACTION_TYP_DEST_ROOT,
 	MLX5DR_ACTION_TYP_DEST_ARRAY,
 	MLX5DR_ACTION_TYP_DEST_IPSEC_DECRYPT,
+	MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
+	MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
 	MLX5DR_ACTION_TYP_MAX,
 };
 
@@ -897,6 +904,28 @@ mlx5dr_tmp_action_create_dest_ipsec_dec(struct mlx5dr_context *ctx,
 					uint8_t log_bulk_sz,
 					uint32_t flags);
 
+/* Create action to push or remove IPv6 extension header.
+ *
+ * @param[in] ctx
+ *	The context in which the new action will be created.
+ * @param[in] type
+ *	Type of direct rule action: MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT or
+ *	MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT.
+ * @param[in] hdr
+ *	Header for packet reformat.
+ * @param[in] log_bulk_size
+ *	Number of unique values used with this pattern.
+ * @param[in] flags
+ *	Action creation flags. (enum mlx5dr_action_flags)
+ * @return pointer to mlx5dr_action on success NULL otherwise.
+ */
+struct mlx5dr_action *
+mlx5dr_action_create_reformat_ipv6_ext(struct mlx5dr_context *ctx,
+				       enum mlx5dr_action_type type,
+				       struct mlx5dr_action_reformat_header *hdr,
+				       uint32_t log_bulk_size,
+				       uint32_t flags);
+
 /* Destroy direct rule action.
  *
  * @param[in] action
diff a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c	(rejected hunks)
@@ -26,7 +26,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
 		BIT(MLX5DR_ACTION_TYP_REMOVE_HEADER) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2) |
-		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2),
+		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2) |
+		BIT(MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT),
 		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
 		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
 		BIT(MLX5DR_ACTION_TYP_CTR),
@@ -39,6 +40,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
 		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
 		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
+		BIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
 		BIT(MLX5DR_ACTION_TYP_TBL) |
@@ -63,6 +65,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
 		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
 		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
+		BIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
@@ -77,7 +80,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
 		BIT(MLX5DR_ACTION_TYP_REMOVE_HEADER) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2) |
-		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2),
+		BIT(MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2) |
+		BIT(MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT),
 		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
 		BIT(MLX5DR_ACTION_TYP_POP_VLAN),
 		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
@@ -91,6 +95,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_
 		BIT(MLX5DR_ACTION_TYP_PUSH_VLAN),
 		BIT(MLX5DR_ACTION_TYP_MODIFY_HDR),
 		BIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |
+		BIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) |
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3),
 		BIT(MLX5DR_ACTION_TYP_REFORMAT_TRAILER),
@@ -1746,7 +1751,7 @@ mlx5dr_action_create_reformat(struct mlx5dr_context *ctx,
 
 	if (!mlx5dr_action_is_hws_flags(flags) ||
 	    ((flags & MLX5DR_ACTION_FLAG_SHARED) && (log_bulk_size || num_of_hdrs > 1))) {
-		DR_LOG(ERR, "Reformat flags don't fit HWS (flags: %x0x)", flags);
+		DR_LOG(ERR, "Reformat flags don't fit HWS (flags: 0x%x)", flags);
 		rte_errno = EINVAL;
 		goto free_action;
 	}
@@ -2489,6 +2494,347 @@ mlx5dr_tmp_action_create_dest_ipsec_dec(struct mlx5dr_context *ctx,
 	return NULL;
 }
 
+static void *
+mlx5dr_action_create_pop_ipv6_route_ext_mhdr1(struct mlx5dr_action *action)
+{
+	struct mlx5dr_action_mh_pattern pattern;
+	__be64 cmd[3] = {0};
+	uint16_t mod_id;
+
+	mod_id = flow_hw_get_ipv6_route_ext_mod_id_from_ctx(action->ctx, 0);
+	if (!mod_id) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/*
+	 * Backup ipv6_route_ext.next_hdr to ipv6_route_ext.seg_left.
+	 * Next_hdr will be copied to ipv6.protocol after pop done.
+	 */
+	MLX5_SET(copy_action_in, &cmd[0], action_type, MLX5_MODIFICATION_TYPE_COPY);
+	MLX5_SET(copy_action_in, &cmd[0], length, 8);
+	MLX5_SET(copy_action_in, &cmd[0], src_offset, 24);
+	MLX5_SET(copy_action_in, &cmd[0], src_field, mod_id);
+	MLX5_SET(copy_action_in, &cmd[0], dst_field, mod_id);
+
+	/* Add nop between the continuous same modify field id */
+	MLX5_SET(copy_action_in, &cmd[1], action_type, MLX5_MODIFICATION_TYPE_NOP);
+
+	/* Clear next_hdr for right checksum */
+	MLX5_SET(set_action_in, &cmd[2], action_type, MLX5_MODIFICATION_TYPE_SET);
+	MLX5_SET(set_action_in, &cmd[2], length, 8);
+	MLX5_SET(set_action_in, &cmd[2], offset, 24);
+	MLX5_SET(set_action_in, &cmd[2], field, mod_id);
+
+	pattern.data = cmd;
+	pattern.sz = sizeof(cmd);
+
+	return mlx5dr_action_create_modify_header(action->ctx, 1, &pattern,
+						  0, action->flags);
+}
+
+static void *
+mlx5dr_action_create_pop_ipv6_route_ext_mhdr2(struct mlx5dr_action *action)
+{
+	enum mlx5_modification_field field[MLX5_ST_SZ_DW(definer_hl_ipv6_addr)] = {
+		MLX5_MODI_OUT_DIPV6_127_96,
+		MLX5_MODI_OUT_DIPV6_95_64,
+		MLX5_MODI_OUT_DIPV6_63_32,
+		MLX5_MODI_OUT_DIPV6_31_0
+	};
+	struct mlx5dr_action_mh_pattern pattern;
+	__be64 cmd[5] = {0};
+	uint16_t mod_id;
+	uint32_t i;
+
+	/* Copy ipv6_route_ext[first_segment].dst_addr by flex parser to ipv6.dst_addr */
+	for (i = 0; i < MLX5_ST_SZ_DW(definer_hl_ipv6_addr); i++) {
+		mod_id = flow_hw_get_ipv6_route_ext_mod_id_from_ctx(action->ctx, i + 1);
+		if (!mod_id) {
+			rte_errno = EINVAL;
+			return NULL;
+		}
+
+		MLX5_SET(copy_action_in, &cmd[i], action_type, MLX5_MODIFICATION_TYPE_COPY);
+		MLX5_SET(copy_action_in, &cmd[i], dst_field, field[i]);
+		MLX5_SET(copy_action_in, &cmd[i], src_field, mod_id);
+	}
+
+	mod_id = flow_hw_get_ipv6_route_ext_mod_id_from_ctx(action->ctx, 0);
+	if (!mod_id) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* Restore next_hdr from seg_left for flex parser identifying */
+	MLX5_SET(copy_action_in, &cmd[4], action_type, MLX5_MODIFICATION_TYPE_COPY);
+	MLX5_SET(copy_action_in, &cmd[4], length, 8);
+	MLX5_SET(copy_action_in, &cmd[4], dst_offset, 24);
+	MLX5_SET(copy_action_in, &cmd[4], src_field, mod_id);
+	MLX5_SET(copy_action_in, &cmd[4], dst_field, mod_id);
+
+	pattern.data = cmd;
+	pattern.sz = sizeof(cmd);
+
+	return mlx5dr_action_create_modify_header(action->ctx, 1, &pattern,
+						  0, action->flags);
+}
+
+static void *
+mlx5dr_action_create_pop_ipv6_route_ext_mhdr3(struct mlx5dr_action *action)
+{
+	uint8_t cmd[MLX5DR_MODIFY_ACTION_SIZE] = {0};
+	struct mlx5dr_action_mh_pattern pattern;
+	uint16_t mod_id;
+
+	mod_id = flow_hw_get_ipv6_route_ext_mod_id_from_ctx(action->ctx, 0);
+	if (!mod_id) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* Copy ipv6_route_ext.next_hdr to ipv6.protocol */
+	MLX5_SET(copy_action_in, cmd, action_type, MLX5_MODIFICATION_TYPE_COPY);
+	MLX5_SET(copy_action_in, cmd, length, 8);
+	MLX5_SET(copy_action_in, cmd, src_offset, 24);
+	MLX5_SET(copy_action_in, cmd, src_field, mod_id);
+	MLX5_SET(copy_action_in, cmd, dst_field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+
+	pattern.data = (__be64 *)cmd;
+	pattern.sz = sizeof(cmd);
+
+	return mlx5dr_action_create_modify_header(action->ctx, 1, &pattern,
+						  0, action->flags);
+}
+
+static int
+mlx5dr_action_create_pop_ipv6_route_ext(struct mlx5dr_action *action)
+{
+	uint8_t anchor_id = flow_hw_get_ipv6_route_ext_anchor_from_ctx(action->ctx);
+	struct mlx5dr_action_remove_header_attr hdr_attr;
+	uint32_t i;
+
+	if (!anchor_id) {
+		rte_errno = EINVAL;
+		return rte_errno;
+	}
+
+	action->ipv6_route_ext.action[0] =
+		mlx5dr_action_create_pop_ipv6_route_ext_mhdr1(action);
+	action->ipv6_route_ext.action[1] =
+		mlx5dr_action_create_pop_ipv6_route_ext_mhdr2(action);
+	action->ipv6_route_ext.action[2] =
+		mlx5dr_action_create_pop_ipv6_route_ext_mhdr3(action);
+
+	hdr_attr.by_anchor.decap = 1;
+	hdr_attr.by_anchor.start_anchor = anchor_id;
+	hdr_attr.by_anchor.end_anchor = MLX5_HEADER_ANCHOR_TCP_UDP;
+	hdr_attr.type = MLX5DR_ACTION_REMOVE_HEADER_TYPE_BY_HEADER;
+	action->ipv6_route_ext.action[3] =
+		mlx5dr_action_create_remove_header(action->ctx, &hdr_attr, action->flags);
+
+	if (!action->ipv6_route_ext.action[0] || !action->ipv6_route_ext.action[1] ||
+	    !action->ipv6_route_ext.action[2] || !action->ipv6_route_ext.action[3]) {
+		DR_LOG(ERR, "Failed to create ipv6_route_ext pop subaction");
+		goto err;
+	}
+
+	return 0;
+
+err:
+	for (i = 0; i < MLX5DR_ACTION_IPV6_EXT_MAX_SA; i++)
+		if (action->ipv6_route_ext.action[i])
+			mlx5dr_action_destroy(action->ipv6_route_ext.action[i]);
+
+	return rte_errno;
+}
+
+static void *
+mlx5dr_action_create_push_ipv6_route_ext_mhdr1(struct mlx5dr_action *action)
+{
+	uint8_t cmd[MLX5DR_MODIFY_ACTION_SIZE] = {0};
+	struct mlx5dr_action_mh_pattern pattern;
+
+	/* Set ipv6.protocol to IPPROTO_ROUTING */
+	MLX5_SET(set_action_in, cmd, action_type, MLX5_MODIFICATION_TYPE_SET);
+	MLX5_SET(set_action_in, cmd, length, 8);
+	MLX5_SET(set_action_in, cmd, field, MLX5_MODI_OUT_IPV6_NEXT_HDR);
+	MLX5_SET(set_action_in, cmd, data, IPPROTO_ROUTING);
+
+	pattern.data = (__be64 *)cmd;
+	pattern.sz = sizeof(cmd);
+
+	return mlx5dr_action_create_modify_header(action->ctx, 1, &pattern, 0,
+						  action->flags | MLX5DR_ACTION_FLAG_SHARED);
+}
+
+static void *
+mlx5dr_action_create_push_ipv6_route_ext_mhdr2(struct mlx5dr_action *action,
+					       uint32_t bulk_size,
+					       uint8_t *data)
+{
+	enum mlx5_modification_field field[MLX5_ST_SZ_DW(definer_hl_ipv6_addr)] = {
+		MLX5_MODI_OUT_DIPV6_127_96,
+		MLX5_MODI_OUT_DIPV6_95_64,
+		MLX5_MODI_OUT_DIPV6_63_32,
+		MLX5_MODI_OUT_DIPV6_31_0
+	};
+	struct mlx5dr_action_mh_pattern pattern;
+	uint8_t seg_left, next_hdr;
+	uint32_t *ipv6_dst_addr;
+	__be64 cmd[5] = {0};
+	uint16_t mod_id;
+	uint32_t i;
+
+	/* Fetch the last IPv6 address in the segment list */
+	if (action->flags & MLX5DR_ACTION_FLAG_SHARED) {
+		seg_left = MLX5_GET(header_ipv6_routing_ext, data, segments_left) - 1;
+		ipv6_dst_addr = (uint32_t *)data + MLX5_ST_SZ_DW(header_ipv6_routing_ext) +
+				seg_left * MLX5_ST_SZ_DW(definer_hl_ipv6_addr);
+	}
+
+	/* Copy IPv6 destination address from ipv6_route_ext.last_segment */
+	for (i = 0; i < MLX5_ST_SZ_DW(definer_hl_ipv6_addr); i++) {
+		MLX5_SET(set_action_in, &cmd[i], action_type, MLX5_MODIFICATION_TYPE_SET);
+		MLX5_SET(set_action_in, &cmd[i], field, field[i]);
+		if (action->flags & MLX5DR_ACTION_FLAG_SHARED)
+			MLX5_SET(set_action_in, &cmd[i], data, be32toh(*ipv6_dst_addr++));
+	}
+
+	mod_id = flow_hw_get_ipv6_route_ext_mod_id_from_ctx(action->ctx, 0);
+	if (!mod_id) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/* Set ipv6_route_ext.next_hdr since initially pushed as 0 for right checksum */
+	MLX5_SET(set_action_in, &cmd[4], action_type, MLX5_MODIFICATION_TYPE_SET);
+	MLX5_SET(set_action_in, &cmd[4], length, 8);
+	MLX5_SET(set_action_in, &cmd[4], offset, 24);
+	MLX5_SET(set_action_in, &cmd[4], field, mod_id);
+	if (action->flags & MLX5DR_ACTION_FLAG_SHARED) {
+		next_hdr = MLX5_GET(header_ipv6_routing_ext, data, next_hdr);
+		MLX5_SET(set_action_in, &cmd[4], data, next_hdr);
+	}
+
+	pattern.data = cmd;
+	pattern.sz = sizeof(cmd);
+
+	return mlx5dr_action_create_modify_header(action->ctx, 1, &pattern,
+						  bulk_size, action->flags);
+}
+
+static int
+mlx5dr_action_create_push_ipv6_route_ext(struct mlx5dr_action *action,
+					 struct mlx5dr_action_reformat_header *hdr,
+					 uint32_t bulk_size)
+{
+	struct mlx5dr_action_insert_header insert_hdr = {{0}};
+	uint8_t header[MLX5_PUSH_MAX_LEN];
+	uint32_t i;
+
+	if (!hdr || !hdr->sz || hdr->sz > MLX5_PUSH_MAX_LEN ||
+	    ((action->flags & MLX5DR_ACTION_FLAG_SHARED) && !hdr->data)) {
+		DR_LOG(ERR, "Invalid ipv6_route_ext header");
+		rte_errno = EINVAL;
+		return rte_errno;
+	}
+
+	if (action->flags & MLX5DR_ACTION_FLAG_SHARED) {
+		memcpy(header, hdr->data, hdr->sz);
+		/* Clear ipv6_route_ext.next_hdr for right checksum */
+		MLX5_SET(header_ipv6_routing_ext, header, next_hdr, 0);
+	}
+
+	insert_hdr.anchor = MLX5_HEADER_ANCHOR_TCP_UDP;
+	insert_hdr.encap = 1;
+	insert_hdr.hdr.sz = hdr->sz;
+	insert_hdr.hdr.data = header;
+	action->ipv6_route_ext.action[0] =
+		mlx5dr_action_create_insert_header(action->ctx, 1, &insert_hdr,
+						   bulk_size, action->flags);
+	action->ipv6_route_ext.action[1] =
+		mlx5dr_action_create_push_ipv6_route_ext_mhdr1(action);
+	action->ipv6_route_ext.action[2] =
+		mlx5dr_action_create_push_ipv6_route_ext_mhdr2(action, bulk_size, hdr->data);
+
+	if (!action->ipv6_route_ext.action[0] ||
+	    !action->ipv6_route_ext.action[1] ||
+	    !action->ipv6_route_ext.action[2]) {
+		DR_LOG(ERR, "Failed to create ipv6_route_ext push subaction");
+		goto err;
+	}
+
+	return 0;
+
+err:
+	for (i = 0; i < MLX5DR_ACTION_IPV6_EXT_MAX_SA; i++)
+		if (action->ipv6_route_ext.action[i])
+			mlx5dr_action_destroy(action->ipv6_route_ext.action[i]);
+
+	return rte_errno;
+}
+
+struct mlx5dr_action *
+mlx5dr_action_create_reformat_ipv6_ext(struct mlx5dr_context *ctx,
+				       enum mlx5dr_action_type action_type,
+				       struct mlx5dr_action_reformat_header *hdr,
+				       uint32_t log_bulk_size,
+				       uint32_t flags)
+{
+	struct mlx5dr_action *action;
+	int ret;
+
+	if (mlx5dr_context_cap_dynamic_reparse(ctx)) {
+		DR_LOG(ERR, "IPv6 extension actions is not supported");
+		rte_errno = ENOTSUP;
+		return NULL;
+	}
+
+	if (!mlx5dr_action_is_hws_flags(flags) ||
+	    ((flags & MLX5DR_ACTION_FLAG_SHARED) && log_bulk_size)) {
+		DR_LOG(ERR, "IPv6 extension flags don't fit HWS (flags: 0x%x)", flags);
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	action = mlx5dr_action_create_generic(ctx, flags, action_type);
+	if (!action) {
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+
+	switch (action_type) {
+	case MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT:
+		if (!(flags & MLX5DR_ACTION_FLAG_SHARED)) {
+			DR_LOG(ERR, "Pop ipv6_route_ext must be shared");
+			rte_errno = EINVAL;
+			goto free_action;
+		}
+
+		ret = mlx5dr_action_create_pop_ipv6_route_ext(action);
+		break;
+	case MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT:
+		ret = mlx5dr_action_create_push_ipv6_route_ext(action, hdr, log_bulk_size);
+		break;
+	default:
+		DR_LOG(ERR, "Unsupported action type %d\n", action_type);
+		rte_errno = ENOTSUP;
+		goto free_action;
+	}
+
+	if (ret) {
+		DR_LOG(ERR, "Failed to create IPv6 extension reformat action");
+		goto free_action;
+	}
+
+	return action;
+
+free_action:
+	simple_free(action);
+	return NULL;
+}
+
 static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 {
 	struct mlx5dr_devx_obj *obj = NULL;
@@ -2566,6 +2912,12 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)
 		mlx5dr_action_destroy_stcs(action);
 		mlx5dr_tmp_action_dest_ipsec_destroy_ste_arr(action->dest_ipsec.action_ste);
 		break;
+	case MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT:
+	case MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT:
+		for (i = 0; i < MLX5DR_ACTION_IPV6_EXT_MAX_SA; i++)
+			if (action->ipv6_route_ext.action[i])
+				mlx5dr_action_destroy(action->ipv6_route_ext.action[i]);
+		break;
 	}
 }
 
diff a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h	(rejected hunks)
@@ -143,6 +146,10 @@ struct mlx5dr_action {
 					uint8_t offset;
 					bool encap;
 				} reformat;
+				struct {
+					struct mlx5dr_action
+						*action[MLX5DR_ACTION_IPV6_EXT_MAX_SA];
+				} ipv6_route_ext;
 				struct {
 					struct mlx5dr_devx_obj *devx_obj;
 					uint8_t return_reg_id;
diff a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c	(rejected hunks)
@@ -32,6 +32,8 @@ const char *mlx5dr_debug_action_type_str[] = {
 	[MLX5DR_ACTION_TYP_INSERT_HEADER] = "INSERT_HEADER",
 	[MLX5DR_ACTION_TYP_REMOVE_HEADER] = "REMOVE_HEADER",
 	[MLX5DR_ACTION_TYP_DEST_IPSEC_DECRYPT] = "DEST_IPSEC_DECRYPT",
+	[MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = "POP_IPV6_ROUTE_EXT",
+	[MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = "PUSH_IPV6_ROUTE_EXT",
 };
 
 static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,
diff a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h	(rejected hunks)
@@ -3080,6 +3081,39 @@ flow_hw_get_srh_flex_parser_byte_off_from_ctx(void *dr_ctx)
 	return UINT32_MAX;
 }
 
+static __rte_always_inline uint8_t
+flow_hw_get_ipv6_route_ext_anchor_from_ctx(void *dr_ctx)
+{
+	uint16_t port;
+	struct mlx5_priv *priv;
+
+	MLX5_ETH_FOREACH_DEV(port, NULL) {
+		priv = rte_eth_devices[port].data->dev_private;
+		if (priv->dr_ctx == dr_ctx)
+			return priv->sh->srh_flex_parser.flex.devx_fp->anchor_id;
+	}
+	return 0;
+}
+
+static __rte_always_inline uint16_t
+flow_hw_get_ipv6_route_ext_mod_id_from_ctx(void *dr_ctx, uint8_t idx)
+{
+	uint16_t port;
+	struct mlx5_priv *priv;
+	struct mlx5_flex_parser_devx *fp;
+
+	if (idx >= MLX5_GRAPH_NODE_SAMPLE_NUM || idx >= MLX5_SRV6_SAMPLE_NUM)
+		return 0;
+	MLX5_ETH_FOREACH_DEV(port, NULL) {
+		priv = rte_eth_devices[port].data->dev_private;
+		if (priv->dr_ctx == dr_ctx) {
+			fp = priv->sh->srh_flex_parser.flex.devx_fp;
+			return fp->sample_info[idx].modify_field_id;
+		}
+	}
+	return 0;
+}
+
 struct mlx5_list_entry *
 flow_dv_sft_create_cb(void *tool_ctx __rte_unused, void *cb_ctx);
 int
Checking patch drivers/net/mlx5/hws/mlx5dr_action.c...
error: while searching for:
	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
}

int mlx5dr_action_template_process(struct mlx5dr_action_template *at)
{
	struct mlx5dr_actions_wqe_setter *start_setter = at->setters + 1;

error: patch failed: drivers/net/mlx5/hws/mlx5dr_action.c:3422
Hunk #2 succeeded at 2223 (offset -1377 lines).
Checking patch drivers/net/mlx5/hws/mlx5dr_action.h...
error: drivers/net/mlx5/hws/mlx5dr_action.h: does not match index
Applying patch drivers/net/mlx5/hws/mlx5dr_action.c with 1 reject...
Rejected hunk #1.
Hunk #2 applied cleanly.
hint: Use 'git am --show-current-patch' to see the failed patch
diff a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c	(rejected hunks)
@@ -3422,6 +3422,121 @@ mlx5dr_action_setter_reformat_trailer(struct mlx5dr_actions_apply_data *apply,
 	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;
 }
 
+static void
+mlx5dr_action_setter_ipv6_route_ext_gen_push_mhdr(uint8_t *data, void *mh_data)
+{
+	uint8_t *action_ptr = mh_data;
+	uint32_t *ipv6_dst_addr;
+	uint8_t seg_left;
+	uint32_t i;
+
+	/* Fetch the last IPv6 address in the segment list which is the next hop */
+	seg_left = MLX5_GET(header_ipv6_routing_ext, data, segments_left) - 1;
+	ipv6_dst_addr = (uint32_t *)data + MLX5_ST_SZ_DW(header_ipv6_routing_ext)
+			+ seg_left * MLX5_ST_SZ_DW(definer_hl_ipv6_addr);
+
+	/* Load next hop IPv6 address in reverse order to ipv6.dst_address */
+	for (i = 0; i < MLX5_ST_SZ_DW(definer_hl_ipv6_addr); i++) {
+		MLX5_SET(set_action_in, action_ptr, data, be32toh(*ipv6_dst_addr++));
+		action_ptr += MLX5DR_MODIFY_ACTION_SIZE;
+	}
+
+	/* Set ipv6_route_ext.next_hdr per user input */
+	MLX5_SET(set_action_in, action_ptr, data, *data);
+}
+
+static void
+mlx5dr_action_setter_ipv6_route_ext_mhdr(struct mlx5dr_actions_apply_data *apply,
+					 struct mlx5dr_actions_wqe_setter *setter)
+{
+	struct mlx5dr_rule_action *rule_action = apply->rule_action;
+	struct mlx5dr_actions_wqe_setter tmp_setter = {0};
+	struct mlx5dr_rule_action tmp_rule_action;
+	__be64 cmd[MLX5_SRV6_SAMPLE_NUM] = {0};
+	struct mlx5dr_action *ipv6_ext_action;
+	uint8_t *header;
+
+	header = rule_action[setter->idx_double].ipv6_ext.header;
+	ipv6_ext_action = rule_action[setter->idx_double].action;
+	tmp_rule_action.action = ipv6_ext_action->ipv6_route_ext.action[setter->extra_data];
+
+	if (tmp_rule_action.action->flags & MLX5DR_ACTION_FLAG_SHARED) {
+		tmp_rule_action.modify_header.offset = 0;
+		tmp_rule_action.modify_header.pattern_idx = 0;
+		tmp_rule_action.modify_header.data = NULL;
+	} else {
+		/*
+		 * Copy ipv6_dst from ipv6_route_ext.last_seg.
+		 * Set ipv6_route_ext.next_hdr.
+		 */
+		mlx5dr_action_setter_ipv6_route_ext_gen_push_mhdr(header, cmd);
+		tmp_rule_action.modify_header.data = (uint8_t *)cmd;
+		tmp_rule_action.modify_header.pattern_idx = 0;
+		tmp_rule_action.modify_header.offset =
+			rule_action[setter->idx_double].ipv6_ext.offset;
+	}
+
+	apply->rule_action = &tmp_rule_action;
+
+	/* Reuse regular */
+	mlx5dr_action_setter_modify_header(apply, &tmp_setter);
+
+	/* Swap rule actions from backup */
+	apply->rule_action = rule_action;
+}
+
+static void
+mlx5dr_action_setter_ipv6_route_ext_insert_ptr(struct mlx5dr_actions_apply_data *apply,
+					       struct mlx5dr_actions_wqe_setter *setter)
+{
+	struct mlx5dr_rule_action *rule_action = apply->rule_action;
+	struct mlx5dr_actions_wqe_setter tmp_setter = {0};
+	struct mlx5dr_rule_action tmp_rule_action;
+	struct mlx5dr_action *ipv6_ext_action;
+	uint8_t header[MLX5_PUSH_MAX_LEN];
+
+	ipv6_ext_action = rule_action[setter->idx_double].action;
+	tmp_rule_action.action = ipv6_ext_action->ipv6_route_ext.action[setter->extra_data];
+
+	if (tmp_rule_action.action->flags & MLX5DR_ACTION_FLAG_SHARED) {
+		tmp_rule_action.reformat.offset = 0;
+		tmp_rule_action.reformat.hdr_idx = 0;
+		tmp_rule_action.reformat.data = NULL;
+	} else {
+		memcpy(header, rule_action[setter->idx_double].ipv6_ext.header,
+		       tmp_rule_action.action->reformat.header_size);
+		/* Clear ipv6_route_ext.next_hdr for right checksum */
+		MLX5_SET(header_ipv6_routing_ext, header, next_hdr, 0);
+		tmp_rule_action.reformat.data = header;
+		tmp_rule_action.reformat.hdr_idx = 0;
+		tmp_rule_action.reformat.offset =
+			rule_action[setter->idx_double].ipv6_ext.offset;
+	}
+
+	apply->rule_action = &tmp_rule_action;
+
+	/* Reuse regular */
+	mlx5dr_action_setter_insert_ptr(apply, &tmp_setter);
+
+	/* Swap rule actions from backup */
+	apply->rule_action = rule_action;
+}
+
+static void
+mlx5dr_action_setter_ipv6_route_ext_pop(struct mlx5dr_actions_apply_data *apply,
+					struct mlx5dr_actions_wqe_setter *setter)
+{
+	struct mlx5dr_rule_action *rule_action = &apply->rule_action[setter->idx_single];
+	uint8_t idx = MLX5DR_ACTION_IPV6_EXT_MAX_SA - 1;
+	struct mlx5dr_action *action;
+
+	/* Pop the ipv6_route_ext as set_single logic */
+	action = rule_action->action->ipv6_route_ext.action[idx];
+	apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
+	apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] =
+		htobe32(action->stc[apply->tbl_type].offset);
+}
+
 int mlx5dr_action_template_process(struct mlx5dr_action_template *at)
 {
 	struct mlx5dr_actions_wqe_setter *start_setter = at->setters + 1;
Checking patch doc/guides/nics/features/default.ini...
error: while searching for:
flag                 =
inc_tcp_ack          =
inc_tcp_seq          =
jump                 =
mac_swap             =
mark                 =

error: patch failed: doc/guides/nics/features/default.ini:160
Checking patch doc/guides/nics/features/mlx5.ini...
Checking patch doc/guides/nics/mlx5.rst...
error: while searching for:
- Modify flex item field.
- Matching on random value.
- Send to kernel.

Limitations
-----------

error: patch failed: doc/guides/nics/mlx5.rst:112
error: while searching for:
  - Supports on non-root table.
  - Supports on isolated mode.
  - In HW steering (``dv_flow_en`` = 2):
    - not supported on guest port.

Statistics
----------

error: patch failed: doc/guides/nics/mlx5.rst:721
Checking patch drivers/net/mlx5/mlx5.h...
Hunk #1 succeeded at 373 (offset -37 lines).
Checking patch drivers/net/mlx5/mlx5_flow.h...
error: drivers/net/mlx5/mlx5_flow.h: does not match index
Checking patch drivers/net/mlx5/mlx5_flow_hw.c...
error: while searching for:
		mlx5_free(acts->encap_decap);
		acts->encap_decap = NULL;
	}
	if (acts->mhdr) {
		flow_hw_template_destroy_mhdr_action(acts->mhdr);
		mlx5_free(acts->mhdr);

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:641
Hunk #2 succeeded at 605 (offset -179 lines).
Hunk #3 succeeded at 1425 (offset -570 lines).
error: while searching for:
{
	struct mlx5_priv *priv = dev->data->dev_private;
	const struct rte_flow_template_table_attr *table_attr = &cfg->attr;
	const struct rte_flow_attr *attr = &table_attr->flow_attr;
	struct rte_flow_action *actions = at->actions;
	struct rte_flow_action *masks = at->masks;
	enum mlx5dr_action_type refmt_type = MLX5DR_ACTION_TYP_LAST;
	const struct rte_flow_action_raw_encap *raw_encap_data;
	const struct rte_flow_item *enc_item = NULL, *enc_item_m = NULL;
	uint16_t reformat_src = 0;
	uint8_t *encap_data = NULL, *encap_data_m = NULL;
	size_t data_size = 0;
	struct mlx5_hw_modify_header_action mhdr = { 0 };
	bool actions_end = false;
	uint32_t type;
	bool reformat_used = false;
	unsigned int of_vlan_offset;
	uint16_t jump_pos;
	uint32_t ct_idx;

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:1984
Hunk #5 succeeded at 1738 (offset -591 lines).
error: while searching for:
		if (ret)
			goto err;
	}
	return 0;
err:
	err = rte_errno;

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:2360
Hunk #7 succeeded at 2380 (offset -548 lines).
Hunk #8 succeeded at 2513 (offset -554 lines).
Hunk #9 succeeded at 2679 (offset -551 lines).
Hunk #10 succeeded at 4320 (offset -1128 lines).
error: while searching for:
#endif
	uint16_t i;
	int ret;

	/* FDB actions are only valid to proxy port. */
	if (attr->transfer && (!priv->sh->config.dv_esw_en || !priv->master))

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:5526
Hunk #12 succeeded at 4622 (offset -1210 lines).
error: while searching for:
	[RTE_FLOW_ACTION_TYPE_OF_POP_VLAN] = MLX5DR_ACTION_TYP_POP_VLAN,
	[RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = MLX5DR_ACTION_TYP_PUSH_VLAN,
	[RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL] = MLX5DR_ACTION_TYP_DEST_ROOT,
};

static inline void

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:5752
Hunk #14 succeeded at 4801 (offset -1278 lines).
Hunk #15 succeeded at 4811 (offset -1278 lines).
Hunk #16 succeeded at 4821 (offset -1278 lines).
Hunk #17 succeeded at 4854 (offset -1283 lines).
Hunk #18 succeeded at 4936 (offset -1287 lines).
error: while searching for:
		at->dr_off[i] = UINT16_MAX;
	at->reformat_off = UINT16_MAX;
	at->mhdr_off = UINT16_MAX;
	for (i = 0; ra[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
		const struct rte_flow_action_modify_field *info;


error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:6366
error: while searching for:
			break;
		}
	}
	at->tmpl = flow_hw_dr_actions_template_create(at);
	if (!at->tmpl)
		goto error;
	at->action_flags = action_flags;

error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:6393
Hunk #21 succeeded at 5393 (offset -1295 lines).
Hunk #22 succeeded at 5404 (offset -1295 lines).
Hunk #23 succeeded at 7953 (offset -1568 lines).
Hunk #24 succeeded at 7969 (offset -1568 lines).
Hunk #25 succeeded at 7989 (offset -1568 lines).
Applying patch doc/guides/nics/features/default.ini with 1 reject...
Rejected hunk #1.
Applied patch doc/guides/nics/features/mlx5.ini cleanly.
Applying patch doc/guides/nics/mlx5.rst with 2 rejects...
Rejected hunk #1.
Rejected hunk #2.
Applied patch drivers/net/mlx5/mlx5.h cleanly.
Applying patch drivers/net/mlx5/mlx5_flow_hw.c with 7 rejects...
Rejected hunk #1.
Hunk #2 applied cleanly.
Hunk #3 applied cleanly.
Rejected hunk #4.
Hunk #5 applied cleanly.
Rejected hunk #6.
Hunk #7 applied cleanly.
Hunk #8 applied cleanly.
Hunk #9 applied cleanly.
Hunk #10 applied cleanly.
Rejected hunk #11.
Hunk #12 applied cleanly.
Rejected hunk #13.
Hunk #14 applied cleanly.
Hunk #15 applied cleanly.
Hunk #16 applied cleanly.
Hunk #17 applied cleanly.
Hunk #18 applied cleanly.
Rejected hunk #19.
Rejected hunk #20.
Hunk #21 applied cleanly.
Hunk #22 applied cleanly.
Hunk #23 applied cleanly.
Hunk #24 applied cleanly.
Hunk #25 applied cleanly.
hint: Use 'git am --show-current-patch' to see the failed patch
diff a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini	(rejected hunks)
@@ -160,6 +160,8 @@ drop                 =
 flag                 =
 inc_tcp_ack          =
 inc_tcp_seq          =
+ipv6_ext_push        =
+ipv6_ext_remove      =
 jump                 =
 mac_swap             =
 mark                 =
diff a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst	(rejected hunks)
@@ -112,6 +112,7 @@ Features
 - Modify flex item field.
 - Matching on random value.
 - Send to kernel.
+- Push or remove IPv6 routing extension.
 
 Limitations
 -----------
@@ -721,7 +722,15 @@ Limitations
   - Supports on non-root table.
   - Supports on isolated mode.
   - In HW steering (``dv_flow_en`` = 2):
-    - not supported on guest port.
+  - not supported on guest port.
+
+- IPv6 routing extension push or remove:
+
+  - Supported only with HW Steering enabled (``dv_flow_en`` = 2).
+  - Supported in non-zero group (No limits on transfer domain if `fdb_def_rule_en` = 1 which is default).
+  - Only supports TCP or UDP as next layer.
+  - IPv6 routing header must be the only present extension.
+  - Not supported on guest port.
 
 Statistics
 ----------
diff a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c	(rejected hunks)
@@ -641,6 +641,12 @@ __flow_hw_action_template_destroy(struct rte_eth_dev *dev,
 		mlx5_free(acts->encap_decap);
 		acts->encap_decap = NULL;
 	}
+	if (acts->push_remove) {
+		if (acts->push_remove->action)
+			mlx5dr_action_destroy(acts->push_remove->action);
+		mlx5_free(acts->push_remove);
+		acts->push_remove = NULL;
+	}
 	if (acts->mhdr) {
 		flow_hw_template_destroy_mhdr_action(acts->mhdr);
 		mlx5_free(acts->mhdr);
@@ -1984,19 +2104,24 @@ __flow_hw_actions_translate(struct rte_eth_dev *dev,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const struct rte_flow_template_table_attr *table_attr = &cfg->attr;
+	struct mlx5_hca_flex_attr *hca_attr = &priv->sh->cdev->config.hca_attr.flex;
 	const struct rte_flow_attr *attr = &table_attr->flow_attr;
 	struct rte_flow_action *actions = at->actions;
 	struct rte_flow_action *masks = at->masks;
 	enum mlx5dr_action_type refmt_type = MLX5DR_ACTION_TYP_LAST;
+	enum mlx5dr_action_type recom_type = MLX5DR_ACTION_TYP_LAST;
 	const struct rte_flow_action_raw_encap *raw_encap_data;
+	const struct rte_flow_action_ipv6_ext_push *ipv6_ext_data;
 	const struct rte_flow_item *enc_item = NULL, *enc_item_m = NULL;
-	uint16_t reformat_src = 0;
+	uint16_t reformat_src = 0, recom_src = 0;
 	uint8_t *encap_data = NULL, *encap_data_m = NULL;
-	size_t data_size = 0;
+	uint8_t *push_data = NULL, *push_data_m = NULL;
+	size_t data_size = 0, push_size = 0;
 	struct mlx5_hw_modify_header_action mhdr = { 0 };
 	bool actions_end = false;
 	uint32_t type;
 	bool reformat_used = false;
+	bool recom_used = false;
 	unsigned int of_vlan_offset;
 	uint16_t jump_pos;
 	uint32_t ct_idx;
@@ -2360,6 +2515,14 @@ __flow_hw_actions_translate(struct rte_eth_dev *dev,
 		if (ret)
 			goto err;
 	}
+	if (recom_used) {
+		MLX5_ASSERT(at->recom_off != UINT16_MAX);
+		ret = mlx5_create_ipv6_ext_reformat(dev, cfg, acts, at, push_data,
+						    push_data_m, push_size, recom_src,
+						    recom_type);
+		if (ret)
+			goto err;
+	}
 	return 0;
 err:
 	err = rte_errno;
@@ -5526,6 +5735,7 @@ mlx5_flow_hw_actions_validate(struct rte_eth_dev *dev,
 #endif
 	uint16_t i;
 	int ret;
+	const struct rte_flow_action_ipv6_ext_remove *remove_data;
 
 	/* FDB actions are only valid to proxy port. */
 	if (attr->transfer && (!priv->sh->config.dv_esw_en || !priv->master))
@@ -5752,6 +5977,8 @@ static enum mlx5dr_action_type mlx5_hw_dr_action_types[] = {
 	[RTE_FLOW_ACTION_TYPE_OF_POP_VLAN] = MLX5DR_ACTION_TYP_POP_VLAN,
 	[RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = MLX5DR_ACTION_TYP_PUSH_VLAN,
 	[RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL] = MLX5DR_ACTION_TYP_DEST_ROOT,
+	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH] = MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,
+	[RTE_FLOW_ACTION_TYPE_IPV6_EXT_REMOVE] = MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,
 };
 
 static inline void
@@ -6366,6 +6623,7 @@ flow_hw_actions_template_create(struct rte_eth_dev *dev,
 		at->dr_off[i] = UINT16_MAX;
 	at->reformat_off = UINT16_MAX;
 	at->mhdr_off = UINT16_MAX;
+	at->recom_off = UINT16_MAX;
 	for (i = 0; ra[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
 		const struct rte_flow_action_modify_field *info;
 
@@ -6393,7 +6651,7 @@ flow_hw_actions_template_create(struct rte_eth_dev *dev,
 			break;
 		}
 	}
-	at->tmpl = flow_hw_dr_actions_template_create(at);
+	at->tmpl = flow_hw_dr_actions_template_create(dev, at);
 	if (!at->tmpl)
 		goto error;
 	at->action_flags = action_flags;

https://lab.dpdk.org/results/dashboard/patchsets/27756/

UNH-IOL DPDK Community Lab


More information about the test-report mailing list