diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2f57759..f533f78 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3440,8 +3440,18 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 	dev_flow->external = external;
 	/* Subflow object was created, we must include one in the list. */
 	LIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next);
-	if (prefix_flow)
+	if (prefix_flow) {
+		/*
+		 * Some suffix subflow need the item flags and decap action
+		 * flag to know if actions in suffix flow should be applied
+		 * to new outer layer or not.
+		 * Action flag will be overwritten in tanslate after using.
+		 * No need to copy the hash_fields, as it will be generated
+		 * by RSS action with the item layer flags.
+		 */
 		dev_flow->layers = prefix_flow->layers;
+		dev_flow->actions = prefix_flow->actions;
+	}
 	if (sub_flow)
 		*sub_flow = dev_flow;
 	return flow_drv_translate(dev, dev_flow, attr, items, actions, error);
@@ -3737,6 +3747,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
  *   Pointer to Ethernet device.
  * @param[in] flow
  *   Parent flow structure pointer.
+ * @param[in] prefix_flow
+ *   Prefix flow structure pointer.
  * @param[in] attr
  *   Flow rule attributes.
  * @param[in] items
@@ -3753,6 +3765,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 static int
 flow_create_split_metadata(struct rte_eth_dev *dev,
 			   struct rte_flow *flow,
+			   struct mlx5_flow *prefix_flow,
 			   const struct rte_flow_attr *attr,
 			   const struct rte_flow_item items[],
 			   const struct rte_flow_action actions[],
@@ -3773,7 +3786,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 	if (!config->dv_flow_en ||
 	    config->dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
 	    !mlx5_flow_ext_mreg_supported(dev))
-		return flow_create_split_inner(dev, flow, NULL, NULL,
+		return flow_create_split_inner(dev, flow, NULL, prefix_flow,
 					       attr, items, actions, external,
 					       error);
 	actions_n = flow_parse_qrss_action(actions, &qrss);
@@ -3856,7 +3869,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 			goto exit;
 	}
 	/* Add the unmodified original or prefix subflow. */
-	ret = flow_create_split_inner(dev, flow, &dev_flow, NULL, attr,
+	ret = flow_create_split_inner(dev, flow, &dev_flow, prefix_flow, attr,
 				      items, ext_actions ? ext_actions :
 				      actions, external, error);
 	if (ret < 0)
@@ -3892,7 +3905,6 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 				.type = RTE_FLOW_ACTION_TYPE_END,
 			},
 		};
-		struct mlx5_flow *prefix_flow;
 
 		/*
 		 * Configure the tag item only if there is no meter subflow.
@@ -4052,7 +4064,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 				 MLX5_FLOW_TABLE_LEVEL_SUFFIX;
 	}
 	/* Add the prefix subflow. */
-	ret = flow_create_split_metadata(dev, flow, &sfx_attr,
+	ret = flow_create_split_metadata(dev, flow, dev_flow, &sfx_attr,
 					 sfx_items ? sfx_items : items,
 					 sfx_actions ? sfx_actions : actions,
 					 external, error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index c958fca..359a037 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -85,16 +85,44 @@
  *   Pointer to item specification.
  * @param[out] attr
  *   Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ *   Pointer to the sub flow.
  * @param[in] tunnel_decap
  *   Whether action is after tunnel decapsulation.
  */
 static void
 flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
-		  bool tunnel_decap)
+		  struct mlx5_flow *dev_flow, bool tunnel_decap)
 {
+	if (dev_flow->layers) {
+		if (dev_flow->actions & MLX5_FLOW_ACTION_DECAP) {
+			if (dev_flow->layers & MLX5_FLOW_LAYER_INNER_L3_IPV4)
+				attr->ipv4 = 1;
+			else if (dev_flow->layers &
+				 MLX5_FLOW_LAYER_INNER_L3_IPV6)
+				attr->ipv6 = 1;
+			if (dev_flow->layers & MLX5_FLOW_LAYER_INNER_L4_TCP)
+				attr->tcp = 1;
+			else if (dev_flow->layers &
+				 MLX5_FLOW_LAYER_INNER_L4_UDP)
+				attr->udp = 1;
+		} else {
+			if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L3_IPV4)
+				attr->ipv4 = 1;
+			else if (dev_flow->layers &
+				 MLX5_FLOW_LAYER_OUTER_L3_IPV6)
+				attr->ipv6 = 1;
+			if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L4_TCP)
+				attr->tcp = 1;
+			else if (dev_flow->layers &
+				 MLX5_FLOW_LAYER_OUTER_L4_UDP)
+				attr->udp = 1;
+		}
+		attr->valid = 1;
+		return;
+	}
 	for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		uint8_t next_protocol = 0xff;
-
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_GRE:
 		case RTE_FLOW_ITEM_TYPE_NVGRE:
@@ -640,6 +668,8 @@ struct field_modify_info modify_tcp[] = {
  *   Pointer to rte_flow_item objects list.
  * @param[in] attr
  *   Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ *   Pointer to the sub flow.
  * @param[in] tunnel_decap
  *   Whether action is after tunnel decapsulation.
  * @param[out] error
@@ -653,8 +683,8 @@ struct field_modify_info modify_tcp[] = {
 			(struct mlx5_flow_dv_modify_hdr_resource *resource,
 			 const struct rte_flow_action *action,
 			 const struct rte_flow_item *items,
-			 union flow_dv_attr *attr, bool tunnel_decap,
-			 struct rte_flow_error *error)
+			 union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+			 bool tunnel_decap, struct rte_flow_error *error)
 {
 	const struct rte_flow_action_set_tp *conf =
 		(const struct rte_flow_action_set_tp *)(action->conf);
@@ -666,7 +696,7 @@ struct field_modify_info modify_tcp[] = {
 	struct field_modify_info *field;
 
 	if (!attr->valid)
-		flow_dv_attr_init(items, attr, tunnel_decap);
+		flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
 	if (attr->udp) {
 		memset(&udp, 0, sizeof(udp));
 		memset(&udp_mask, 0, sizeof(udp_mask));
@@ -716,6 +746,8 @@ struct field_modify_info modify_tcp[] = {
  *   Pointer to rte_flow_item objects list.
  * @param[in] attr
  *   Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ *   Pointer to the sub flow.
  * @param[in] tunnel_decap
  *   Whether action is after tunnel decapsulation.
  * @param[out] error
@@ -729,8 +761,8 @@ struct field_modify_info modify_tcp[] = {
 			(struct mlx5_flow_dv_modify_hdr_resource *resource,
 			 const struct rte_flow_action *action,
 			 const struct rte_flow_item *items,
-			 union flow_dv_attr *attr, bool tunnel_decap,
-			 struct rte_flow_error *error)
+			 union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+			 bool tunnel_decap, struct rte_flow_error *error)
 {
 	const struct rte_flow_action_set_ttl *conf =
 		(const struct rte_flow_action_set_ttl *)(action->conf);
@@ -742,7 +774,7 @@ struct field_modify_info modify_tcp[] = {
 	struct field_modify_info *field;
 
 	if (!attr->valid)
-		flow_dv_attr_init(items, attr, tunnel_decap);
+		flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
 	if (attr->ipv4) {
 		memset(&ipv4, 0, sizeof(ipv4));
 		memset(&ipv4_mask, 0, sizeof(ipv4_mask));
@@ -778,6 +810,8 @@ struct field_modify_info modify_tcp[] = {
  *   Pointer to rte_flow_item objects list.
  * @param[in] attr
  *   Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ *   Pointer to the sub flow.
  * @param[in] tunnel_decap
  *   Whether action is after tunnel decapsulation.
  * @param[out] error
@@ -790,8 +824,8 @@ struct field_modify_info modify_tcp[] = {
 flow_dv_convert_action_modify_dec_ttl
 			(struct mlx5_flow_dv_modify_hdr_resource *resource,
 			 const struct rte_flow_item *items,
-			 union flow_dv_attr *attr, bool tunnel_decap,
-			 struct rte_flow_error *error)
+			 union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+			 bool tunnel_decap, struct rte_flow_error *error)
 {
 	struct rte_flow_item item;
 	struct rte_flow_item_ipv4 ipv4;
@@ -801,7 +835,7 @@ struct field_modify_info modify_tcp[] = {
 	struct field_modify_info *field;
 
 	if (!attr->valid)
-		flow_dv_attr_init(items, attr, tunnel_decap);
+		flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
 	if (attr->ipv4) {
 		memset(&ipv4, 0, sizeof(ipv4));
 		memset(&ipv4_mask, 0, sizeof(ipv4_mask));
@@ -7505,7 +7539,7 @@ struct field_modify_info modify_tcp[] = {
 		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
 			if (flow_dv_convert_action_modify_tp
 					(mhdr_res, actions, items,
-					 &flow_attr, !!(action_flags &
+					 &flow_attr, dev_flow, !!(action_flags &
 					 MLX5_FLOW_ACTION_DECAP), error))
 				return -rte_errno;
 			action_flags |= actions->type ==
@@ -7515,7 +7549,7 @@ struct field_modify_info modify_tcp[] = {
 			break;
 		case RTE_FLOW_ACTION_TYPE_DEC_TTL:
 			if (flow_dv_convert_action_modify_dec_ttl
-					(mhdr_res, items, &flow_attr,
+					(mhdr_res, items, &flow_attr, dev_flow,
 					 !!(action_flags &
 					 MLX5_FLOW_ACTION_DECAP), error))
 				return -rte_errno;
@@ -7524,7 +7558,7 @@ struct field_modify_info modify_tcp[] = {
 		case RTE_FLOW_ACTION_TYPE_SET_TTL:
 			if (flow_dv_convert_action_modify_ttl
 					(mhdr_res, actions, items, &flow_attr,
-					 !!(action_flags &
+					 dev_flow, !!(action_flags &
 					 MLX5_FLOW_ACTION_DECAP), error))
 				return -rte_errno;
 			action_flags |= MLX5_FLOW_ACTION_SET_TTL;
