get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 126248,
    "url": "https://patches.dpdk.org/api/patches/126248/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230418172144.24365-1-getelson@nvidia.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20230418172144.24365-1-getelson@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230418172144.24365-1-getelson@nvidia.com",
    "date": "2023-04-18T17:21:44",
    "name": "ethdev: add indirect list flow action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8df08fe9190b16c9b92f9e14df97c4af6286689e",
    "submitter": {
        "id": 1882,
        "url": "https://patches.dpdk.org/api/people/1882/?format=api",
        "name": "Gregory Etelson",
        "email": "getelson@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230418172144.24365-1-getelson@nvidia.com/mbox/",
    "series": [
        {
            "id": 27766,
            "url": "https://patches.dpdk.org/api/series/27766/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=27766",
            "date": "2023-04-18T17:21:44",
            "name": "ethdev: add indirect list flow action",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/27766/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/126248/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/126248/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 7CB334297F;\n\tTue, 18 Apr 2023 19:22:16 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 06FE64021F;\n\tTue, 18 Apr 2023 19:22:16 +0200 (CEST)",
            "from NAM10-BN7-obe.outbound.protection.outlook.com\n (mail-bn7nam10on2087.outbound.protection.outlook.com [40.107.92.87])\n by mails.dpdk.org (Postfix) with ESMTP id 6E1754014F\n for <dev@dpdk.org>; Tue, 18 Apr 2023 19:22:14 +0200 (CEST)",
            "from MW4PR03CA0354.namprd03.prod.outlook.com (2603:10b6:303:dc::29)\n by SJ0PR12MB8614.namprd12.prod.outlook.com (2603:10b6:a03:47d::17)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.45; Tue, 18 Apr\n 2023 17:22:11 +0000",
            "from CO1NAM11FT090.eop-nam11.prod.protection.outlook.com\n (2603:10b6:303:dc:cafe::99) by MW4PR03CA0354.outlook.office365.com\n (2603:10b6:303:dc::29) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.47 via Frontend\n Transport; Tue, 18 Apr 2023 17:22:11 +0000",
            "from mail.nvidia.com (216.228.117.160) by\n CO1NAM11FT090.mail.protection.outlook.com (10.13.175.152) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.6319.20 via Frontend Transport; Tue, 18 Apr 2023 17:22:11 +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.5; Tue, 18 Apr 2023\n 10:22:01 -0700",
            "from nvidia.com (10.126.231.37) 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.986.37; Tue, 18 Apr\n 2023 10:21:58 -0700"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=ieymtgzcsuVITLPQkc9si3vXhO5OhRnd7YTVXO7/qC1HbYWEQ2imj51PJArQZ94MTGNUJ37Gs0VBZ+HVe/jKui4phS8Ed29s1cKLCAp60xYA6MXu3PM5apGJlkfoDCh27S2CZ9JwSCTmDsuijZN5OwFyn0SpcmSiCM6X6CNZmrQlpx2dMrwPuQgTv+fCS9/uOoWeQrFVe2GnhP8h5TjE0lc/IttkwTQNyPiRQGvj/y1Z5JgAq2luSQgO73IjCiKkgJsVg+AHliFQ4g++jsMMtm7c0hiRUy7s5z6nrBQhSmWQtCzBx7i3UMoXKSAQ1DGPClHBioPYtpBD+KfgeimSvA==",
        "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=XVN4ccH2F9J17mw3qgnhtAKiDi6Hjh367bjYrOKh7pQ=;\n b=j0jLOKCXtDr1Xb8t4NLb/4igzOCRW61rrwODz2rrwWs35pX3hn/uuyZ1efyvBXAzrVih0qotpfTRPak/SbpHhkWyglI+BYkJBxGko5GNa8J87bS1y/jng1124LeuO157z3oqIr09NLwrdM4MQG4n0TM3QLW1S3g5lU5UgSYsVdEigIxbi1tLZ3BqRePj5v3nWsFLvF6o0moaabmaAuvZU+I9JRCfTGbQ/nLHq6CchH5g2B3BrhLG0ELdL2Eg1aYFHI3qxuUBmzwmnoAwn4z7DlgenNqvi8axHTy5aFJdSywiVTXVMOGv5gFxuHcZAndQ/yTtdWXStSaBaHUJHkPqeQ==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.160) smtp.rcpttodomain=dpdk.org 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",
        "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=XVN4ccH2F9J17mw3qgnhtAKiDi6Hjh367bjYrOKh7pQ=;\n b=hWNnbJDMfUEXrLiR3PhzmcxabKYc48dJTO4/cDINJmc4J4za5mkQQcOaeqB71u68kJQTCqj2bjko3R7Jl3knqVvgRhVPN8jDK4HM+V/RwrgpKa9QSYiAHusImJMW6w8f1ipc/ztJ8NmGsSoZei+4Y+Oz1DcnPGDvNE29nnC2Zs0YHj1B87asFhVpqRVpsWvtiX6MLlYWlcMY8+FiHawYHq6V17IpeK3VDceDSh/EfAKVeIb5HHZk517ThZLZ9LvU/w9fEGiZjp4sR8VyEQY5EcP3XFmFMxEts1znlL6FG0jf/Ke2g+5bhjlqWLSCofJRt1/IqUrHbnu8bXs4ehs1vw==",
        "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": "Gregory Etelson <getelson@nvidia.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<mkashani@nvidia.com>, Ori Kam <orika@nvidia.com>, Aman Singh\n <aman.deep.singh@intel.com>, Yuying Zhang <yuying.zhang@intel.com>, \"Ferruh\n Yigit\" <ferruh.yigit@amd.com>, Thomas Monjalon <thomas@monjalon.net>, \"Andrew\n Rybchenko\" <andrew.rybchenko@oktetlabs.ru>",
        "Subject": "[PATCH] ethdev: add indirect list flow action",
        "Date": "Tue, 18 Apr 2023 20:21:44 +0300",
        "Message-ID": "<20230418172144.24365-1-getelson@nvidia.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.231.37]",
        "X-ClientProxiedBy": "rnnvmail202.nvidia.com (10.129.68.7) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "CO1NAM11FT090:EE_|SJ0PR12MB8614:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "9a50f947-064d-4b18-9b37-08db4031722c",
        "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 tfMi4XDjwelcA8N2gVTV1nUsZoOTlNehRP/3kv/gDOG1defwVxGHOEotSagTXcFimexn5855hG2miyzSnSRpdzHfT3vM1MNh2dwUvaWDErxqOBf/+uCUonwdlREbEBlrzLZII/Z5+ClRKnFjnqed+krQXrBADdGWjOmDAkQ5RmQIBWaiXEKV+c7jmCfqupu5mFPWD7iqYmUqux0VCPP2bSkFjs4QpcmTZ0nOwBdeWZG+Nw4danrK+xhmFeDJFAVx0UW/YpLnnGkZiKMsgVHGORHKxNE4BLHKJ+fmlcb7WfI0xgVS7+dPSpHL7/AhDyWMEtfR+oAWq8OBKycj3yh1RdKlhQY+ix1sBrZHCHaHiNXifXPuWkXTc6bz5c+IrNxMx+Vl7AzM6z9RrWOw5dZZouJTovmRT4DETGYnq2jP3DUIdXoh62KQR2DHUhs8lfsz5A2d9ivsdGI1tEF5m3bO4WYmb2utp2F70S3TzuAgQHL8NIYT+17VEtq9p0F71WQ1rtZoNJb73Gj0VtorykAIgGWD6/JsgSWk23evrpYhomECrpPwZXrj2CqHF5QQmGvsIzOgzdODPgWwDRhle45wF12v0/BiUNG89bnaTDaNodYvx3gXwv15YOYSjZOCzICDBWGKWKEndzym8nNV4chY42T4mIhoxWqng6qZs/QOknntFS5SvATIRrl3kplxkcj+XIp8kmQ1nyqbuyZy0SmdzPchqt7fAUotAyG76c5HVPTpS6VUKj0ziJLRrk9jspYJU5GaDbRLrNe+2ErNxFJ2zQ==",
        "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:(13230028)(4636009)(136003)(396003)(346002)(376002)(39860400002)(451199021)(40470700004)(36840700001)(46966006)(5660300002)(86362001)(426003)(336012)(82310400005)(2616005)(47076005)(83380400001)(82740400003)(16526019)(186003)(26005)(356005)(7636003)(1076003)(40480700001)(36860700001)(8676002)(34020700004)(6286002)(8936002)(478600001)(54906003)(7696005)(6666004)(316002)(55016003)(41300700001)(40460700003)(36756003)(4326008)(6916009)(70586007)(70206006)(2906002)(30864003);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "18 Apr 2023 17:22:11.5220 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 9a50f947-064d-4b18-9b37-08db4031722c",
        "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 CO1NAM11FT090.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SJ0PR12MB8614",
        "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": "Indirect flow action provides a handler to hardware\nflow action object. The handler is  used in flow rules for sharing\nhardware action object state.\n\nCurrent  INDIRECT flow handler can reference a single\nflow action type.\n\nNew INDIRECT_LIST extends existing functionality.\nINDIRECT_LIST flow handler can reference one or many flow actions.\n\ntestpmd example:\n\nset raw_encap 0 \\\neth src is 11:00:00:00:00:11 dst is aa:00:00:00:00:aa / \\\nipv4 src is 1.1.1.1 dst is 2.2.2.2 ttl is 64 proto is 17 / \\\nudp src is 0x1234 dst is 4789 / vxlan vni is 0xabcd / end_set\nset raw_encap 1 \\\neth src is 22:00:00:00:00:22 dst is bb:00:00:00:00:bb / \\\nipv6 src is 2001::1111 dst is 2001::2222 proto is 17 / \\\nudp src is 0x1234 dst is 4789 / vxlan vni is 0xabcd / end_set\n\nset sample_actions 0 \\\nraw_encap index 0 / represented_port ethdev_port_id 0 / end\nset sample_actions 1 \\\nraw_encap index 1 / represented_port ethdev_port_id 0 / end\n\nflow indirect_action 0 create transfer list actions \\\nsample ratio 1 index 0 / \\\nsample ratio 1 index 1 / \\\njump group 0xcaca / end\n\nflow actions_template 0 create transfer actions_template_id 10 \\\ntemplate indirect_list 0 / end mask indirect_list / end\n\nSigned-off-by: Gregory Etelson <getelson@nvidia.com>\n---\n app/test-pmd/cmdline_flow.c            |  41 ++++++-\n app/test-pmd/config.c                  | 162 +++++++++++++++++++------\n app/test-pmd/testpmd.h                 |   7 +-\n doc/guides/nics/features/default.ini   |   1 +\n doc/guides/prog_guide/rte_flow.rst     |   6 +\n doc/guides/rel_notes/release_23_07.rst |   4 +\n lib/ethdev/rte_flow.c                  |  92 ++++++++++++++\n lib/ethdev/rte_flow.h                  | 149 +++++++++++++++++++++++\n lib/ethdev/rte_flow_driver.h           |  27 ++++-\n lib/ethdev/version.map                 |   4 +\n 10 files changed, 452 insertions(+), 41 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex 58939ec321..956a39d167 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -145,6 +145,7 @@ enum index {\n \n \t/* Queue indirect action arguments */\n \tQUEUE_INDIRECT_ACTION_CREATE,\n+\tQUEUE_INDIRECT_ACTION_LIST_CREATE,\n \tQUEUE_INDIRECT_ACTION_UPDATE,\n \tQUEUE_INDIRECT_ACTION_DESTROY,\n \tQUEUE_INDIRECT_ACTION_QUERY,\n@@ -157,6 +158,7 @@ enum index {\n \tQUEUE_INDIRECT_ACTION_TRANSFER,\n \tQUEUE_INDIRECT_ACTION_CREATE_POSTPONE,\n \tQUEUE_INDIRECT_ACTION_SPEC,\n+\tQUEUE_INDIRECT_ACTION_LIST,\n \n \t/* Queue indirect action update arguments */\n \tQUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,\n@@ -242,6 +244,7 @@ enum index {\n \n \t/* Indirect action arguments */\n \tINDIRECT_ACTION_CREATE,\n+\tINDIRECT_ACTION_LIST_CREATE,\n \tINDIRECT_ACTION_UPDATE,\n \tINDIRECT_ACTION_DESTROY,\n \tINDIRECT_ACTION_QUERY,\n@@ -253,6 +256,7 @@ enum index {\n \tINDIRECT_ACTION_EGRESS,\n \tINDIRECT_ACTION_TRANSFER,\n \tINDIRECT_ACTION_SPEC,\n+\tINDIRECT_ACTION_LIST,\n \n \t/* Indirect action destroy arguments */\n \tINDIRECT_ACTION_DESTROY_ID,\n@@ -626,6 +630,7 @@ enum index {\n \tACTION_SAMPLE_INDEX,\n \tACTION_SAMPLE_INDEX_VALUE,\n \tACTION_INDIRECT,\n+\tACTION_INDIRECT_LIST,\n \tACTION_SHARED_INDIRECT,\n \tINDIRECT_ACTION_PORT,\n \tINDIRECT_ACTION_ID2PTR,\n@@ -1266,6 +1271,7 @@ static const enum index next_qia_create_attr[] = {\n \tQUEUE_INDIRECT_ACTION_TRANSFER,\n \tQUEUE_INDIRECT_ACTION_CREATE_POSTPONE,\n \tQUEUE_INDIRECT_ACTION_SPEC,\n+\tQUEUE_INDIRECT_ACTION_LIST,\n \tZERO,\n };\n \n@@ -1294,6 +1300,7 @@ static const enum index next_ia_create_attr[] = {\n \tINDIRECT_ACTION_EGRESS,\n \tINDIRECT_ACTION_TRANSFER,\n \tINDIRECT_ACTION_SPEC,\n+\tINDIRECT_ACTION_LIST,\n \tZERO,\n };\n \n@@ -2013,6 +2020,7 @@ static const enum index next_action[] = {\n \tACTION_AGE_UPDATE,\n \tACTION_SAMPLE,\n \tACTION_INDIRECT,\n+\tACTION_INDIRECT_LIST,\n \tACTION_SHARED_INDIRECT,\n \tACTION_MODIFY_FIELD,\n \tACTION_CONNTRACK,\n@@ -2289,6 +2297,7 @@ static const enum index next_action_sample[] = {\n \tACTION_RAW_ENCAP,\n \tACTION_VXLAN_ENCAP,\n \tACTION_NVGRE_ENCAP,\n+\tACTION_REPRESENTED_PORT,\n \tACTION_NEXT,\n \tZERO,\n };\n@@ -3426,6 +3435,12 @@ static const struct token token_list[] = {\n \t\t.help = \"specify action to create indirect handle\",\n \t\t.next = NEXT(next_action),\n \t},\n+\t[QUEUE_INDIRECT_ACTION_LIST] = {\n+\t\t.name = \"list\",\n+\t\t.help = \"specify actions for indirect handle list\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTIONS, END)),\n+\t\t.call = parse_qia,\n+\t},\n \t/* Top-level command. */\n \t[PUSH] = {\n \t\t.name = \"push\",\n@@ -6775,6 +6790,14 @@ static const struct token token_list[] = {\n \t\t.args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),\n \t\t.call = parse_vc,\n \t},\n+\t[ACTION_INDIRECT_LIST] = {\n+\t\t.name = \"indirect_list\",\n+\t\t.help = \"apply indirect list action by id\",\n+\t\t.priv = PRIV_ACTION(INDIRECT_LIST, 0),\n+\t\t.next = NEXT(next_ia),\n+\t\t.args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),\n+\t\t.call = parse_vc,\n+\t},\n \t[ACTION_SHARED_INDIRECT] = {\n \t\t.name = \"shared_indirect\",\n \t\t.help = \"apply indirect action by id and port\",\n@@ -6823,6 +6846,12 @@ static const struct token token_list[] = {\n \t\t.help = \"specify action to create indirect handle\",\n \t\t.next = NEXT(next_action),\n \t},\n+\t[INDIRECT_ACTION_LIST] = {\n+\t\t.name = \"list\",\n+\t\t.help = \"specify actions for indirect handle list\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTIONS, END)),\n+\t\t.call = parse_ia,\n+\t},\n \t[ACTION_POL_G] = {\n \t\t.name = \"g_actions\",\n \t\t.help = \"submit a list of associated actions for green\",\n@@ -7181,6 +7210,9 @@ parse_ia(struct context *ctx, const struct token *token,\n \t\treturn len;\n \tcase INDIRECT_ACTION_QU_MODE:\n \t\treturn len;\n+\tcase INDIRECT_ACTION_LIST:\n+\t\tout->command = INDIRECT_ACTION_LIST_CREATE;\n+\t\treturn len;\n \tdefault:\n \t\treturn -1;\n \t}\n@@ -7278,6 +7310,9 @@ parse_qia(struct context *ctx, const struct token *token,\n \t\treturn len;\n \tcase QUEUE_INDIRECT_ACTION_QU_MODE:\n \t\treturn len;\n+\tcase QUEUE_INDIRECT_ACTION_LIST:\n+\t\tout->command = QUEUE_INDIRECT_ACTION_LIST_CREATE;\n+\t\treturn len;\n \tdefault:\n \t\treturn -1;\n \t}\n@@ -7454,10 +7489,12 @@ parse_vc(struct context *ctx, const struct token *token,\n \t\t\treturn -1;\n \t\tbreak;\n \tcase ACTIONS:\n-\t\tout->args.vc.actions =\n+\t\tout->args.vc.actions = out->args.vc.pattern ?\n \t\t\t(void *)RTE_ALIGN_CEIL((uintptr_t)\n \t\t\t\t\t       (out->args.vc.pattern +\n \t\t\t\t\t\tout->args.vc.pattern_n),\n+\t\t\t\t\t       sizeof(double)) :\n+\t\t\t(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),\n \t\t\t\t\t       sizeof(double));\n \t\tctx->object = out->args.vc.actions;\n \t\tctx->objmask = NULL;\n@@ -11532,6 +11569,7 @@ cmd_flow_parsed(const struct buffer *in)\n \t\t\t\t     in->args.aged.destroy);\n \t\tbreak;\n \tcase QUEUE_INDIRECT_ACTION_CREATE:\n+\tcase QUEUE_INDIRECT_ACTION_LIST_CREATE:\n \t\tport_queue_action_handle_create(\n \t\t\t\tin->port, in->queue, in->postpone,\n \t\t\t\tin->args.vc.attr.group,\n@@ -11567,6 +11605,7 @@ cmd_flow_parsed(const struct buffer *in)\n \t\t\t\t\t\t      in->args.vc.actions);\n \t\tbreak;\n \tcase INDIRECT_ACTION_CREATE:\n+\tcase INDIRECT_ACTION_LIST_CREATE:\n \t\tport_action_handle_create(\n \t\t\t\tin->port, in->args.vc.attr.group,\n \t\t\t\t&((const struct rte_flow_indir_action_conf) {\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 096c218c12..c220682ff9 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -1764,6 +1764,44 @@ port_flow_configure(portid_t port_id,\n \treturn 0;\n }\n \n+static int\n+action_handle_create(portid_t port_id,\n+\t\t     struct port_indirect_action *pia,\n+\t\t     const struct rte_flow_indir_action_conf *conf,\n+\t\t     const struct rte_flow_action *action,\n+\t\t     struct rte_flow_error *error)\n+{\n+\tif (action->type == RTE_FLOW_ACTION_TYPE_AGE) {\n+\t\tstruct rte_flow_action_age *age =\n+\t\t\t(struct rte_flow_action_age *)(uintptr_t)(action->conf);\n+\n+\t\tpia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;\n+\t\tage->context = &pia->age_type;\n+\t} else if (action->type == RTE_FLOW_ACTION_TYPE_CONNTRACK) {\n+\t\tstruct rte_flow_action_conntrack *ct =\n+\t\t\t(struct rte_flow_action_conntrack *)(uintptr_t)(action->conf);\n+\n+\t\tmemcpy(ct, &conntrack_context, sizeof(*ct));\n+\t}\n+\tpia->type = action->type;\n+\tpia->handle = rte_flow_action_handle_create(port_id, conf, action,\n+\t\t\t\t\t\t    error);\n+\treturn pia->handle ? 0 : -1;\n+}\n+\n+static int\n+action_list_handle_create(portid_t port_id,\n+\t\t\t  struct port_indirect_action *pia,\n+\t\t\t  const struct rte_flow_indir_action_conf *conf,\n+\t\t\t  const struct rte_flow_action *actions,\n+\t\t\t  struct rte_flow_error *error)\n+{\n+\tpia->type = RTE_FLOW_ACTION_TYPE_INDIRECT_LIST;\n+\tpia->list_handle =\n+\t\trte_flow_action_list_handle_create(port_id, conf,\n+\t\t\t\t\t\t   actions, error);\n+\treturn pia->list_handle ? 0 : -1;\n+}\n /** Create indirect action */\n int\n port_action_handle_create(portid_t port_id, uint32_t id,\n@@ -1773,32 +1811,21 @@ port_action_handle_create(portid_t port_id, uint32_t id,\n \tstruct port_indirect_action *pia;\n \tint ret;\n \tstruct rte_flow_error error;\n+\tbool is_indirect_list = action[1].type != RTE_FLOW_ACTION_TYPE_END;\n \n \tret = action_alloc(port_id, id, &pia);\n \tif (ret)\n \t\treturn ret;\n-\tif (action->type == RTE_FLOW_ACTION_TYPE_AGE) {\n-\t\tstruct rte_flow_action_age *age =\n-\t\t\t(struct rte_flow_action_age *)(uintptr_t)(action->conf);\n-\n-\t\tpia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;\n-\t\tage->context = &pia->age_type;\n-\t} else if (action->type == RTE_FLOW_ACTION_TYPE_CONNTRACK) {\n-\t\tstruct rte_flow_action_conntrack *ct =\n-\t\t(struct rte_flow_action_conntrack *)(uintptr_t)(action->conf);\n-\n-\t\tmemcpy(ct, &conntrack_context, sizeof(*ct));\n-\t}\n \t/* Poisoning to make sure PMDs update it in case of error. */\n \tmemset(&error, 0x22, sizeof(error));\n-\tpia->handle = rte_flow_action_handle_create(port_id, conf, action,\n-\t\t\t\t\t\t    &error);\n-\tif (!pia->handle) {\n+\tret = is_indirect_list ?\n+\t       action_list_handle_create(port_id, pia, conf, action, &error) :\n+\t       action_handle_create(port_id, pia, conf, action, &error);\n+\tif (ret) {\n \t\tuint32_t destroy_id = pia->id;\n \t\tport_action_handle_destroy(port_id, 1, &destroy_id);\n \t\treturn port_flow_complain(&error);\n \t}\n-\tpia->type = action->type;\n \tprintf(\"Indirect action #%u created\\n\", pia->id);\n \treturn 0;\n }\n@@ -1833,10 +1860,17 @@ port_action_handle_destroy(portid_t port_id,\n \t\t\t */\n \t\t\tmemset(&error, 0x33, sizeof(error));\n \n-\t\t\tif (pia->handle && rte_flow_action_handle_destroy(\n-\t\t\t\t\tport_id, pia->handle, &error)) {\n-\t\t\t\tret = port_flow_complain(&error);\n-\t\t\t\tcontinue;\n+\t\t\tif (pia->handle) {\n+\t\t\t\tret = pia->type ==\n+\t\t\t\t      RTE_FLOW_ACTION_TYPE_INDIRECT_LIST ?\n+\t\t\t\t\trte_flow_action_list_handle_destroy\n+\t\t\t\t\t(port_id, pia->list_handle, &error) :\n+\t\t\t\t\trte_flow_action_handle_destroy\n+\t\t\t\t\t(port_id, pia->handle, &error);\n+\t\t\t\tif (ret) {\n+\t\t\t\t\tret = port_flow_complain(&error);\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n \t\t\t}\n \t\t\t*tmp = pia->next;\n \t\t\tprintf(\"Indirect action #%u destroyed\\n\", pia->id);\n@@ -1867,11 +1901,18 @@ port_action_handle_flush(portid_t port_id)\n \n \t\t/* Poisoning to make sure PMDs update it in case of error. */\n \t\tmemset(&error, 0x44, sizeof(error));\n-\t\tif (pia->handle != NULL &&\n-\t\t    rte_flow_action_handle_destroy\n-\t\t\t\t\t(port_id, pia->handle, &error) != 0) {\n-\t\t\tprintf(\"Indirect action #%u not destroyed\\n\", pia->id);\n-\t\t\tret = port_flow_complain(&error);\n+\t\tif (pia->handle != NULL) {\n+\t\t\tret = pia->type ==\n+\t\t\t      RTE_FLOW_ACTION_TYPE_INDIRECT_LIST ?\n+\t\t\t      rte_flow_action_list_handle_destroy\n+\t\t\t\t      (port_id, pia->list_handle, &error) :\n+\t\t\t      rte_flow_action_handle_destroy\n+\t\t\t\t      (port_id, pia->handle, &error);\n+\t\t\tif (ret) {\n+\t\t\t\tprintf(\"Indirect action #%u not destroyed\\n\",\n+\t\t\t\t       pia->id);\n+\t\t\t\tret = port_flow_complain(&error);\n+\t\t\t}\n \t\t\ttmp = &pia->next;\n \t\t} else {\n \t\t\t*tmp = pia->next;\n@@ -2822,6 +2863,45 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id,\n \treturn ret;\n }\n \n+static void\n+queue_action_handle_create(portid_t port_id, uint32_t queue_id,\n+\t\t\t   struct port_indirect_action *pia,\n+\t\t\t   struct queue_job *job,\n+\t\t\t   const struct rte_flow_op_attr *attr,\n+\t\t\t   const struct rte_flow_indir_action_conf *conf,\n+\t\t\t   const struct rte_flow_action *action,\n+\t\t\t   struct rte_flow_error *error)\n+{\n+\tif (action->type == RTE_FLOW_ACTION_TYPE_AGE) {\n+\t\tstruct rte_flow_action_age *age =\n+\t\t\t(struct rte_flow_action_age *)(uintptr_t)(action->conf);\n+\n+\t\tpia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;\n+\t\tage->context = &pia->age_type;\n+\t}\n+\t/* Poisoning to make sure PMDs update it in case of error. */\n+\tpia->handle = rte_flow_async_action_handle_create(port_id, queue_id,\n+\t\t\t\t\t\t\t  attr, conf, action,\n+\t\t\t\t\t\t\t  job, error);\n+\tpia->type = action->type;\n+}\n+\n+static void\n+queue_action_list_handle_create(portid_t port_id, uint32_t queue_id,\n+\t\t\t\tstruct port_indirect_action *pia,\n+\t\t\t\tstruct queue_job *job,\n+\t\t\t\tconst struct rte_flow_op_attr *attr,\n+\t\t\t\tconst struct rte_flow_indir_action_conf *conf,\n+\t\t\t\tconst struct rte_flow_action *action,\n+\t\t\t\tstruct rte_flow_error *error)\n+{\n+\t/* Poisoning to make sure PMDs update it in case of error. */\n+\tpia->type = RTE_FLOW_ACTION_TYPE_INDIRECT_LIST;\n+\tpia->list_handle = rte_flow_async_action_list_handle_create\n+\t\t\t\t(port_id, queue_id, attr, conf, action,\n+\t\t\t\t job, error);\n+}\n+\n /** Enqueue indirect action create operation. */\n int\n port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,\n@@ -2835,6 +2915,8 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,\n \tint ret;\n \tstruct rte_flow_error error;\n \tstruct queue_job *job;\n+\tbool is_indirect_list = action[1].type != RTE_FLOW_ACTION_TYPE_END;\n+\n \n \tret = action_alloc(port_id, id, &pia);\n \tif (ret)\n@@ -2853,17 +2935,16 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,\n \tjob->type = QUEUE_JOB_TYPE_ACTION_CREATE;\n \tjob->pia = pia;\n \n-\tif (action->type == RTE_FLOW_ACTION_TYPE_AGE) {\n-\t\tstruct rte_flow_action_age *age =\n-\t\t\t(struct rte_flow_action_age *)(uintptr_t)(action->conf);\n-\n-\t\tpia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;\n-\t\tage->context = &pia->age_type;\n-\t}\n \t/* Poisoning to make sure PMDs update it in case of error. */\n \tmemset(&error, 0x88, sizeof(error));\n-\tpia->handle = rte_flow_async_action_handle_create(port_id, queue_id,\n-\t\t\t\t\t&attr, conf, action, job, &error);\n+\n+\tif (is_indirect_list)\n+\t\tqueue_action_list_handle_create(port_id, queue_id, pia, job,\n+\t\t\t\t\t\t&attr, conf, action, &error);\n+\telse\n+\t\tqueue_action_handle_create(port_id, queue_id, pia, job, &attr,\n+\t\t\t\t\t   conf, action, &error);\n+\n \tif (!pia->handle) {\n \t\tuint32_t destroy_id = pia->id;\n \t\tport_queue_action_handle_destroy(port_id, queue_id,\n@@ -2871,7 +2952,6 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,\n \t\tfree(job);\n \t\treturn port_flow_complain(&error);\n \t}\n-\tpia->type = action->type;\n \tprintf(\"Indirect action #%u creation queued\\n\", pia->id);\n \treturn 0;\n }\n@@ -2920,9 +3000,15 @@ port_queue_action_handle_destroy(portid_t port_id,\n \t\t\t}\n \t\t\tjob->type = QUEUE_JOB_TYPE_ACTION_DESTROY;\n \t\t\tjob->pia = pia;\n-\n-\t\t\tif (rte_flow_async_action_handle_destroy(port_id,\n-\t\t\t\tqueue_id, &attr, pia->handle, job, &error)) {\n+\t\t\tret = pia->type == RTE_FLOW_ACTION_TYPE_INDIRECT_LIST ?\n+\t\t\t      rte_flow_async_action_list_handle_destroy\n+\t\t\t\t      (port_id, queue_id,\n+\t\t\t\t       &attr, pia->list_handle,\n+\t\t\t\t       job, &error) :\n+\t\t\t      rte_flow_async_action_handle_destroy\n+\t\t\t\t      (port_id, queue_id, &attr, pia->handle,\n+\t\t\t\t       job, &error);\n+\t\t\tif (ret) {\n \t\t\t\tfree(job);\n \t\t\t\tret = port_flow_complain(&error);\n \t\t\t\tcontinue;\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex bdfbfd36d3..9786e62d28 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -228,7 +228,12 @@ struct port_indirect_action {\n \tstruct port_indirect_action *next; /**< Next flow in list. */\n \tuint32_t id; /**< Indirect action ID. */\n \tenum rte_flow_action_type type; /**< Action type. */\n-\tstruct rte_flow_action_handle *handle;\t/**< Indirect action handle. */\n+\tunion {\n+\t\tstruct rte_flow_action_handle *handle;\n+\t\t/**< Indirect action handle. */\n+\t\tstruct rte_flow_action_list_handle *list_handle;\n+\t\t/**< Indirect action list handle*/\n+\t};\n \tenum age_action_context_type age_type; /**< Age action context type. */\n };\n \ndiff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini\nindex 1a5087abad..10a1c1af77 100644\n--- a/doc/guides/nics/features/default.ini\n+++ b/doc/guides/nics/features/default.ini\n@@ -158,6 +158,7 @@ drop                 =\n flag                 =\n inc_tcp_ack          =\n inc_tcp_seq          =\n+indirect_list        =\n jump                 =\n mac_swap             =\n mark                 =\ndiff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst\nindex 32fc45516a..ed67e86c58 100644\n--- a/doc/guides/prog_guide/rte_flow.rst\n+++ b/doc/guides/prog_guide/rte_flow.rst\n@@ -3300,6 +3300,12 @@ The ``quota`` value is reduced according to ``mode`` setting.\n    | ``RTE_FLOW_QUOTA_MODE_L3``      | Count packet bytes starting from L3 |\n    +------------------+----------------------------------------------------+\n \n+Action: ``INDIRECT_LIST``\n+^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+The new ``INDIRECT_LIST`` flow action references one or many flow actions.\n+Extends the ``INDIRECT`` flow action.\n+\n Negative types\n ~~~~~~~~~~~~~~\n \ndiff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst\nindex a9b1293689..955493e445 100644\n--- a/doc/guides/rel_notes/release_23_07.rst\n+++ b/doc/guides/rel_notes/release_23_07.rst\n@@ -55,6 +55,10 @@ New Features\n      Also, make sure to start the actual text at the margin.\n      =======================================================\n \n+   * **Added indirect list flow action.**\n+\n+     * ``RTE_FLOW_ACTION_TYPE_INDIRECT_LIST``\n+\n \n Removed Items\n -------------\ndiff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c\nindex 69e6e749f7..73b31fc69f 100644\n--- a/lib/ethdev/rte_flow.c\n+++ b/lib/ethdev/rte_flow.c\n@@ -259,6 +259,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {\n \tMK_FLOW_ACTION(METER_MARK, sizeof(struct rte_flow_action_meter_mark)),\n \tMK_FLOW_ACTION(SEND_TO_KERNEL, 0),\n \tMK_FLOW_ACTION(QUOTA, sizeof(struct rte_flow_action_quota)),\n+\tMK_FLOW_ACTION(INDIRECT_LIST, 0),\n };\n \n int\n@@ -2171,3 +2172,94 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,\n \t\t\t\t\t\t    user_data, error);\n \treturn flow_err(port_id, ret, error);\n }\n+\n+struct rte_flow_action_list_handle *\n+rte_flow_action_list_handle_create(uint16_t port_id,\n+\t\t\t\t   const\n+\t\t\t\t   struct rte_flow_indir_action_conf *conf,\n+\t\t\t\t   const struct rte_flow_action *actions,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tconst struct rte_flow_ops *ops;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);\n+\tops = rte_flow_ops_get(port_id, error);\n+\tif (!ops || !ops->action_list_handle_create) {\n+\t\trte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"action_list handle not supported\");\n+\t\treturn NULL;\n+\t}\n+\tdev = &rte_eth_devices[port_id];\n+\treturn ops->action_list_handle_create(dev, conf, actions, error);\n+}\n+\n+int\n+rte_flow_action_list_handle_destroy(uint16_t port_id,\n+\t\t\t\t    struct rte_flow_action_list_handle *handle,\n+\t\t\t\t    struct rte_flow_error *error)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tconst struct rte_flow_ops *ops;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\tops = rte_flow_ops_get(port_id, error);\n+\tif (!ops || !ops->action_list_handle_destroy)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"action_list handle not supported\");\n+\tdev = &rte_eth_devices[port_id];\n+\treturn ops->action_list_handle_destroy(dev, handle, error);\n+}\n+\n+struct rte_flow_action_list_handle *\n+rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,\n+\t\t\t\t\t const struct rte_flow_op_attr *attr,\n+\t\t\t\t\t const struct\n+\t\t\t\t\t rte_flow_indir_action_conf *conf,\n+\t\t\t\t\t const struct rte_flow_action *actions,\n+\t\t\t\t\t void *user_data,\n+\t\t\t\t\t struct rte_flow_error *error)\n+{\n+\tstruct rte_eth_dev *dev;\n+\tconst struct rte_flow_ops *ops;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);\n+\tops = rte_flow_ops_get(port_id, error);\n+\tif (!ops || !ops->async_action_list_handle_create) {\n+\t\trte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"action_list handle not supported\");\n+\t\treturn NULL;\n+\t}\n+\tdev = &rte_eth_devices[port_id];\n+\treturn ops->async_action_list_handle_create(dev, queue_id, attr, conf,\n+\t\t\t\t\t\t    actions, user_data, error);\n+}\n+\n+int\n+rte_flow_async_action_list_handle_destroy(uint16_t port_id, uint32_t queue_id,\n+\t\t\t\t\t  const\n+\t\t\t\t\t  struct rte_flow_op_attr *op_attr,\n+\t\t\t\t\t  struct\n+\t\t\t\t\t  rte_flow_action_list_handle *handle,\n+\t\t\t\t\t  void *user_data,\n+\t\t\t\t\t  struct rte_flow_error *error)\n+{\n+\tint ret;\n+\tstruct rte_eth_dev *dev;\n+\tconst struct rte_flow_ops *ops;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\tops = rte_flow_ops_get(port_id, error);\n+\tif (!ops || !ops->async_action_list_handle_destroy)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"async action_list handle not supported\");\n+\tdev = &rte_eth_devices[port_id];\n+\tret = ops->async_action_list_handle_destroy(dev, queue_id, op_attr,\n+\t\t\t\t\t\t    handle, user_data, error);\n+\treturn flow_err(port_id, ret, error);\n+}\n+\ndiff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h\nindex 713ba8b65c..deb5dc2f9d 100644\n--- a/lib/ethdev/rte_flow.h\n+++ b/lib/ethdev/rte_flow.h\n@@ -2912,6 +2912,11 @@ enum rte_flow_action_type {\n \t * applied to the given ethdev Rx queue.\n \t */\n \tRTE_FLOW_ACTION_TYPE_SKIP_CMAN,\n+\n+\t/**\n+\t * RTE_FLOW_ACTION_TYPE_INDIRECT_LIST\n+\t */\n+\tRTE_FLOW_ACTION_TYPE_INDIRECT_LIST,\n };\n \n /**\n@@ -6118,6 +6123,150 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,\n \t\t\t\t\t  void *user_data,\n \t\t\t\t\t  struct rte_flow_error *error);\n \n+struct rte_flow_action_list_handle;\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Create an indirect flow action object from flow actions list.\n+ * The object is identified by a unique handle.\n+ * The handle has single state and configuration\n+ * across all the flow rules using it.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] conf\n+ *   Action configuration for the indirect action list creation.\n+ * @param[in] actions\n+ *   Specific configuration of the indirect action lists.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   A valid handle in case of success, NULL otherwise and rte_errno is set\n+ *   to one of the error codes defined:\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-ENOSYS) if underlying device does not support this functionality.\n+ *   - (-EIO) if underlying device is removed.\n+ *   - (-EINVAL) if *actions* list invalid.\n+ *   - (-ENOTSUP) if *action* list element valid but unsupported.\n+ *   - (-E2BIG) to many elements in *actions*\n+ */\n+__rte_experimental\n+struct rte_flow_action_list_handle *\n+rte_flow_action_list_handle_create(uint16_t port_id,\n+\t\t\t\t   const\n+\t\t\t\t   struct rte_flow_indir_action_conf *conf,\n+\t\t\t\t   const struct rte_flow_action *actions,\n+\t\t\t\t   struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Async function call to create an indirect flow action object\n+ * from flow actions list.\n+ * The object is identified by a unique handle.\n+ * The handle has single state and configuration\n+ * across all the flow rules using it.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] queue_id\n+ *   Flow queue which is used to update the rule.\n+ * @param[in] attr\n+ *   Indirect action update operation attributes.\n+ * @param[in] conf\n+ *   Action configuration for the indirect action list creation.\n+ * @param[in] actions\n+ *   Specific configuration of the indirect action list.\n+ * @param[in] user_data\n+ *   The user data that will be returned on async completion event.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   A valid handle in case of success, NULL otherwise and rte_errno is set\n+ *   to one of the error codes defined:\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-ENOSYS) if underlying device does not support this functionality.\n+ *   - (-EIO) if underlying device is removed.\n+ *   - (-EINVAL) if *actions* list invalid.\n+ *   - (-ENOTSUP) if *action* list element valid but unsupported.\n+ *   - (-E2BIG) to many elements in *actions*\n+ */\n+__rte_experimental\n+struct rte_flow_action_list_handle *\n+rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,\n+\t\t\t\t\t const struct rte_flow_op_attr *attr,\n+\t\t\t\t\t const struct\n+\t\t\t\t\t rte_flow_indir_action_conf *conf,\n+\t\t\t\t\t const struct rte_flow_action *actions,\n+\t\t\t\t\t void *user_data,\n+\t\t\t\t\t struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Destroy indirect actions list by handle.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] handle\n+ *   Handle for the indirect actions list to be destroyed.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   - (0) if success.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-ENOSYS) if underlying device does not support this functionality.\n+ *   - (-EIO) if underlying device is removed.\n+ *   - (-ENOENT) if actions list pointed by *action* handle was not found.\n+ *   - (-EBUSY) if actions list pointed by *action* handle still used\n+ *   rte_errno is also set.\n+ */\n+__rte_experimental\n+int\n+rte_flow_action_list_handle_destroy(uint16_t port_id,\n+\t\t\t\t    struct rte_flow_action_list_handle *handle,\n+\t\t\t\t    struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Enqueue indirect action list destruction operation.\n+ * The destroy queue must be the same\n+ * as the queue on which the action was created.\n+ *\n+ * @param[in] port_id\n+ *   Port identifier of Ethernet device.\n+ * @param[in] queue_id\n+ *   Flow queue which is used to destroy the rule.\n+ * @param[in] op_attr\n+ *   Indirect action destruction operation attributes.\n+ * @param[in] handle\n+ *   Handle for the indirect action object to be destroyed.\n+ * @param[in] user_data\n+ *   The user data that will be returned on the completion events.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *   PMDs initialize this structure in case of error only.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+__rte_experimental\n+int\n+rte_flow_async_action_list_handle_destroy\n+\t\t(uint16_t port_id, uint32_t queue_id,\n+\t\t const struct rte_flow_op_attr *op_attr,\n+\t\t struct rte_flow_action_list_handle *handle,\n+\t\t void *user_data, struct rte_flow_error *error);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h\nindex a129a4605d..71d9b4b0a7 100644\n--- a/lib/ethdev/rte_flow_driver.h\n+++ b/lib/ethdev/rte_flow_driver.h\n@@ -121,6 +121,17 @@ struct rte_flow_ops {\n \t\t const void *update, void *query,\n \t\t enum rte_flow_query_update_mode qu_mode,\n \t\t struct rte_flow_error *error);\n+\t/** @see rte_flow_action_list_handle_create() */\n+\tstruct rte_flow_action_list_handle *(*action_list_handle_create)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_indir_action_conf *conf,\n+\t\t const struct rte_flow_action actions[],\n+\t\t struct rte_flow_error *error);\n+\t/** @see rte_flow_action_list_handle_destroy() */\n+\tint (*action_list_handle_destroy)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t struct rte_flow_action_list_handle *handle,\n+\t\t struct rte_flow_error *error);\n \t/** See rte_flow_tunnel_decap_set() */\n \tint (*tunnel_decap_set)\n \t\t(struct rte_eth_dev *dev,\n@@ -294,7 +305,7 @@ struct rte_flow_ops {\n \t\t void *data,\n \t\t void *user_data,\n \t\t struct rte_flow_error *error);\n-\t/** See rte_flow_async_action_handle_query_update */\n+\t/** @see rte_flow_async_action_handle_query_update */\n \tint (*async_action_handle_query_update)\n \t\t(struct rte_eth_dev *dev, uint32_t queue_id,\n \t\t const struct rte_flow_op_attr *op_attr,\n@@ -302,6 +313,20 @@ struct rte_flow_ops {\n \t\t const void *update, void *query,\n \t\t enum rte_flow_query_update_mode qu_mode,\n \t\t void *user_data, struct rte_flow_error *error);\n+\t/** @see rte_flow_async_action_list_handle_create() */\n+\tstruct rte_flow_action_list_handle *\n+\t(*async_action_list_handle_create)\n+\t\t(struct rte_eth_dev *dev, uint32_t queue_id,\n+\t\t const struct rte_flow_op_attr *attr,\n+\t\t const struct rte_flow_indir_action_conf *conf,\n+\t\t const struct rte_flow_action *actions,\n+\t\t void *user_data, struct rte_flow_error *error);\n+\t/** @see rte_flow_async_action_list_handle_destroy() */\n+\tint (*async_action_list_handle_destroy)\n+\t\t(struct rte_eth_dev *dev, uint32_t queue_id,\n+\t\t const struct rte_flow_op_attr *op_attr,\n+\t\t struct rte_flow_action_list_handle *action_handle,\n+\t\t void *user_data, struct rte_flow_error *error);\n };\n \n /**\ndiff --git a/lib/ethdev/version.map b/lib/ethdev/version.map\nindex 357d1a88c0..d6c0b927f1 100644\n--- a/lib/ethdev/version.map\n+++ b/lib/ethdev/version.map\n@@ -299,6 +299,10 @@ EXPERIMENTAL {\n \trte_flow_action_handle_query_update;\n \trte_flow_async_action_handle_query_update;\n \trte_flow_async_create_by_index;\n+\trte_flow_action_list_handle_create;\n+\trte_flow_action_list_handle_destroy;\n+\trte_flow_async_action_list_handle_create;\n+\trte_flow_async_action_list_handle_destroy;\n };\n \n INTERNAL {\n",
    "prefixes": []
}