From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id EA2C941F51;
	Sun,  9 Jun 2024 13:01:52 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 2E97040B9F;
	Sun,  9 Jun 2024 13:01:41 +0200 (CEST)
Received: from NAM02-DM3-obe.outbound.protection.outlook.com
 (mail-dm3nam02on2088.outbound.protection.outlook.com [40.107.95.88])
 by mails.dpdk.org (Postfix) with ESMTP id 7789940B94
 for <dev@dpdk.org>; Sun,  9 Jun 2024 13:01:37 +0200 (CEST)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=XzzLx9sPKBDA/t5Y6ABrUK31kQ3oCpmtBeJvpXaiFOzQA4oI2VycCJBBDsN26+TFB0RkubWL3yXZsz079p430zK6/vZribl6e2SsfDQGcZ6npI6wKOu2V630hV/QX5N8o2b60LPrmy6CPGrB5pig9PvcuP80wP6U1L1kMCu21K65JRCsiKG4g0ek/TBFdE2QsgiZFgQ1D3VsP05s3wjR0s57433a0nsh2yXq9kLfpX/HaSdqhlxrQ0eD5cbvG3WJLyi7vyxy+2VundquBNVM/yoYe/mkGKA67hVJszAA6hkxZOjW57pShcL/EYK23DmxmoEeB1cwzpvESx8CoCHRIA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
 bh=HzK7q/pBTetDPH0NFeBETqki7StnE4dnwSmW6CuQPxA=;
 b=oTpm78LIOA2TUR9n8/s1T14Gwb8hsRGxQkvTsJyixPPQLiayrcoFL74AkdYx29fXJKCq2cSXEAclj3PX8JM3VYrNXl/WFaZk69Do/lIeQS4TZeG9MdubfP2vNfAQKis2mdPawhxapB2THxOcFRXRt2BxMHyW+tK/OGB59nhRNquELU2NfyEwvrYKeEPCdR0KAEt0Aa5mRl1xZUUiTSXFeUMoMKXX4N132yO/MQV+3micVkqfiwCRfpcj7COMQDKa6rYy7Nq1qvXDM2SbbsW0gLVqBgxDuFQpOhoMpuhy4VEHz5wt3tvOwehwxM6XMZN3vY4DnA//xy4HUHddurovCg==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is
 216.228.118.233) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com;
 dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;
 dkim=none (message not signed); arc=none (0)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;
 s=selector2;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=HzK7q/pBTetDPH0NFeBETqki7StnE4dnwSmW6CuQPxA=;
 b=F+NeZd0idlFq1wWcXeTobI9qTC3wzVr8mjDxLeKhuhKfGnV8+pVp3XSfkPjkSOadwwQPG0zLEL8mJcEBTXuzzsif3d0NMjfgQoxGiDcoht9DFaUpPzlSexT3UCEgWoVXwJrgT1Al3uuq7DXUie7kQ83A69xlbMt6E2CzW9rDWWAExUZOsNdgP7B/b+KmUQiMa22yLaTX2XsB0mjJhe4RJTc3T4YXEZNzRc3DYavNNJ/bK8cGuLAbJ89OM6fH1CeAHjIC0ITEa0L23U2VefsIAzl2QGRb/XxYI2/SwE51GyaRKjXs/9iZSuIfY7i0PakxKJb9Qq3/2fWpXF1dWsdiDg==
Received: from BL1PR13CA0350.namprd13.prod.outlook.com (2603:10b6:208:2c6::25)
 by DM4PR12MB6037.namprd12.prod.outlook.com (2603:10b6:8:b0::11) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7633.36; Sun, 9 Jun
 2024 11:01:34 +0000
Received: from BL02EPF0001A104.namprd05.prod.outlook.com
 (2603:10b6:208:2c6:cafe::e) by BL1PR13CA0350.outlook.office365.com
 (2603:10b6:208:2c6::25) with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7677.15 via Frontend
 Transport; Sun, 9 Jun 2024 11:01:34 +0000
X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.233)
 smtp.mailfrom=nvidia.com;
 dkim=none (message not signed)
 header.d=none;dmarc=pass action=none header.from=nvidia.com;
Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates
 216.228.118.233 as permitted sender) receiver=protection.outlook.com;
 client-ip=216.228.118.233; helo=mail.nvidia.com; pr=C
Received: from mail.nvidia.com (216.228.118.233) by
 BL02EPF0001A104.mail.protection.outlook.com (10.167.241.135) with Microsoft
 SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.20.7677.15 via Frontend Transport; Sun, 9 Jun 2024 11:01:34 +0000
Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com
 (10.127.129.6) with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Sun, 9 Jun 2024
 04:01:21 -0700
Received: from drhqmail201.nvidia.com (10.126.190.180) by
 drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.4; Sun, 9 Jun 2024 04:01:21 -0700
Received: from nvidia.com (10.127.8.14) by mail.nvidia.com (10.126.190.180)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4 via Frontend
 Transport; Sun, 9 Jun 2024 04:01:19 -0700
From: Maayan Kashani <mkashani@nvidia.com>
To: <dev@dpdk.org>
CC: <mkashani@nvidia.com>, <dsosnowski@nvidia.com>, <rasland@nvidia.com>,
 "Bing Zhao" <bingz@nvidia.com>, Viacheslav Ovsiienko
 <viacheslavo@nvidia.com>, "Ori Kam" <orika@nvidia.com>, Suanming Mou
 <suanmingm@nvidia.com>, Matan Azrad <matan@nvidia.com>
Subject: [PATCH v7 03/11] net/mlx5: add basic actions support for non-template
 API
Date: Sun, 9 Jun 2024 14:00:59 +0300
Message-ID: <20240609110107.92009-3-mkashani@nvidia.com>
X-Mailer: git-send-email 2.21.0
In-Reply-To: <20240609110107.92009-1-mkashani@nvidia.com>
References: <20240609085600.87274-1-mkashani@nvidia.com>
 <20240609110107.92009-1-mkashani@nvidia.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain
X-NV-OnPremToCloud: ExternallySecured
X-EOPAttributedMessage: 0
X-MS-PublicTrafficType: Email
X-MS-TrafficTypeDiagnostic: BL02EPF0001A104:EE_|DM4PR12MB6037:EE_
X-MS-Office365-Filtering-Correlation-Id: f2b4273c-2c5f-4b6f-df9d-08dc887386fb
X-MS-Exchange-SenderADCheck: 1
X-MS-Exchange-AntiSpam-Relay: 0
X-Microsoft-Antispam: BCL:0;
 ARA:13230031|82310400017|376005|36860700004|1800799015; 
X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?h0QE9WH23GjfV1zrgnNUZYvFYFscMjBczCofoRUW2tNjPTuiJZrGqk1JZtVX?=
 =?us-ascii?Q?kkZomuPubFFQosnoMetqKunR4L94QCdzsgoZk+Ny8Gbs/GP6E7X3bQpyAb7S?=
 =?us-ascii?Q?iV7ylOqPxIX0SSlt/1R5/Am0dyhxG8n7nar9iCVGuzrc9rst+GKbfJCPRygD?=
 =?us-ascii?Q?bWpyfrrFX1xz2Rvo5KaPBKlEHuLSSdzOxUDyEww/zGG8WE2XdF3fKDZSYabe?=
 =?us-ascii?Q?LCtJz0jS7sn0qP1xCpOvzokUfPpWanqQMGTnxOnWrN0s4v4Dm/+fJ+zJU9/f?=
 =?us-ascii?Q?7AtwEp/X/NdKGeTRm9/WWtjFbs428AzmmiO/A8WHEsPLx0VmnlKQ8e4ul8Pw?=
 =?us-ascii?Q?7ipeNMrcRZ8pGMzko3Y0jHMnSGZmKVB+ZHOzEhXvn96IkizjCy1KRXYvsB0t?=
 =?us-ascii?Q?0zpUZfRntiRSv3sqVpbL9oPse6T2LR6ukVcYgtyG0m3WJXW8SYfUzKZqg8bt?=
 =?us-ascii?Q?De4XbDQhboE6muTU1OFGN4PLHDzoP7W1D4HRWqMUUnPArXJQ6znfy92JynS3?=
 =?us-ascii?Q?FQQQ61clRREKekJHOeNgMrfkfw7SfvfTsNgqPt4rU+BTo3pd7RylJIQz47P9?=
 =?us-ascii?Q?v2xGyIetRU9wZ4SNVI/6vXD04z84kJn9fdnCZitk/03dS49gWD1aMqoQx4h7?=
 =?us-ascii?Q?KJxo57vbtL1OEDjVBgWK0jJ4VvN3q/Ge+HcpAo2NiL1gI6v7mH6YPuadNwJs?=
 =?us-ascii?Q?lfr2Fgl5cssy4Jk8JHDwDF92CCAE5tOlh6P93FcrxK6s8XiwdjVbiDV/JmpG?=
 =?us-ascii?Q?B6G4CM7HZ/o4SsQbfxZ6ny6GHY+JqRr4YgudGMnkQfCnb5puaa6kyF7MEJJV?=
 =?us-ascii?Q?5O++gcBmrsr4dOa7wNw3ezPpS/tsZ5NsFln+lJqWa/NFdFSFzxEtmqapa6cp?=
 =?us-ascii?Q?TkHUyRN+jzK22u9rWcfO75+FBjXigWHGrRrq2rIwaNmSE7UY+/FFPiY5Ivlc?=
 =?us-ascii?Q?6pQEgPnRFHi9H+uF5zHBRFtHRNH1cElODZdFsHOJYU+m+o0s6x8g7w7F4Dt1?=
 =?us-ascii?Q?NQeAG2xpdDi3IqwNUfUoIfGPNVXiyDybmn/N1gk9lVqjSonlnR5ulRXYdEmS?=
 =?us-ascii?Q?9PX4v4w22/Zoa7Cwz0Ukr7h03uKOOqBFp3i5dZckW+3QwJKLfjumjXUGdVNw?=
 =?us-ascii?Q?T6FQznK0QmnczyjzyuK1KOlYOqQFZDduTJ1D8P2og23sEtT52x0Qb6pHF+RQ?=
 =?us-ascii?Q?DGhc5qljk1o1e2oC+l/wQ65Yn5z7q8PO8nLe7RDx2GFixU064BevESLWfLha?=
 =?us-ascii?Q?F9lTv05lTKEYiQ+U6636NrkCkNQ4lhq3fKOT7ZehQOWtvt8+wOuxqp3Y3qdg?=
 =?us-ascii?Q?kgO4n2nlcDWtEnQvpXg5myP4cOqjERNBqyrdil3pnJf15aKkDMBULqlkZqJL?=
 =?us-ascii?Q?N31LerrdZ993ofWpZ+Z4LHgMpKRooxsnmDb8oqbaIDGE6Ohjzw=3D=3D?=
X-Forefront-Antispam-Report: CIP:216.228.118.233; CTRY:US; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc7edge2.nvidia.com; CAT:NONE;
 SFS:(13230031)(82310400017)(376005)(36860700004)(1800799015); DIR:OUT;
 SFP:1101; 
X-OriginatorOrg: Nvidia.com
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jun 2024 11:01:34.5163 (UTC)
X-MS-Exchange-CrossTenant-Network-Message-Id: f2b4273c-2c5f-4b6f-df9d-08dc887386fb
X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a
X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.118.233];
 Helo=[mail.nvidia.com]
X-MS-Exchange-CrossTenant-AuthSource: BL02EPF0001A104.namprd05.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Anonymous
X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6037
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

From: Bing Zhao <bingz@nvidia.com>

Support JUMP / DROP / QUEUE / MARK / FLAG now.

Signed-off-by: Bing Zhao <bingz@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c | 154 ++++++++++++++++++++++++++++----
 1 file changed, 136 insertions(+), 18 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 5f1e93c3aad..fe75b8fd07c 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -546,8 +546,7 @@ flow_hw_jump_release(struct rte_eth_dev *dev, struct mlx5_hw_jump_action *jump)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_flow_group *grp;
 
-	grp = container_of
-		(jump, struct mlx5_flow_group, jump);
+	grp = container_of(jump, struct mlx5_flow_group, jump);
 	mlx5_hlist_unregister(priv->sh->flow_tbls, &grp->entry);
 }
 
@@ -647,17 +646,9 @@ flow_hw_template_destroy_mhdr_action(struct mlx5_hw_modify_header_action *mhdr)
  *   Pointer to the template HW steering DR actions.
  */
 static void
-__flow_hw_action_template_destroy(struct rte_eth_dev *dev,
-				 struct mlx5_hw_actions *acts)
+__flow_hw_actions_release(struct rte_eth_dev *dev, struct mlx5_hw_actions *acts)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_action_construct_data *data;
-
-	while (!LIST_EMPTY(&acts->act_list)) {
-		data = LIST_FIRST(&acts->act_list);
-		LIST_REMOVE(data, next);
-		mlx5_ipool_free(priv->acts_ipool, data->idx);
-	}
 
 	if (acts->mark)
 		if (!(rte_atomic_fetch_sub_explicit(&priv->hws_mark_refcnt, 1,
@@ -702,6 +693,32 @@ __flow_hw_action_template_destroy(struct rte_eth_dev *dev,
 	}
 }
 
+/**
+ * Destroy DR actions created by action template.
+ *
+ * For DR actions created during table creation's action translate.
+ * Need to destroy the DR action when destroying the table.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] acts
+ *   Pointer to the template HW steering DR actions.
+ */
+static void
+__flow_hw_action_template_destroy(struct rte_eth_dev *dev, struct mlx5_hw_actions *acts)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_action_construct_data *data;
+
+	while (!LIST_EMPTY(&acts->act_list)) {
+		data = LIST_FIRST(&acts->act_list);
+		LIST_REMOVE(data, next);
+		mlx5_ipool_free(priv->acts_ipool, data->idx);
+	}
+
+	__flow_hw_actions_release(dev, acts);
+}
+
 /**
  * Append dynamic action to the dynamic action list.
  *
@@ -12690,14 +12707,114 @@ static int flow_hw_prepare(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static int flow_hw_translate_actions(struct rte_eth_dev *dev __rte_unused,
-					const struct rte_flow_attr *attr __rte_unused,
-					const struct rte_flow_action actions[] __rte_unused,
-					struct rte_flow_hw *flow __rte_unused,
-					struct rte_flow_error *error __rte_unused)
+static int
+flow_hw_translate_actions(struct rte_eth_dev *dev,
+			  const struct rte_flow_attr *attr,
+			  const struct rte_flow_action actions[],
+			  struct rte_flow_hw *flow,
+			  struct mlx5_hw_actions *hw_acts,
+			  bool external,
+			  struct rte_flow_error *error)
 {
-	/* TODO implement */
+	struct mlx5_priv *priv = dev->data->dev_private;
+	enum mlx5dr_table_type type;
+	enum mlx5_hw_action_flag_type flag_type;
+	bool actions_end = false;
+	uint64_t action_flags = 0; /* to be used when needed */
+	uint32_t actions_n = 0;
+	uint32_t mark_id;
+	uint32_t jump_group;
+	bool is_mark;
+	struct mlx5_flow_template_table_cfg tbl_cfg;
+	enum mlx5_flow_fate_type fate_type = MLX5_FLOW_FATE_NONE;
+
+	RTE_SET_USED(action_flags);
+	if (attr->transfer)
+		type = MLX5DR_TABLE_TYPE_FDB;
+	else if (attr->egress)
+		type = MLX5DR_TABLE_TYPE_NIC_TX;
+	else
+		type = MLX5DR_TABLE_TYPE_NIC_RX;
+	/* The group in the attribute translation was done in advance. */
+	flag_type = (attr->group == 0) ? MLX5_HW_ACTION_FLAG_ROOT :
+					 MLX5_HW_ACTION_FLAG_NONE_ROOT;
+	for (; !actions_end; actions++) {
+		switch (actions->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_DROP:
+			hw_acts->rule_acts[actions_n++].action = priv->hw_drop[flag_type];
+			fate_type = MLX5_FLOW_FATE_DROP;
+			break;
+		case RTE_FLOW_ACTION_TYPE_FLAG:
+		case RTE_FLOW_ACTION_TYPE_MARK:
+			is_mark = actions->type == RTE_FLOW_ACTION_TYPE_MARK;
+			mark_id = is_mark ?
+				  ((const struct rte_flow_action_mark *)(actions->conf))->id :
+				  MLX5_FLOW_MARK_DEFAULT;
+			hw_acts->rule_acts[actions_n].tag.value = mlx5_flow_mark_set(mark_id);
+			hw_acts->rule_acts[actions_n].action = priv->hw_tag[flag_type];
+			actions_n++;
+			action_flags |= is_mark ? MLX5_FLOW_ACTION_MARK : MLX5_FLOW_ACTION_FLAG;
+			hw_acts->mark = true;
+			rte_atomic_fetch_add_explicit(&priv->hws_mark_refcnt, 1,
+						      rte_memory_order_relaxed);
+			flow_hw_rxq_flag_set(dev, true);
+			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP:
+			jump_group = ((const struct rte_flow_action_jump *)actions->conf)->group;
+			tbl_cfg.attr.flow_attr = *attr;
+			tbl_cfg.external = external;
+			/* The flow_hw_jump_action_register() can be refactored. */
+			hw_acts->jump = flow_hw_jump_action_register(dev, &tbl_cfg,
+								     jump_group, error);
+			if (hw_acts->jump == NULL)
+				goto clean_up;
+			hw_acts->rule_acts[actions_n++].action =
+				(flag_type == MLX5_HW_ACTION_FLAG_NONE_ROOT) ?
+				hw_acts->jump->hws_action : hw_acts->jump->root_action;
+			action_flags |= MLX5_FLOW_ACTION_JUMP;
+			fate_type = MLX5_FLOW_FATE_JUMP;
+			break;
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+			/* Right now, only Rx supports the TIR, validation is needed. */
+			hw_acts->tir = flow_hw_tir_action_register(dev,
+						mlx5_hw_act_flag[flag_type][type], actions);
+			if (hw_acts->tir == NULL) {
+				rte_flow_error_set(error, EINVAL,
+						   RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+						   "Failed to translate queue.");
+				goto clean_up;
+			}
+			action_flags |= MLX5_FLOW_ACTION_QUEUE;
+			fate_type = MLX5_FLOW_FATE_QUEUE;
+			break;
+		case RTE_FLOW_ACTION_TYPE_END:
+			/*
+			 * Using NULL action right now, maybe a new API can be used
+			 * to create a dummy action with type MLX5DR_ACTION_TYP_LAST.
+			 */
+			hw_acts->rule_acts[actions_n++].action = priv->sh->hw_dummy_last;
+			actions_end = true;
+			break;
+		default:
+			break;
+		}
+	}
+	if (fate_type == MLX5_FLOW_FATE_QUEUE) {
+		hw_acts->rule_acts[actions_n++].action = hw_acts->tir->action;
+		flow->hrxq = hw_acts->tir;
+	} else {
+		if (fate_type == MLX5_FLOW_FATE_JUMP)
+			flow->jump = hw_acts->jump;
+	}
+	/* Total actions number should be validated before. */
+	MLX5_ASSERT(actions_n <= MLX5_HW_MAX_ACTS);
 	return 0;
+clean_up:
+	/* Make sure that there is no garbage in the actions. */
+	__flow_hw_actions_release(dev, hw_acts);
+	return -rte_errno;
 }
 
 static int flow_hw_register_matcher(struct rte_eth_dev *dev,
@@ -12891,7 +13008,8 @@ static int flow_hw_create_flow(struct rte_eth_dev *dev,
 	if (ret)
 		goto error;
 
-	ret = flow_hw_translate_actions(dev, attr, actions, *flow, error);
+	/* Note: the actions should be saved in the sub-flow rule itself for reference. */
+	ret = flow_hw_translate_actions(dev, attr, actions, *flow, &hw_act, external, error);
 	if (ret)
 		goto error;
 
-- 
2.21.0