get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 124355,
    "url": "http://patches.dpdk.org/api/patches/124355/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230222141139.3233715-2-elibr@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": "<20230222141139.3233715-2-elibr@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230222141139.3233715-2-elibr@nvidia.com",
    "date": "2023-02-22T14:11:38",
    "name": "[2/2] app/testpmd: user assigned flow ID to flows",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "763a61b96b501298b36c76e0f823573fd82f7023",
    "submitter": {
        "id": 2017,
        "url": "http://patches.dpdk.org/api/people/2017/?format=api",
        "name": "Eli Britstein",
        "email": "elibr@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230222141139.3233715-2-elibr@nvidia.com/mbox/",
    "series": [
        {
            "id": 27139,
            "url": "http://patches.dpdk.org/api/series/27139/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=27139",
            "date": "2023-02-22T14:11:38",
            "name": "[1/2] app/testpmd: change rule type",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/27139/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/124355/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/124355/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 446FE41D3D;\n\tWed, 22 Feb 2023 15:12:11 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id DB9C940693;\n\tWed, 22 Feb 2023 15:12:10 +0100 (CET)",
            "from NAM02-DM3-obe.outbound.protection.outlook.com\n (mail-dm3nam02on2063.outbound.protection.outlook.com [40.107.95.63])\n by mails.dpdk.org (Postfix) with ESMTP id 8E98640689\n for <dev@dpdk.org>; Wed, 22 Feb 2023 15:12:09 +0100 (CET)",
            "from DS7PR03CA0024.namprd03.prod.outlook.com (2603:10b6:5:3b8::29)\n by SJ0PR12MB5456.namprd12.prod.outlook.com (2603:10b6:a03:3ae::12) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6111.21; Wed, 22 Feb\n 2023 14:12:07 +0000",
            "from DM6NAM11FT042.eop-nam11.prod.protection.outlook.com\n (2603:10b6:5:3b8:cafe::4c) by DS7PR03CA0024.outlook.office365.com\n (2603:10b6:5:3b8::29) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6111.21 via Frontend\n Transport; Wed, 22 Feb 2023 14:12:07 +0000",
            "from mail.nvidia.com (216.228.117.160) by\n DM6NAM11FT042.mail.protection.outlook.com (10.13.173.165) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.6111.17 via Frontend Transport; Wed, 22 Feb 2023 14:12:07 +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.36; Wed, 22 Feb\n 2023 06:11:58 -0800",
            "from nvidia.com (10.126.230.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.36; Wed, 22 Feb\n 2023 06:11:56 -0800"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=HJ8U+xH3oiz1qA0RE4ip7ByChTT+EjztI5ygEvamCdYEj11qQtM8GD+kgaVdD4PF4P54rB1Vz2yxi7AyjAdicrmyTKi+cSvKgJVBcyhpEDMomiCXtkySak1adTSuPpWijfWyYw0dETAzqjn8xLvov71P8oFl3AwB8zHXxzqQ+yStzF3SqBvdeVH13r7CHEKwNhtlmwdKGosa7tVnDaD7HyPfkyyKNW0Pi4j2+T8bMMn2wgUwn7lGGMe0qd1v2ea+IhnBXt/OemWVA0KrU1w2TNqDiBCcflThY9FE4PtUjMjtFJMw9Rb84p6M3ktCh3uU7U5kc28tbiWa5Rqv2mgZbw==",
        "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=CaMMk0H9l+srtJiJ58K6l7+fUvFs+J9ijyg2uVeyFfU=;\n b=lNfyrYQlfr1HYya95YU9qcuVPlHT9JFnd9a7cUQMHKaO6k+FsgwK5VchIniqq/bjoJTYGj+yTskKS5iQNjQAisVmS8yfjXTvvOBJ3QBUZIb6W8oa60sI8LmTachxRPAsEDNbWAjkLOy+HHTmZmkfLbvCFennCKvAotDmPEDEgMvNe14m5+qfp91OglJXh98RP+oA455RS50TSg6mqhD9S+NJaVCjvnMHC89BEBGzzjfFywxXgpjj4+hN/Wrn22wxAVkCZqFI13qFmBQgwjuwCcB+zBK9GPdt4R0gdIlhumbYnKrRoia25G6Qcb56EStf6eRqlup5RzcmoUWHsvpF0Q==",
        "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=CaMMk0H9l+srtJiJ58K6l7+fUvFs+J9ijyg2uVeyFfU=;\n b=sSSHqFy/qBw/WdNsV6XSusFwAkaL5HPpykGpDoVWB+iQCtgaYl/ALSwDgYAR9OSZNDGmIed1HBogEj9guRn5MCnDW6CJBdWB9cb6aO6W96YHphgVnCO7PeGRThaM/kb1JUt7lAcvylozsLTXG+2pXSYwWQIzMQANLVkK25RRPaO+MufIrt64fdWYnutvY+FylESf0NXk6WyRyR+D1fTDa/vLU3wEYcPOzD8gtFrlAVmcWkhZkUvaIJuPoMfS/MPNW0PwWEIljnW4lQw5aObn/I7OcX2DrZoVfcN7m/3uN88qbAfaaCSACigirOxzzD294NhcVFVeaTJSgE2sJs5BQw==",
        "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": "Eli Britstein <elibr@nvidia.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<asafp@nvidia.com>, Thomas Monjalon <thomas@monjalon.net>, Eli Britstein\n <elibr@nvidia.com>, Ori Kam <orika@nvidia.com>, Aman Singh\n <aman.deep.singh@intel.com>, Yuying Zhang <yuying.zhang@intel.com>",
        "Subject": "[PATCH 2/2] app/testpmd: user assigned flow ID to flows",
        "Date": "Wed, 22 Feb 2023 16:11:38 +0200",
        "Message-ID": "<20230222141139.3233715-2-elibr@nvidia.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230222141139.3233715-1-elibr@nvidia.com>",
        "References": "<20230222141139.3233715-1-elibr@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.230.37]",
        "X-ClientProxiedBy": "rnnvmail201.nvidia.com (10.129.68.8) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "DM6NAM11FT042:EE_|SJ0PR12MB5456:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "702c4d75-baae-4b7d-5a98-08db14dec7fb",
        "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 roV2GKFa3cEz3xvBpz4pfBYUEk9hAdimgLo3MwsbGJrWwb55MSvPvmltfgMtHISXjbKKOUEcmJdqSE3sXFBvIZKJdcT0FXazQS9fr7iKZGH8F1p1bRbDAO1PVmKjlMgUTj46dd9WJbyUKV0DV4k9tqjTWKbkmYBCGx6DGaRYr2r6YeJ6rGvRVLPU5o0pfKUvO4ZiSGSKFaFInaVk+jR3pyO7rgweeWq8yrvtzvUd3F1uQ5Wbp+JqHwm0ed6LhejkeAD+1jeWKE5W846wp5ND5D9NkiIOSB+jCFx+xpeYjnEl1q1ISghN5vO3AoijBI/RCMD4+3eRm7w00vubW0VzXtPxzBDEe5PcW13biWLwuVO1WwTYgzXEj/RFeLNL0qJPLJUuuo1JehzGfFHLmrDcIHdtJPjrnaDkX1ENOwPDCxoQ1iTif7aFbWG/Psb6t3SBuqBncRa/+68YZ7ABnMZRxTrjULZJ+BzdrnXQ9OxvRjIPezwfLd1U5eEpuJqjj/txc9C9R90HIqiiuSK5C26ini50fmI4sPhi33MzAexGag0BM1rchYwjODdz9/h6VGD2FGoB9wSJdQe78XvsUhBSXWMTsT56W8ESEpOpAI/ni8CxZgxW5ILnb7H7Esoub6X6xSKCUwInNi7e2UFDYzlMmdoXT9elrycYtVWPRs8mGeJ4Em3d+Q44zkaiz0TE3fPiajFwqbpyM9/2oq161drAZOhf3ZL52Dy+Kbhl9lR6JiQ=",
        "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:(13230025)(4636009)(136003)(396003)(376002)(346002)(39860400002)(451199018)(46966006)(36840700001)(40470700004)(30864003)(356005)(5660300002)(82740400003)(47076005)(8936002)(41300700001)(36860700001)(82310400005)(2906002)(34020700004)(2616005)(478600001)(86362001)(8676002)(4326008)(6916009)(70586007)(70206006)(426003)(54906003)(316002)(7636003)(6666004)(36756003)(26005)(6286002)(16526019)(1076003)(40480700001)(7696005)(336012)(83380400001)(40460700003)(186003)(55016003);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "22 Feb 2023 14:12:07.1928 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 702c4d75-baae-4b7d-5a98-08db14dec7fb",
        "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 DM6NAM11FT042.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SJ0PR12MB5456",
        "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": "Currently, testpmd assigns its own IDs, as indices, to created flows.\nLater, the flow index is used as the ID for flow operations (query,\ndestroy, dump).\n\nAllow the user to assign a user-id, to be later used as an alternative\nto the flow index testpmd assigns.\n\nExample:\n\ntestpmd> flow create 0 ingress user_id 0x1234 pattern eth / end actions\ncount / drop / end\nFlow rule #0 created, user-id 0x1234\n\ntestpmd> flow query 0 0x1234 count user_id\n\ntestpmd> flow dump 0 user_id rule 0x1234\n\ntestpmd> flow destroy 0 rule 0x1234 user_id\nFlow rule user_id 0x1234 destroyed\n\ntestpmd> flow destroy 0 rule 0x1234 user_id\nFlow rule #0 destroyed, user-id 0x1234\n\nSigned-off-by: Eli Britstein <elibr@nvidia.com>\n---\n app/test-pmd/cmdline_flow.c                 | 72 +++++++++++++++++++--\n app/test-pmd/config.c                       | 34 +++++++---\n app/test-pmd/testpmd.h                      | 12 ++--\n doc/guides/testpmd_app_ug/testpmd_funcs.rst | 14 ++--\n 4 files changed, 108 insertions(+), 24 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex a2709e8aa9..758ca03966 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -206,9 +206,11 @@ enum index {\n \n \t/* Destroy arguments. */\n \tDESTROY_RULE,\n+\tDESTROY_IS_USER_ID,\n \n \t/* Query arguments. */\n \tQUERY_ACTION,\n+\tQUERY_IS_USER_ID,\n \n \t/* List arguments. */\n \tLIST_GROUP,\n@@ -224,10 +226,12 @@ enum index {\n \tVC_TRANSFER,\n \tVC_TUNNEL_SET,\n \tVC_TUNNEL_MATCH,\n+\tVC_USER_ID,\n \n \t/* Dump arguments */\n \tDUMP_ALL,\n \tDUMP_ONE,\n+\tDUMP_IS_USER_ID,\n \n \t/* Configure arguments */\n \tCONFIG_QUEUES_NUMBER,\n@@ -1077,6 +1081,7 @@ struct buffer {\n \t\t\tuint32_t act_templ_id;\n \t\t\tstruct rte_flow_attr attr;\n \t\t\tstruct tunnel_ops tunnel_ops;\n+\t\t\tuintptr_t user_id;\n \t\t\tstruct rte_flow_item *pattern;\n \t\t\tstruct rte_flow_action *actions;\n \t\t\tstruct rte_flow_action *masks;\n@@ -1087,15 +1092,18 @@ struct buffer {\n \t\tstruct {\n \t\t\tuintptr_t *rule;\n \t\t\tuintptr_t rule_n;\n+\t\t\tbool is_user_id;\n \t\t} destroy; /**< Destroy arguments. */\n \t\tstruct {\n \t\t\tchar file[128];\n \t\t\tbool mode;\n \t\t\tuintptr_t rule;\n+\t\t\tbool is_user_id;\n \t\t} dump; /**< Dump arguments. */\n \t\tstruct {\n \t\t\tuintptr_t rule;\n \t\t\tstruct rte_flow_action action;\n+\t\t\tbool is_user_id;\n \t\t} query; /**< Query arguments. */\n \t\tstruct {\n \t\t\tuint32_t *group;\n@@ -1319,6 +1327,7 @@ static const enum index next_ia_qu_attr[] = {\n static const enum index next_dump_subcmd[] = {\n \tDUMP_ALL,\n \tDUMP_ONE,\n+\tDUMP_IS_USER_ID,\n \tZERO,\n };\n \n@@ -1339,12 +1348,14 @@ static const enum index next_vc_attr[] = {\n \tVC_TRANSFER,\n \tVC_TUNNEL_SET,\n \tVC_TUNNEL_MATCH,\n+\tVC_USER_ID,\n \tITEM_PATTERN,\n \tZERO,\n };\n \n static const enum index next_destroy_attr[] = {\n \tDESTROY_RULE,\n+\tDESTROY_IS_USER_ID,\n \tEND,\n \tZERO,\n };\n@@ -1355,6 +1366,12 @@ static const enum index next_dump_attr[] = {\n \tZERO,\n };\n \n+static const enum index next_query_attr[] = {\n+\tQUERY_IS_USER_ID,\n+\tEND,\n+\tZERO,\n+};\n+\n static const enum index next_list_attr[] = {\n \tLIST_GROUP,\n \tEND,\n@@ -3533,7 +3550,7 @@ static const struct token token_list[] = {\n \t[DESTROY] = {\n \t\t.name = \"destroy\",\n \t\t.help = \"destroy specific flow rules\",\n-\t\t.next = NEXT(NEXT_ENTRY(DESTROY_RULE),\n+\t\t.next = NEXT(next_destroy_attr,\n \t\t\t     NEXT_ENTRY(COMMON_PORT_ID)),\n \t\t.args = ARGS(ARGS_ENTRY(struct buffer, port)),\n \t\t.call = parse_destroy,\n@@ -3555,7 +3572,7 @@ static const struct token token_list[] = {\n \t[QUERY] = {\n \t\t.name = \"query\",\n \t\t.help = \"query an existing flow rule\",\n-\t\t.next = NEXT(NEXT_ENTRY(QUERY_ACTION),\n+\t\t.next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION),\n \t\t\t     NEXT_ENTRY(COMMON_RULE_ID),\n \t\t\t     NEXT_ENTRY(COMMON_PORT_ID)),\n \t\t.args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),\n@@ -3674,6 +3691,12 @@ static const struct token token_list[] = {\n \t\t.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),\n \t\t.call = parse_destroy,\n \t},\n+\t[DESTROY_IS_USER_ID] = {\n+\t\t.name = \"user_id\",\n+\t\t.help = \"rule identifier is user-id\",\n+\t\t.next = NEXT(next_destroy_attr),\n+\t\t.call = parse_destroy,\n+\t},\n \t/* Dump arguments. */\n \t[DUMP_ALL] = {\n \t\t.name = \"all\",\n@@ -3690,6 +3713,12 @@ static const struct token token_list[] = {\n \t\t\t\tARGS_ENTRY(struct buffer, args.dump.rule)),\n \t\t.call = parse_dump,\n \t},\n+\t[DUMP_IS_USER_ID] = {\n+\t\t.name = \"user_id\",\n+\t\t.help = \"rule identifier is user-id\",\n+\t\t.next = NEXT(next_dump_subcmd),\n+\t\t.call = parse_dump,\n+\t},\n \t/* Query arguments. */\n \t[QUERY_ACTION] = {\n \t\t.name = \"{action}\",\n@@ -3698,6 +3727,12 @@ static const struct token token_list[] = {\n \t\t.call = parse_action,\n \t\t.comp = comp_action,\n \t},\n+\t[QUERY_IS_USER_ID] = {\n+\t\t.name = \"user_id\",\n+\t\t.help = \"rule identifier is user-id\",\n+\t\t.next = NEXT(next_query_attr),\n+\t\t.call = parse_query,\n+\t},\n \t/* List arguments. */\n \t[LIST_GROUP] = {\n \t\t.name = \"group\",\n@@ -3759,6 +3794,13 @@ static const struct token token_list[] = {\n \t\t.args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)),\n \t\t.call = parse_vc,\n \t},\n+\t[VC_USER_ID] = {\n+\t\t.name = \"user_id\",\n+\t\t.help = \"specify a user id to create\",\n+\t\t.next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)),\n+\t\t.call = parse_vc,\n+\t},\n \t/* Validate/create pattern. */\n \t[ITEM_PATTERN] = {\n \t\t.name = \"pattern\",\n@@ -7415,11 +7457,15 @@ parse_vc(struct context *ctx, const struct token *token,\n \tcase VC_TUNNEL_MATCH:\n \t\tctx->object = &out->args.vc.tunnel_ops;\n \t\tbreak;\n+\tcase VC_USER_ID:\n+\t\tctx->object = out;\n+\t\tbreak;\n \t}\n \tctx->objmask = NULL;\n \tswitch (ctx->curr) {\n \tcase VC_GROUP:\n \tcase VC_PRIORITY:\n+\tcase VC_USER_ID:\n \t\treturn len;\n \tcase VC_TUNNEL_SET:\n \t\tout->args.vc.tunnel_ops.enabled = 1;\n@@ -9109,6 +9155,10 @@ parse_destroy(struct context *ctx, const struct token *token,\n \t\t\t\t\t       sizeof(double));\n \t\treturn len;\n \t}\n+\tif (ctx->curr == DESTROY_IS_USER_ID) {\n+\t\tout->args.destroy.is_user_id = true;\n+\t\treturn len;\n+\t}\n \tif (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) +\n \t     sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size)\n \t\treturn -1;\n@@ -9179,6 +9229,9 @@ parse_dump(struct context *ctx, const struct token *token,\n \t\tctx->object = out;\n \t\tctx->objmask = NULL;\n \t\treturn len;\n+\tcase DUMP_IS_USER_ID:\n+\t\tout->args.dump.is_user_id = true;\n+\t\treturn len;\n \tdefault:\n \t\treturn -1;\n \t}\n@@ -9208,6 +9261,10 @@ parse_query(struct context *ctx, const struct token *token,\n \t\tctx->object = out;\n \t\tctx->objmask = NULL;\n \t}\n+\tif (ctx->curr == QUERY_IS_USER_ID) {\n+\t\tout->args.query.is_user_id = true;\n+\t\treturn len;\n+\t}\n \treturn len;\n }\n \n@@ -11602,11 +11659,12 @@ cmd_flow_parsed(const struct buffer *in)\n \tcase CREATE:\n \t\tport_flow_create(in->port, &in->args.vc.attr,\n \t\t\t\t in->args.vc.pattern, in->args.vc.actions,\n-\t\t\t\t &in->args.vc.tunnel_ops);\n+\t\t\t\t &in->args.vc.tunnel_ops, in->args.vc.user_id);\n \t\tbreak;\n \tcase DESTROY:\n \t\tport_flow_destroy(in->port, in->args.destroy.rule_n,\n-\t\t\t\t  in->args.destroy.rule);\n+\t\t\t\t  in->args.destroy.rule,\n+\t\t\t\t  in->args.destroy.is_user_id);\n \t\tbreak;\n \tcase FLUSH:\n \t\tport_flow_flush(in->port);\n@@ -11614,11 +11672,13 @@ cmd_flow_parsed(const struct buffer *in)\n \tcase DUMP_ONE:\n \tcase DUMP_ALL:\n \t\tport_flow_dump(in->port, in->args.dump.mode,\n-\t\t\t\tin->args.dump.rule, in->args.dump.file);\n+\t\t\t\tin->args.dump.rule, in->args.dump.file,\n+\t\t\t\tin->args.dump.is_user_id);\n \t\tbreak;\n \tcase QUERY:\n \t\tport_flow_query(in->port, in->args.query.rule,\n-\t\t\t\t&in->args.query.action);\n+\t\t\t\t&in->args.query.action,\n+\t\t\t\tin->args.query.is_user_id);\n \t\tbreak;\n \tcase LIST:\n \t\tport_flow_list(in->port, in->args.list.group_n,\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 167cb246c5..51cc480762 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -3303,7 +3303,8 @@ port_flow_create(portid_t port_id,\n \t\t const struct rte_flow_attr *attr,\n \t\t const struct rte_flow_item *pattern,\n \t\t const struct rte_flow_action *actions,\n-\t\t const struct tunnel_ops *tunnel_ops)\n+\t\t const struct tunnel_ops *tunnel_ops,\n+\t\t uintptr_t user_id)\n {\n \tstruct rte_flow *flow;\n \tstruct rte_port *port;\n@@ -3351,17 +3352,23 @@ port_flow_create(portid_t port_id,\n \t}\n \tpf->next = port->flow_list;\n \tpf->id = id;\n+\tpf->user_id = user_id;\n \tpf->flow = flow;\n \tport->flow_list = pf;\n \tif (tunnel_ops->enabled)\n \t\tport_flow_tunnel_offload_cmd_release(port_id, tunnel_ops, pft);\n-\tprintf(\"Flow rule #%\"PRIu64\" created\\n\", pf->id);\n+\tif (user_id)\n+\t\tprintf(\"Flow rule #%\"PRIu64\" created, user-id 0x%\"PRIx64\"\\n\",\n+\t\t       pf->id, pf->user_id);\n+\telse\n+\t\tprintf(\"Flow rule #%\"PRIu64\" created\\n\", pf->id);\n \treturn 0;\n }\n \n /** Destroy a number of flow rules. */\n int\n-port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule)\n+port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule,\n+\t\t  bool is_user_id)\n {\n \tstruct rte_port *port;\n \tstruct port_flow **tmp;\n@@ -3379,7 +3386,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule)\n \t\t\tstruct rte_flow_error error;\n \t\t\tstruct port_flow *pf = *tmp;\n \n-\t\t\tif (rule[i] != pf->id)\n+\t\t\tif (rule[i] != (is_user_id ? pf->user_id : pf->id))\n \t\t\t\tcontinue;\n \t\t\t/*\n \t\t\t * Poisoning to make sure PMDs update it in case\n@@ -3390,7 +3397,13 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule)\n \t\t\t\tret = port_flow_complain(&error);\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tprintf(\"Flow rule #%\"PRIu64\" destroyed\\n\", pf->id);\n+\t\t\tif (is_user_id)\n+\t\t\t\tprintf(\"Flow rule #%\"PRIu64\" destroyed, \"\n+\t\t\t\t       \"user-id 0x%\"PRIx64\"\\n\",\n+\t\t\t\t       pf->id, pf->user_id);\n+\t\t\telse\n+\t\t\t\tprintf(\"Flow rule #%\"PRIu64\" destroyed\\n\",\n+\t\t\t\t       pf->id);\n \t\t\t*tmp = pf->next;\n \t\t\tfree(pf);\n \t\t\tbreak;\n@@ -3436,7 +3449,7 @@ port_flow_flush(portid_t port_id)\n /** Dump flow rules. */\n int\n port_flow_dump(portid_t port_id, bool dump_all, uintptr_t rule_id,\n-\t\tconst char *file_name)\n+\t\tconst char *file_name, bool is_user_id)\n {\n \tint ret = 0;\n \tFILE *file = stdout;\n@@ -3454,7 +3467,8 @@ port_flow_dump(portid_t port_id, bool dump_all, uintptr_t rule_id,\n \t\tport = &ports[port_id];\n \t\tpflow = port->flow_list;\n \t\twhile (pflow) {\n-\t\t\tif (rule_id != pflow->id) {\n+\t\t\tif (rule_id !=\n+\t\t\t    (is_user_id ? pflow->user_id : pflow->id)) {\n \t\t\t\tpflow = pflow->next;\n \t\t\t} else {\n \t\t\t\ttmpFlow = pflow->flow;\n@@ -3496,7 +3510,7 @@ port_flow_dump(portid_t port_id, bool dump_all, uintptr_t rule_id,\n /** Query a flow rule. */\n int\n port_flow_query(portid_t port_id, uintptr_t rule,\n-\t\tconst struct rte_flow_action *action)\n+\t\tconst struct rte_flow_action *action, bool is_user_id)\n {\n \tstruct rte_flow_error error;\n \tstruct rte_port *port;\n@@ -3514,7 +3528,7 @@ port_flow_query(portid_t port_id, uintptr_t rule,\n \t\treturn -EINVAL;\n \tport = &ports[port_id];\n \tfor (pf = port->flow_list; pf; pf = pf->next)\n-\t\tif (pf->id == rule)\n+\t\tif ((is_user_id ? pf->user_id : pf->id) == rule)\n \t\t\tbreak;\n \tif (!pf) {\n \t\tfprintf(stderr, \"Flow rule #%\"PRIu64\" not found\\n\", rule);\n@@ -3634,7 +3648,7 @@ port_flow_aged(portid_t port_id, uint8_t destroy)\n \t\t\t       ctx.pf->rule.attr->egress ? 'e' : '-',\n \t\t\t       ctx.pf->rule.attr->transfer ? 't' : '-');\n \t\t\tif (destroy && !port_flow_destroy(port_id, 1,\n-\t\t\t\t\t\t\t  &ctx.pf->id))\n+\t\t\t\t\t\t\t  &ctx.pf->id, false))\n \t\t\t\ttotal++;\n \t\t\tbreak;\n \t\tcase ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION:\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex ba29d97293..b18ebeaf83 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -216,6 +216,7 @@ struct port_flow {\n \tstruct port_flow *next; /**< Next flow in list. */\n \tstruct port_flow *tmp; /**< Temporary linking. */\n \tuintptr_t id; /**< Flow rule ID. */\n+\tuintptr_t user_id; /**< User rule ID. */\n \tstruct rte_flow *flow; /**< Opaque flow object returned by PMD. */\n \tstruct rte_flow_conv_rule rule; /**< Saved flow rule description. */\n \tenum age_action_context_type age_type; /**< Age action context type. */\n@@ -979,17 +980,20 @@ int port_flow_create(portid_t port_id,\n \t\t     const struct rte_flow_attr *attr,\n \t\t     const struct rte_flow_item *pattern,\n \t\t     const struct rte_flow_action *actions,\n-\t\t     const struct tunnel_ops *tunnel_ops);\n+\t\t     const struct tunnel_ops *tunnel_ops,\n+\t\t     uintptr_t user_id);\n int port_action_handle_query(portid_t port_id, uint32_t id);\n void update_age_action_context(const struct rte_flow_action *actions,\n \t\t     struct port_flow *pf);\n int mcast_addr_pool_destroy(portid_t port_id);\n-int port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule);\n+int port_flow_destroy(portid_t port_id, uint32_t n, const uintptr_t *rule,\n+\t\t      bool is_user_id);\n int port_flow_flush(portid_t port_id);\n int port_flow_dump(portid_t port_id, bool dump_all,\n-\t\t\tuintptr_t rule, const char *file_name);\n+\t\t\tuintptr_t rule, const char *file_name,\n+\t\t\tbool is_user_id);\n int port_flow_query(portid_t port_id, uintptr_t rule,\n-\t\t    const struct rte_flow_action *action);\n+\t\t    const struct rte_flow_action *action, bool is_user_id);\n void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group);\n void port_flow_aged(portid_t port_id, uint8_t destroy);\n const char *port_flow_tunnel_type(struct rte_flow_tunnel *tunnel);\ndiff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\nindex 5a88933635..92cf7d5adf 100644\n--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst\n@@ -3010,12 +3010,14 @@ following sections.\n \n    flow create {port_id}\n        [group {group_id}] [priority {level}] [ingress] [egress] [transfer]\n-       pattern {item} [/ {item} [...]] / end\n+       [user_id {user_id}] pattern {item} [/ {item} [...]] / end\n        actions {action} [/ {action} [...]] / end\n \n - Destroy specific flow rules::\n \n-   flow destroy {port_id} rule {rule_id} [...]\n+   flow destroy {port_id} rule {rule_id} [...] [user_id]\n+   [user_id] is used as an optional flag to indicate the rule_id is the\n+   user_id assigned in \"flow create\".\n \n - Destroy all flow rules::\n \n@@ -3023,7 +3025,9 @@ following sections.\n \n - Query an existing flow rule::\n \n-   flow query {port_id} {rule_id} {action}\n+   flow query {port_id} {rule_id} {action} [user_id]\n+   [user_id] is used as an optional flag to indicate the rule_id is the\n+   user_id assigned in \"flow create\".\n \n - List existing flow rules sorted by priority, filtered by group\n   identifiers::\n@@ -3040,7 +3044,9 @@ following sections.\n \n   for one flow::\n \n-   flow dump {port_id} rule {rule_id} {output_file}\n+   flow dump {port_id} rule {rule_id} {output_file} [user_id]\n+   [user_id] is used as an optional flag to indicate the rule_id is the\n+   user_id assigned in \"flow create\".\n \n - List and destroy aged flow rules::\n \n",
    "prefixes": [
        "2/2"
    ]
}