get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/136925/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 136925,
    "url": "http://patches.dpdk.org/api/patches/136925/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20240220141008.292641-2-bingz@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20240220141008.292641-2-bingz@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240220141008.292641-2-bingz@nvidia.com",
    "date": "2024-02-20T14:10:04",
    "name": "[v2,1/5] net/mlx5/hws: support NAT64 action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8a5dea6430ab42fee3ec64e91efd93d188827437",
    "submitter": {
        "id": 1976,
        "url": "http://patches.dpdk.org/api/people/1976/?format=api",
        "name": "Bing Zhao",
        "email": "bingz@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20240220141008.292641-2-bingz@nvidia.com/mbox/",
    "series": [
        {
            "id": 31154,
            "url": "http://patches.dpdk.org/api/series/31154/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=31154",
            "date": "2024-02-20T14:10:03",
            "name": "NAT64 support in mlx5 PMD",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/31154/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/136925/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/136925/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 573B643B54;\n\tTue, 20 Feb 2024 15:11:01 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 48DCE40695;\n\tTue, 20 Feb 2024 15:11:01 +0100 (CET)",
            "from NAM10-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam10on2044.outbound.protection.outlook.com [40.107.93.44])\n by mails.dpdk.org (Postfix) with ESMTP id 9F1A440691\n for <dev@dpdk.org>; Tue, 20 Feb 2024 15:11:00 +0100 (CET)",
            "from BYAPR01CA0046.prod.exchangelabs.com (2603:10b6:a03:94::23) by\n CH0PR12MB5073.namprd12.prod.outlook.com (2603:10b6:610:e0::10) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.7316.20; Tue, 20 Feb 2024 14:10:58 +0000",
            "from SJ5PEPF000001CD.namprd05.prod.outlook.com\n (2603:10b6:a03:94:cafe::f6) by BYAPR01CA0046.outlook.office365.com\n (2603:10b6:a03:94::23) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7292.40 via Frontend\n Transport; Tue, 20 Feb 2024 14:10:57 +0000",
            "from mail.nvidia.com (216.228.117.160) by\n SJ5PEPF000001CD.mail.protection.outlook.com (10.167.242.42) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.7292.25 via Frontend Transport; Tue, 20 Feb 2024 14:10:57 +0000",
            "from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com\n (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Tue, 20 Feb\n 2024 06:10:43 -0800",
            "from nvidia.com (10.126.231.35) by rnnvmail201.nvidia.com\n (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Tue, 20 Feb\n 2024 06:10:39 -0800"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=O9t+g6gT6tCjo5zagRMTTDVI3KkzfpoT1uNfNSzQTcnMjqVXVVd0GQeiUNOmPLlS4g+4bsiqz01S3JL3qio1SxORBXw/D58E+zNFtaIT7AdqV1dNv+UUgzCytTguU3D6u9D8eC6PIzCOicsJpUdr6lRQPoORa+TmV4YmZoGYHvuKjdpYBxssS7j5WhVMS+S9UfavgAKZQX/uo+L/poz3vL5M5u6uhv9FRhilOxokVD1uQdsirAg0MFfO8g/FEm6EJ84Ld7R9DY/kkaXFXPFoEcjv6u3LyJcVUfVaFNBnrjPSnbrruowziRfgNCXoPeY0jvkvKN+AE66RAREWz2fjfg==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n 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;\n bh=CJhV1UXr/LSFp2zbWVJoX46KL4A+4Rhiq3EL4nZt5RM=;\n b=k/lA8EhE9HmVGwVLDR/x+G1nykGNVqfnfz2I4bPSbH5wXlwUh4KgbPHAXHX+z8AGPFEbZ2qEcqB8cjLZdNtG+J6JeLA3r1x8t1NwQZj9DoDSW5vd6uWW7aH34v1y4q6P2qfNmrQ0Rq7NU8/ljbkX6fZAhcIjd07i44NzjYvFJ5ee5xIYWC8b4UU7ewMVbfHKSUnjUE+LPKgSrfOoF68CL4vMUZhWobG1ICe1GxoVDvGe06JuhhobWXwGzJ5bvejgCPuHFZw26FubA4BqcnraVd3wbCDWj7rnBanmcX1FWR9FjBghoqYBgYCcriem8kIizfEmBam1/+9aD5gomNcwcg==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.160) smtp.rcpttodomain=intel.com smtp.mailfrom=nvidia.com;\n dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none (0)",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=CJhV1UXr/LSFp2zbWVJoX46KL4A+4Rhiq3EL4nZt5RM=;\n b=OqbONoPb+VG3kZj4wZbV6rCeVjvTwj8x/s3c6L6VjtQmSa4Fk6etSqqkV2zbEFn44f14BmHpFKHtE30t64dn5vhbMPJnzvh3PpdBTttDVM5WFdXDMi1SRxMeTvGjvKSP5iX39BhGeM8gn5xGkKbocnAm3ox4/XHqZSMVZPGl8lzA6tAEDPZSwo59WEDJ8uCzoonOfwkNQU5WZIwaUOepkWzWInUtq3J0+daSnnQWYl2QJZbtkjJRQxheSkykBJcU9q06PKNv3pYYXX50L4Srjvm4I6QgWMOfWrdpbaesEVdc5ct0ir4HTN1B9Ln52UC+Kx6b7eOTuQTQ2OAQuPX6tQ==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.117.160)\n smtp.mailfrom=nvidia.com;\n dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.117.160 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C",
        "From": "Bing Zhao <bingz@nvidia.com>",
        "To": "<orika@nvidia.com>, <aman.deep.singh@intel.com>, <dsosnowski@nvidia.com>,\n <viacheslavo@nvidia.com>, <suanmingm@nvidia.com>, <matan@nvidia.com>,\n <thomas@monjalon.net>, <ferruh.yigit@amd.com>,\n <andrew.rybchenko@oktetlabs.ru>, <dev@dpdk.org>, <rasland@nvidia.com>",
        "CC": "Erez Shitrit <erezsh@nvidia.com>",
        "Subject": "[PATCH v2 1/5] net/mlx5/hws: support NAT64 action",
        "Date": "Tue, 20 Feb 2024 16:10:04 +0200",
        "Message-ID": "<20240220141008.292641-2-bingz@nvidia.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20240220141008.292641-1-bingz@nvidia.com>",
        "References": "<20231227090731.2569427-1-bingz@nvidia.com>\n <20240220141008.292641-1-bingz@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.231.35]",
        "X-ClientProxiedBy": "rnnvmail203.nvidia.com (10.129.68.9) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ5PEPF000001CD:EE_|CH0PR12MB5073:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "955c2ee3-e316-4e94-f7c2-08dc321dc265",
        "X-LD-Processed": "43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n cxCUTf2U6vP7qFEMPwznG7Kl9ebUAQJRcmRtWWNxoksOEZhdN3jIOK4Y0R1iRrRTOm8mFr0rH6T3vB7oEKxr8LFl1Vl0N9YA79VFpPPiraPIHlIwg+2i7TWRQ2vu8MD3VUolFUR8COOb9V4Kl0iUXRIZoxpq781/kV3n3prfagMoVLHptYzs3bLZ6kX+LbKYYSe7Z9AF6To3gjVGVrxnF+nhphnBlc9J9al9rReJkCMdHx25rbi/X2rlxM1KZfcr8XQKbRVLVNHD1EZ4hYtFauYpPE/lXxVTbWpeUimcph4nD4kfDqXNKwKXVmYFisUEXAOOt4OxTfhcMdm0H1KZdnn6IWclVEr7A0hYlN7PDVFaaZanznJs8MQZ0E0ywmbEUT8Sgx86VrGGpBFiqKnnluPHa4hPG9B5mwMJMTDSHTY8cyCIEY+/LuYVSKpWneo5tck9JcOKGlM+PHqHbkU4sd5PGHQyxvJd56cWn/7AB/qkrHjvIQimSXOeLxZI3Sj+YoidQ9nY0XXxapOcoVBfXPPGrMFArbMgn/utrQHLONuwGobnikm73Uxdd4Y4xZigDMc0UfRyXFVMMiz7yaeu1s/BUy1qhmVzpnr0XGtu/p+w+xsMly6Aq61ZPL55M+hdKOwWub7P8c9zYaqB1+8VbGS/2y5/cdATvjBTx4biVm4=",
        "X-Forefront-Antispam-Report": "CIP:216.228.117.160; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge1.nvidia.com; CAT:NONE;\n SFS:(13230031)(36860700004)(40470700004)(46966006)(921011); DIR:OUT;\n SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "20 Feb 2024 14:10:57.5733 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 955c2ee3-e316-4e94-f7c2-08dc321dc265",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.160];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n SJ5PEPF000001CD.namprd05.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CH0PR12MB5073",
        "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>,\n <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>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Erez Shitrit <erezsh@nvidia.com>\n\nAdd support of new action mlx5dr_action_create_nat64.\nThe new action allows to modify IP packets from version to version, IPV6\nto IPV4 and vice versa.\n\nSigned-off-by: Erez Shitrit <erezsh@nvidia.com>\nSigned-off-by: Bing Zhao <bingz@nvidia.com>\n---\n drivers/net/mlx5/hws/mlx5dr.h        |  29 ++\n drivers/net/mlx5/hws/mlx5dr_action.c | 437 ++++++++++++++++++++++++++-\n drivers/net/mlx5/hws/mlx5dr_action.h |  35 +++\n drivers/net/mlx5/hws/mlx5dr_debug.c  |   1 +\n 4 files changed, 501 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h\nindex 9c5b068c93..9ee6503439 100644\n--- a/drivers/net/mlx5/hws/mlx5dr.h\n+++ b/drivers/net/mlx5/hws/mlx5dr.h\n@@ -51,6 +51,7 @@ enum mlx5dr_action_type {\n \tMLX5DR_ACTION_TYP_DEST_ARRAY,\n \tMLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT,\n \tMLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT,\n+\tMLX5DR_ACTION_TYP_NAT64,\n \tMLX5DR_ACTION_TYP_MAX,\n };\n \n@@ -817,6 +818,34 @@ mlx5dr_action_create_reformat_ipv6_ext(struct mlx5dr_context *ctx,\n \t\t\t\t       uint32_t log_bulk_size,\n \t\t\t\t       uint32_t flags);\n \n+enum mlx5dr_action_nat64_flags {\n+\tMLX5DR_ACTION_NAT64_V4_TO_V6 = 1 << 0,\n+\tMLX5DR_ACTION_NAT64_V6_TO_V4 = 1 << 1,\n+\t/* Indicates if to backup ipv4 addresses in last two registers */\n+\tMLX5DR_ACTION_NAT64_BACKUP_ADDR = 1 << 2,\n+};\n+\n+struct mlx5dr_action_nat64_attr {\n+\tuint8_t num_of_registers;\n+\tuint8_t *registers;\n+\tenum mlx5dr_action_nat64_flags flags;\n+};\n+\n+/* Create direct rule nat64 action.\n+ *\n+ * @param[in] ctx\n+ *\tThe context in which the new action will be created.\n+ * @param[in] attr\n+ * \tThe relevant attiribute of the NAT action.\n+  * @param[in] flags\n+ *\tAction creation flags. (enum mlx5dr_action_flags)\n+ * @return pointer to mlx5dr_action on success NULL otherwise.\n+ */\n+struct mlx5dr_action *\n+mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,\n+\t\t\t   struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t   uint32_t flags);\n+\n /* Destroy direct rule action.\n  *\n  * @param[in] action\ndiff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c\nindex 862ee3e332..06cbf5930b 100644\n--- a/drivers/net/mlx5/hws/mlx5dr_action.c\n+++ b/drivers/net/mlx5/hws/mlx5dr_action.c\n@@ -31,6 +31,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_\n \t\tBIT(MLX5DR_ACTION_TYP_ASO_CT),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n+\t\tBIT(MLX5DR_ACTION_TYP_NAT64),\n \t\tBIT(MLX5DR_ACTION_TYP_MODIFY_HDR),\n \t\tBIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |\n@@ -52,6 +53,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_\n \t\tBIT(MLX5DR_ACTION_TYP_ASO_CT),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n+\t\tBIT(MLX5DR_ACTION_TYP_NAT64),\n \t\tBIT(MLX5DR_ACTION_TYP_MODIFY_HDR),\n \t\tBIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |\n@@ -75,6 +77,7 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_\n \t\tBIT(MLX5DR_ACTION_TYP_ASO_CT),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_VLAN),\n+\t\tBIT(MLX5DR_ACTION_TYP_NAT64),\n \t\tBIT(MLX5DR_ACTION_TYP_MODIFY_HDR),\n \t\tBIT(MLX5DR_ACTION_TYP_INSERT_HEADER) |\n \t\tBIT(MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT) |\n@@ -246,6 +249,311 @@ static void mlx5dr_action_put_shared_stc(struct mlx5dr_action *action,\n \t\tmlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB);\n }\n \n+static struct mlx5dr_action *\n+mlx5dr_action_create_nat64_copy_state(struct mlx5dr_context *ctx,\n+\t\t\t\t      struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t\t      uint32_t flags)\n+{\n+\t__be64 modify_action_data[MLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS];\n+\tstruct mlx5dr_action_mh_pattern pat[2];\n+\tstruct mlx5dr_action *action;\n+\tuint32_t packet_len_field;\n+\tuint8_t *action_ptr;\n+\tuint32_t ttl_field;\n+\tuint32_t src_addr;\n+\tuint32_t dst_addr;\n+\tbool is_v4_to_v6;\n+\n+\tis_v4_to_v6 = attr->flags & MLX5DR_ACTION_NAT64_V4_TO_V6;\n+\n+\tif (is_v4_to_v6) {\n+\t\tpacket_len_field = MLX5_MODI_OUT_IPV4_TOTAL_LEN;\n+\t\tttl_field = MLX5_MODI_OUT_IPV4_TTL;\n+\t\tsrc_addr = MLX5_MODI_OUT_SIPV4;\n+\t\tdst_addr = MLX5_MODI_OUT_DIPV4;\n+\t} else {\n+\t\tpacket_len_field = MLX5_MODI_OUT_IPV6_PAYLOAD_LEN;\n+\t\tttl_field = MLX5_MODI_OUT_IPV6_HOPLIMIT;\n+\t\tsrc_addr = MLX5_MODI_OUT_SIPV6_31_0;\n+\t\tdst_addr = MLX5_MODI_OUT_DIPV6_31_0;\n+\t}\n+\n+\tmemset(modify_action_data, 0, sizeof(modify_action_data));\n+\taction_ptr = (uint8_t *) modify_action_data;\n+\n+\tif (attr->flags & MLX5DR_ACTION_NAT64_BACKUP_ADDR) {\n+\t\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_field, src_addr);\n+\t\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_SRC_IP]);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_field, dst_addr);\n+\t\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_DST_IP]);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\t}\n+\n+\t/* | 8 bit - 8 bit     - 16 bit     |\n+\t * | ttl   - protocol  - packet-len |\n+\t */\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field, packet_len_field);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_offset, 0);/* 16 bits in the lsb */\n+\tMLX5_SET(copy_action_in, action_ptr, length, 16);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_NOP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field, MLX5_MODI_OUT_IP_PROTOCOL);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_offset, 16);\n+\tMLX5_SET(copy_action_in, action_ptr, length, 8);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_NOP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field, ttl_field);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_offset, 24);\n+\tMLX5_SET(copy_action_in, action_ptr, length, 8);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t/* set sip and dip to 0, in order to have new csum */\n+\tif (is_v4_to_v6) {\n+\t\tMLX5_SET(set_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_SET);\n+\t\tMLX5_SET(set_action_in, action_ptr, field, MLX5_MODI_OUT_SIPV4);\n+\t\tMLX5_SET(set_action_in, action_ptr, data, 0);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t\tMLX5_SET(set_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_SET);\n+\t\tMLX5_SET(set_action_in, action_ptr, field, MLX5_MODI_OUT_DIPV4);\n+\t\tMLX5_SET(set_action_in, action_ptr, data, 0);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\t}\n+\n+\tpat[0].data = modify_action_data;\n+\tpat[0].sz = (action_ptr - (uint8_t *) modify_action_data);\n+\n+\taction = mlx5dr_action_create_modify_header(ctx, 1, pat, 0, flags);\n+\tif (!action) {\n+\t\tDR_LOG(ERR, \"Failed to create copy for NAT64: action_sz: %zu, flags: 0x%x\\n\",\n+\t\t       pat[0].sz, flags);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn action;\n+}\n+\n+static struct mlx5dr_action *\n+mlx5dr_action_create_nat64_repalce_state(struct mlx5dr_context *ctx,\n+\t\t\t\t\t struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t\t\t uint32_t flags)\n+{\n+\tuint32_t address_prefix[MLX5DR_ACTION_NAT64_HEADER_MINUS_ONE] = {0};\n+\t__be64 modify_action_data[MLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS];\n+\tstruct mlx5dr_action_mh_pattern pat[2];\n+\tstatic struct mlx5dr_action *action;\n+\tuint8_t header_size_in_dw;\n+\tuint8_t *action_ptr;\n+\tuint32_t eth_type;\n+\tbool is_v4_to_v6;\n+\tuint32_t ip_ver;\n+\tint i;\n+\n+\tis_v4_to_v6 = attr->flags & MLX5DR_ACTION_NAT64_V4_TO_V6;\n+\n+\tif (is_v4_to_v6) {\n+\t\tuint32_t nat64_well_known_pref[] = {0x00010000,\n+\t\t\t\t\t\t    0x9bff6400, 0x0, 0x0, 0x0,\n+\t\t\t\t\t\t    0x9bff6400, 0x0, 0x0, 0x0};\n+\n+\t\theader_size_in_dw = MLX5DR_ACTION_NAT64_IPV6_HEADER;\n+\t\tip_ver = MLX5DR_ACTION_NAT64_IPV6_VER;\n+\t\teth_type = RTE_ETHER_TYPE_IPV6;\n+\t\tmemcpy(address_prefix, nat64_well_known_pref,\n+\t\t       MLX5DR_ACTION_NAT64_HEADER_MINUS_ONE * sizeof(uint32_t));\n+\t} else {\n+\t\theader_size_in_dw = MLX5DR_ACTION_NAT64_IPV4_HEADER;\n+\t\tip_ver = MLX5DR_ACTION_NAT64_IPV4_VER;\n+\t\teth_type = RTE_ETHER_TYPE_IPV4;\n+\t}\n+\n+\tmemset(modify_action_data, 0, sizeof(modify_action_data));\n+\taction_ptr = (uint8_t *) modify_action_data;\n+\n+\tMLX5_SET(set_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_SET);\n+\tMLX5_SET(set_action_in, action_ptr, field, MLX5_MODI_OUT_ETHERTYPE);\n+\tMLX5_SET(set_action_in, action_ptr, length, 16);\n+\tMLX5_SET(set_action_in, action_ptr, data, eth_type);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t/* push empty header with ipv6 as version */\n+\tMLX5_SET(stc_ste_param_insert, action_ptr, action_type,\n+\t\t MLX5_MODIFICATION_TYPE_INSERT);\n+\tMLX5_SET(stc_ste_param_insert, action_ptr, inline_data, 0x1);\n+\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_anchor,\n+\t\t MLX5_HEADER_ANCHOR_IPV6_IPV4);\n+\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_size, 2);\n+\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_argument, ip_ver);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tfor (i = 0; i < header_size_in_dw - 1; i++) {\n+\t\tMLX5_SET(stc_ste_param_insert, action_ptr, action_type,\n+\t\t\t\tMLX5_MODIFICATION_TYPE_INSERT);\n+\t\tMLX5_SET(stc_ste_param_insert, action_ptr, inline_data, 0x1);\n+\t\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_anchor,\n+\t\t\t\tMLX5_HEADER_ANCHOR_IPV6_IPV4);\n+\t\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_size, 2);\n+\t\tMLX5_SET(stc_ste_param_insert, action_ptr, insert_argument,\n+\t\t\t htobe32(address_prefix[i]));\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\t}\n+\n+\t/* Remove orig src/dst addr (8 bytes, 4 words) */\n+\tMLX5_SET(stc_ste_param_remove, action_ptr, action_type,\n+\t\t MLX5_MODIFICATION_TYPE_REMOVE);\n+\tMLX5_SET(stc_ste_param_remove, action_ptr, remove_start_anchor,\n+\t\t MLX5_HEADER_ANCHOR_IPV6_IPV4);\n+\tMLX5_SET(stc_ste_param_remove, action_ptr, remove_end_anchor,\n+\t\t MLX5_HEADER_ANCHOR_TCP_UDP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tpat[0].data = modify_action_data;\n+\tpat[0].sz = action_ptr - (uint8_t *) modify_action_data;\n+\n+\taction = mlx5dr_action_create_modify_header(ctx, 1, pat, 0, flags);\n+\tif (!action) {\n+\t\tDR_LOG(ERR, \"Failed to create action: action_sz: %zu flags: 0x%x\\n\",\n+\t\t       pat[0].sz, flags);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn action;\n+}\n+\n+static struct mlx5dr_action *\n+mlx5dr_action_create_nat64_copy_back_state(struct mlx5dr_context *ctx,\n+\t\t\t\t\t   struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t\t\t   uint32_t flags)\n+{\n+\t__be64 modify_action_data[MLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS];\n+\tstruct mlx5dr_action_mh_pattern pat[2];\n+\tstruct mlx5dr_action *action;\n+\tuint32_t packet_len_field;\n+\tuint32_t packet_len_add;\n+\tuint8_t *action_ptr;\n+\tuint32_t ttl_field;\n+\tuint32_t src_addr;\n+\tuint32_t dst_addr;\n+\tbool is_v4_to_v6;\n+\n+\tis_v4_to_v6 = attr->flags & MLX5DR_ACTION_NAT64_V4_TO_V6;\n+\n+\tif (is_v4_to_v6) {\n+\t\tpacket_len_field = MLX5_MODI_OUT_IPV6_PAYLOAD_LEN;\n+\t\t /* 2' comp to 20, to get -20 in add operation */\n+\t\tpacket_len_add = MLX5DR_ACTION_NAT64_DEC_20;\n+\t\tttl_field = MLX5_MODI_OUT_IPV6_HOPLIMIT;\n+\t\tsrc_addr = MLX5_MODI_OUT_SIPV6_31_0;\n+\t\tdst_addr = MLX5_MODI_OUT_DIPV6_31_0;\n+\t} else {\n+\t\tpacket_len_field = MLX5_MODI_OUT_IPV4_TOTAL_LEN;\n+\t\t/* ipv4 len is including 20 bytes of the header, so add 20 over ipv6 len */\n+\t\tpacket_len_add = MLX5DR_ACTION_NAT64_ADD_20;\n+\t\tttl_field = MLX5_MODI_OUT_IPV4_TTL;\n+\t\tsrc_addr = MLX5_MODI_OUT_SIPV4;\n+\t\tdst_addr = MLX5_MODI_OUT_DIPV4;\n+\n+\t}\n+\n+\tmemset(modify_action_data, 0, sizeof(modify_action_data));\n+\taction_ptr = (uint8_t *) modify_action_data;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t packet_len_field);\n+\tMLX5_SET(copy_action_in, action_ptr, src_offset, 32);\n+\tMLX5_SET(copy_action_in, action_ptr, length, 16);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_NOP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field,\n+\t\t MLX5_MODI_OUT_IP_PROTOCOL);\n+\tMLX5_SET(copy_action_in, action_ptr, src_offset, 16);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_offset, 0);\n+\tMLX5_SET(copy_action_in, action_ptr, length, 8);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_NOP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\tMLX5_SET(copy_action_in, action_ptr, src_field,\n+\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_CONTROL]);\n+\tMLX5_SET(copy_action_in, action_ptr, dst_field, ttl_field);\n+\tMLX5_SET(copy_action_in, action_ptr, src_offset, 24);\n+\tMLX5_SET(copy_action_in, action_ptr, length, 8);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_NOP);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t/* if required Copy original addresses */\n+\tif (attr->flags & MLX5DR_ACTION_NAT64_BACKUP_ADDR) {\n+\t\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_field,\n+\t\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_SRC_IP]);\n+\t\tMLX5_SET(copy_action_in, action_ptr, dst_field, src_addr);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_offset, 0);\n+\t\tMLX5_SET(copy_action_in, action_ptr, length, 32);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\t\tMLX5_SET(copy_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_COPY);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_field,\n+\t\t\t attr->registers[MLX5DR_ACTION_NAT64_REG_DST_IP]);\n+\t\tMLX5_SET(copy_action_in, action_ptr, dst_field, dst_addr);\n+\t\tMLX5_SET(copy_action_in, action_ptr, src_offset, 0);\n+\t\tMLX5_SET(copy_action_in, action_ptr, length, 32);\n+\t\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\t}\n+\n+\t/* take/add off 20 bytes ipv4/6 from/to the total size */\n+\tMLX5_SET(set_action_in, action_ptr, action_type, MLX5_MODIFICATION_TYPE_ADD);\n+\tMLX5_SET(set_action_in, action_ptr, field, packet_len_field);\n+\tMLX5_SET(set_action_in, action_ptr, data, packet_len_add);\n+\tMLX5_SET(set_action_in, action_ptr, length, 16);\n+\taction_ptr += MLX5DR_ACTION_DOUBLE_SIZE;\n+\n+\tpat[0].data = modify_action_data;\n+\tpat[0].sz = action_ptr - (uint8_t *) modify_action_data;\n+\n+\taction = mlx5dr_action_create_modify_header(ctx, 1, pat, 0, flags);\n+\tif (!action) {\n+\t\tDR_LOG(ERR, \"Failed to create action: action_sz: %zu, flags: 0x%x\\n\",\n+\t\t       pat[0].sz, flags);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn action;\n+}\n+\n static void mlx5dr_action_print_combo(enum mlx5dr_action_type *user_actions)\n {\n \tDR_LOG(ERR, \"Invalid action_type sequence\");\n@@ -2526,6 +2834,94 @@ mlx5dr_action_create_reformat_ipv6_ext(struct mlx5dr_context *ctx,\n \treturn NULL;\n }\n \n+static bool\n+mlx5dr_action_nat64_validate_param(struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t\t   uint32_t flags)\n+{\n+\tif (mlx5dr_action_is_root_flags(flags)) {\n+\t\tDR_LOG(ERR, \"Nat64 action not supported for root\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn false;\n+\t}\n+\n+\tif (!(flags & MLX5DR_ACTION_FLAG_SHARED)) {\n+\t\tDR_LOG(ERR, \"Nat64 action must be with SHARED flag\");\n+\t\trte_errno = EINVAL;\n+\t\treturn false;\n+\t}\n+\n+\tif (attr->num_of_registers > MLX5DR_ACTION_NAT64_REG_MAX) {\n+\t\tDR_LOG(ERR, \"Nat64 action doesn't support more than %d registers\",\n+\t\t       MLX5DR_ACTION_NAT64_REG_MAX);\n+\t\trte_errno = EINVAL;\n+\t\treturn false;\n+\t}\n+\n+\tif (attr->flags & MLX5DR_ACTION_NAT64_BACKUP_ADDR &&\n+\t    attr->num_of_registers != MLX5DR_ACTION_NAT64_REG_MAX) {\n+\t\tDR_LOG(ERR, \"Nat64 backup addr requires %d registers\",\n+\t\t       MLX5DR_ACTION_NAT64_REG_MAX);\n+\t\trte_errno = EINVAL;\n+\t\treturn false;\n+\t}\n+\n+\tif (!(attr->flags & MLX5DR_ACTION_NAT64_V4_TO_V6 ||\n+\t      attr->flags & MLX5DR_ACTION_NAT64_V6_TO_V4)) {\n+\t\tDR_LOG(ERR, \"Nat64 backup addr requires one mode at least\");\n+\t\trte_errno = EINVAL;\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+struct mlx5dr_action *\n+mlx5dr_action_create_nat64(struct mlx5dr_context *ctx,\n+\t\t\t   struct mlx5dr_action_nat64_attr *attr,\n+\t\t\t   uint32_t flags)\n+{\n+\tstruct mlx5dr_action *action;\n+\n+\tif (!mlx5dr_action_nat64_validate_param(attr, flags))\n+\t\treturn NULL;\n+\n+\taction = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_NAT64);\n+\tif (!action)\n+\t\treturn NULL;\n+\n+\taction->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_COPY] =\n+\t\tmlx5dr_action_create_nat64_copy_state(ctx, attr, flags);\n+\tif (!action->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_COPY]) {\n+\t\tDR_LOG(ERR, \"Nat64 failed creating copy state\");\n+\t\tgoto free_action;\n+\t}\n+\n+\taction->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_REPLACE] =\n+\t\tmlx5dr_action_create_nat64_repalce_state(ctx, attr, flags);\n+\tif (!action->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_REPLACE]) {\n+\t\tDR_LOG(ERR, \"Nat64 failed creating replace state\");\n+\t\tgoto free_copy;\n+\t}\n+\n+\taction->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_COPYBACK] =\n+\t\tmlx5dr_action_create_nat64_copy_back_state(ctx, attr, flags);\n+\tif (!action->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_COPYBACK]) {\n+\t\tDR_LOG(ERR, \"Nat64 failed creating copyback state\");\n+\t\tgoto free_replace;\n+\t}\n+\n+\treturn action;\n+\n+\n+free_replace:\n+\tmlx5dr_action_destroy(action->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_REPLACE]);\n+free_copy:\n+\tmlx5dr_action_destroy(action->nat64.stages[MLX5DR_ACTION_NAT64_STAGE_COPY]);\n+free_action:\n+\tsimple_free(action);\n+\treturn NULL;\n+}\n+\n static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)\n {\n \tstruct mlx5dr_devx_obj *obj = NULL;\n@@ -2600,6 +2996,10 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action)\n \t\t\tif (action->ipv6_route_ext.action[i])\n \t\t\t\tmlx5dr_action_destroy(action->ipv6_route_ext.action[i]);\n \t\tbreak;\n+\tcase MLX5DR_ACTION_TYP_NAT64:\n+\t\tfor (i = 0; i < MLX5DR_ACTION_NAT64_STAGES; i++)\n+\t\t\tmlx5dr_action_destroy(action->nat64.stages[i]);\n+\t\tbreak;\n \t}\n }\n \n@@ -2874,6 +3274,28 @@ mlx5dr_action_setter_modify_header(struct mlx5dr_actions_apply_data *apply,\n \t}\n }\n \n+static void\n+mlx5dr_action_setter_nat64(struct mlx5dr_actions_apply_data *apply,\n+\t\t\t   struct mlx5dr_actions_wqe_setter *setter)\n+{\n+\tstruct mlx5dr_rule_action *rule_action;\n+\tstruct mlx5dr_action *cur_stage_action;\n+\tstruct mlx5dr_action *action;\n+\tuint32_t stc_idx;\n+\n+\trule_action = &apply->rule_action[setter->idx_double];\n+\taction = rule_action->action;\n+\tcur_stage_action = action->nat64.stages[setter->stage_idx];\n+\n+\tstc_idx = htobe32(cur_stage_action->stc[apply->tbl_type].offset);\n+\n+\tapply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW6] = stc_idx;\n+\tapply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW7] = 0;\n+\n+\tapply->wqe_data[MLX5DR_ACTION_OFFSET_DW6] = 0;\n+\tapply->wqe_data[MLX5DR_ACTION_OFFSET_DW7] = 0;\n+}\n+\n static void\n mlx5dr_action_setter_insert_ptr(struct mlx5dr_actions_apply_data *apply,\n \t\t\t\tstruct mlx5dr_actions_wqe_setter *setter)\n@@ -3174,7 +3596,7 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at)\n \tstruct mlx5dr_actions_wqe_setter *setter = at->setters;\n \tstruct mlx5dr_actions_wqe_setter *pop_setter = NULL;\n \tstruct mlx5dr_actions_wqe_setter *last_setter;\n-\tint i;\n+\tint i, j;\n \n \t/* Note: Given action combination must be valid */\n \n@@ -3361,6 +3783,19 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at)\n \t\t\tsetter->idx_ctr = i;\n \t\t\tbreak;\n \n+\t\tcase MLX5DR_ACTION_TYP_NAT64:\n+\t\t\t/* NAT64 requires 3 setters, each of them does specific modify header */\n+\t\t\tfor (j = 0; j < MLX5DR_ACTION_NAT64_STAGES; j++) {\n+\t\t\t\tsetter = mlx5dr_action_setter_find_first(last_setter,\n+\t\t\t\t\t\t\t\t\t ASF_DOUBLE | ASF_REMOVE);\n+\t\t\t\tsetter->flags |= ASF_DOUBLE | ASF_MODIFY;\n+\t\t\t\tsetter->set_double = &mlx5dr_action_setter_nat64;\n+\t\t\t\tsetter->idx_double = i;\n+\t\t\t\t/* The stage indicates which modify-header to push */\n+\t\t\t\tsetter->stage_idx = j;\n+\t\t\t}\n+\t\t\tbreak;\n+\n \t\tdefault:\n \t\t\tDR_LOG(ERR, \"Unsupported action type: %d\", action_type[i]);\n \t\t\trte_errno = ENOTSUP;\ndiff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h\nindex fad35a845b..49c2a9bc6b 100644\n--- a/drivers/net/mlx5/hws/mlx5dr_action.h\n+++ b/drivers/net/mlx5/hws/mlx5dr_action.h\n@@ -11,6 +11,9 @@\n /* Max number of internal subactions of ipv6_ext */\n #define MLX5DR_ACTION_IPV6_EXT_MAX_SA 4\n \n+/* Number of MH in NAT64 */\n+#define MLX5DR_ACTION_NAT64_STAGES 3\n+\n enum mlx5dr_action_stc_idx {\n \tMLX5DR_ACTION_STC_IDX_CTRL = 0,\n \tMLX5DR_ACTION_STC_IDX_HIT = 1,\n@@ -68,6 +71,34 @@ enum mlx5dr_action_stc_reparse {\n \tMLX5DR_ACTION_STC_REPARSE_OFF,\n };\n \n+ /* 2' comp to 20, to get -20 in add operation */\n+#define MLX5DR_ACTION_NAT64_DEC_20 0xffffffec\n+\n+enum {\n+\tMLX5DR_ACTION_NAT64_MAX_MODIFY_ACTIONS = 20,\n+\tMLX5DR_ACTION_NAT64_ADD_20 = 20,\n+\tMLX5DR_ACTION_NAT64_HEADER_MINUS_ONE = 9,\n+\tMLX5DR_ACTION_NAT64_IPV6_HEADER = 10,\n+\tMLX5DR_ACTION_NAT64_IPV4_HEADER = 5,\n+\tMLX5DR_ACTION_NAT64_IPV6_VER = 0x60000000,\n+\tMLX5DR_ACTION_NAT64_IPV4_VER = 0x45000000,\n+};\n+\n+/* 3 stages for the nat64 action */\n+enum mlx5dr_action_nat64_stages {\n+\tMLX5DR_ACTION_NAT64_STAGE_COPY = 0,\n+\tMLX5DR_ACTION_NAT64_STAGE_REPLACE = 1,\n+\tMLX5DR_ACTION_NAT64_STAGE_COPYBACK = 2,\n+};\n+\n+/* Registers for keeping data from stage to stage */\n+enum {\n+\tMLX5DR_ACTION_NAT64_REG_CONTROL = 0,\n+\tMLX5DR_ACTION_NAT64_REG_SRC_IP = 1,\n+\tMLX5DR_ACTION_NAT64_REG_DST_IP = 2,\n+\tMLX5DR_ACTION_NAT64_REG_MAX = 3,\n+};\n+\n struct mlx5dr_action_default_stc {\n \tstruct mlx5dr_pool_chunk nop_ctr;\n \tstruct mlx5dr_pool_chunk nop_dw5;\n@@ -109,6 +140,7 @@ struct mlx5dr_actions_wqe_setter {\n \tuint8_t idx_double;\n \tuint8_t idx_ctr;\n \tuint8_t idx_hit;\n+\tuint8_t stage_idx;\n \tuint8_t flags;\n \tuint8_t extra_data;\n };\n@@ -182,6 +214,9 @@ struct mlx5dr_action {\n \t\t\t\t\tuint8_t num_of_words;\n \t\t\t\t\tbool decap;\n \t\t\t\t} remove_header;\n+\t\t\t\tstruct {\n+\t\t\t\t\tstruct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES];\n+\t\t\t\t} nat64;\n \t\t\t};\n \t\t};\n \ndiff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c\nindex 11557bcab8..39e168d556 100644\n--- a/drivers/net/mlx5/hws/mlx5dr_debug.c\n+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c\n@@ -28,6 +28,7 @@ const char *mlx5dr_debug_action_type_str[] = {\n \t[MLX5DR_ACTION_TYP_REMOVE_HEADER] = \"REMOVE_HEADER\",\n \t[MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = \"POP_IPV6_ROUTE_EXT\",\n \t[MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = \"PUSH_IPV6_ROUTE_EXT\",\n+\t[MLX5DR_ACTION_TYP_NAT64] = \"NAT64\",\n };\n \n static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX,\n",
    "prefixes": [
        "v2",
        "1/5"
    ]
}