get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 102451,
    "url": "http://patches.dpdk.org/api/patches/102451/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20211020151457.17577-3-viacheslavo@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": "<20211020151457.17577-3-viacheslavo@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211020151457.17577-3-viacheslavo@nvidia.com",
    "date": "2021-10-20T15:14:55",
    "name": "[v8,2/4] ethdev: introduce configurable flexible item",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "e817a4d89a6f91bccef7db7e522acf35a5b83c5a",
    "submitter": {
        "id": 1926,
        "url": "http://patches.dpdk.org/api/people/1926/?format=api",
        "name": "Slava Ovsiienko",
        "email": "viacheslavo@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/20211020151457.17577-3-viacheslavo@nvidia.com/mbox/",
    "series": [
        {
            "id": 19846,
            "url": "http://patches.dpdk.org/api/series/19846/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=19846",
            "date": "2021-10-20T15:14:53",
            "name": "ethdev: introduce configurable flexible item",
            "version": 8,
            "mbox": "http://patches.dpdk.org/series/19846/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/102451/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/102451/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 D3F03A0C43;\n\tWed, 20 Oct 2021 17:15:59 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8CA6E4123A;\n\tWed, 20 Oct 2021 17:15:52 +0200 (CEST)",
            "from NAM12-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam12on2079.outbound.protection.outlook.com [40.107.237.79])\n by mails.dpdk.org (Postfix) with ESMTP id 31A1D411BB\n for <dev@dpdk.org>; Wed, 20 Oct 2021 17:15:51 +0200 (CEST)",
            "from BN0PR04CA0038.namprd04.prod.outlook.com (2603:10b6:408:e8::13)\n by SN1PR12MB2573.namprd12.prod.outlook.com (2603:10b6:802:2b::21)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.18; Wed, 20 Oct\n 2021 15:15:48 +0000",
            "from BN8NAM11FT013.eop-nam11.prod.protection.outlook.com\n (2603:10b6:408:e8:cafe::58) by BN0PR04CA0038.outlook.office365.com\n (2603:10b6:408:e8::13) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4628.15 via Frontend\n Transport; Wed, 20 Oct 2021 15:15:46 +0000",
            "from mail.nvidia.com (216.228.112.34) by\n BN8NAM11FT013.mail.protection.outlook.com (10.13.176.182) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4628.16 via Frontend Transport; Wed, 20 Oct 2021 15:15:46 +0000",
            "from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com\n (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 20 Oct\n 2021 15:15:31 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=bt/tRdHCFqFLjv0GbgmnaPc7k9eRWIVWU4AI39OvDsIC5tPMLxB/PbKvNo2v1ox5X3ZWVGyAh2h+wpXvfHiHTHFjZdIij/sGyH4iVx1IGUGNXpQBOLRg1bqSmJvUN40w2FrhAgVJNrTCtmdz73wyON+/36e10Ox/13Yj+fkGS77x97Yjtu2uJziM7AHU1C7G30A+o3T31BW2RZYXB4ERVPKnX7KsgAeHecyIudsWJgAhxx/RYLUYxvkY4FBTeXAiv+A1tLmYRfNA4/S6B6vIBj27xhmAveEyuofVFpW0wKrCGI9cz8E8oy/XyNYqWF6DAJU0h4s+Nj9Kj1HSws8Hjg==",
        "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=eeusMxanBvIOj8ajxbTINYbdRm7alhHaaOXMyjvI3pE=;\n b=WbPYUirV2kFgG/9zFu5mf487KyUT42EAtiiUQgznU9hN2+LN7bqalJyF4taQldy5NdzgHsR03/tDaAiodHDFf/EJQn7pDRPriJNcb/ASVaDlZomYS+DHm68qjYQNEBF6+r5+FAbg52mAjh6um6Ouub85J2MaPKVLlSpDdZezyUkqmRLLXp+yduaCiMGkIcLuz1hvO0JJ5CgHBoQqRx8mrlP6d+jz2sMAoH9b2MCGgzMyHOL60QcX86FtT1nz1P2HaH4batTJ/2aWRWsUmpYG9cUmhtyV/bunqVuyS5ELUnmMGVJsTJa1/1KAA8VmCVvOj4AR0dWq7zGVmqsAkipfpw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com;\n dmarc=pass (p=quarantine sp=quarantine pct=100) action=none\n header.from=nvidia.com; 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=eeusMxanBvIOj8ajxbTINYbdRm7alhHaaOXMyjvI3pE=;\n b=msI41s0RXKDkgGV2cIqYVbIFBsvRH7u+bhpcTeQ/3ws5Gus+b7LYN91ejPJ+VlcRswFBqQ/VvO3nQygQVRkNFrSf8/9Opj5NClb/4mJ3//qkMbsV9eCLvKvrT+XZt6M2f73xc0ABwyfurMAKhoPzz4h5Keumu59TqrZX7jGqVnlJqcs10TxlC4s+9f2KM67vAnQuv/FOPKLLBYYCbC2ePiLFxYstr0F3ovh8QlgjzqLA5AkN0Z8+L1x1aLlfj2lKOu0y2dKz+NbH3faiDc6clyFLx30RtZJvQwKAC1Q8e34DirdKeWq8s0yPzJ5PQUlMfPX+RXoaIBHepvCqaqcRrw==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.112.34)\n smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed)\n header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.112.34 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.112.34; helo=mail.nvidia.com;",
        "From": "Viacheslav Ovsiienko <viacheslavo@nvidia.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<rasland@nvidia.com>, <matan@nvidia.com>, <shahafs@nvidia.com>,\n <orika@nvidia.com>, <getelson@nvidia.com>, <thomas@monjalon.net>",
        "Date": "Wed, 20 Oct 2021 18:14:55 +0300",
        "Message-ID": "<20211020151457.17577-3-viacheslavo@nvidia.com>",
        "X-Mailer": "git-send-email 2.18.1",
        "In-Reply-To": "<20211020151457.17577-1-viacheslavo@nvidia.com>",
        "References": "<20210922180418.20663-1-viacheslavo@nvidia.com>\n <20211020151457.17577-1-viacheslavo@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[172.20.187.6]",
        "X-ClientProxiedBy": "HQMAIL107.nvidia.com (172.20.187.13) To\n HQMAIL107.nvidia.com (172.20.187.13)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "f2bfb48e-e3d2-416b-9805-08d993dc7e1a",
        "X-MS-TrafficTypeDiagnostic": "SN1PR12MB2573:",
        "X-LD-Processed": "43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr",
        "X-Microsoft-Antispam-PRVS": "\n <SN1PR12MB25733500F8D847A06125A83DDFBE9@SN1PR12MB2573.namprd12.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:10000;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n oCIYJYrdiflF3ErGetwWZeYMtVTvBeDLG6/FeqtEefS4oEuNDBGzybbgh9udj8WwCGCwqcn84wRvEHNRVe/CtmaC0hOR3R3Tqil+xzg7aVW61PZRennxNxlpvo+xHw6+nPyT/h9hsENpBhuJE578b65wljopm7yaV0L+za2Y2ucIEDEAI9mnSR7b5rqwZHVbLOniQYx2bVslI9Ksk3gYqiXHw1siBydkUgg1XOSndpW3J8TqWVYXUv6LFzlu4JEqkG6wrTml0VLswvah9tRzC19SXpZxJquwCxAOuD3jOf3lA9W+YJAZUA1CIEZoUEycLs2hYWwHqjtz/XImVSt8AGRC9zID4lvxNUi5wx+Bb7UuIT8NKO+CZ7/lRxVzp4TrS0wdPRX5mwSpe+gv5MhOiO7HqkUxh//Irhxm7LF9ejTChbdHZliXX9PtIG5H9kImcZuU0V6aimxh5oFphSJdZwAeLzcY/v7afwWX4JL2Lo/4qvfkBzzxU9HDv7HcVQkpfSm+L156j7ln0IWOfE20MqppO0UkjiouW1oMCmB/jOtQZjIziGB3kFlv/lHUOsylu9YUZf7ciFgcYSW+iiCMbdTcLFNgrknwWf3MqTyKWfnRddUaDOCMGjNhDRVEgTduyf0Y/SpYDfnvXb5TmhA3YWn8wa3Rph0yjQJJHJDmO//pw/U2KN/fvukDwsrypWx2DX+YS3PmWczxXYGogYM50g==",
        "X-Forefront-Antispam-Report": "CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;\n SFS:(4636009)(36840700001)(46966006)(426003)(86362001)(8676002)(16526019)(508600001)(70206006)(55016002)(1076003)(70586007)(336012)(2616005)(30864003)(7636003)(8936002)(83380400001)(26005)(6666004)(356005)(36860700001)(5660300002)(36756003)(47076005)(2906002)(6916009)(6286002)(186003)(316002)(36906005)(4326008)(54906003)(82310400003)(7696005);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "20 Oct 2021 15:15:46.5737 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n f2bfb48e-e3d2-416b-9805-08d993dc7e1a",
        "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.112.34];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n BN8NAM11FT013.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SN1PR12MB2573",
        "Subject": "[dpdk-dev] [PATCH v8 2/4] ethdev: introduce configurable flexible\n item",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "1. Introduction and Retrospective\n\nNowadays the networks are evolving fast and wide, the network\nstructures are getting more and more complicated, the new\napplication areas are emerging. To address these challenges\nthe new network protocols are continuously being developed,\nconsidered by technical communities, adopted by industry and,\neventually implemented in hardware and software. The DPDK\nframework follows the common trends and if we bother\nto glance at the RTE Flow API header we see the multiple\nnew items were introduced during the last years since\nthe initial release.\n\nThe new protocol adoption and implementation process is\nnot straightforward and takes time, the new protocol passes\ndevelopment, consideration, adoption, and implementation\nphases. The industry tries to mitigate and address the\nforthcoming network protocols, for example, many hardware\nvendors are implementing flexible and configurable network\nprotocol parsers. As DPDK developers, could we anticipate\nthe near future in the same fashion and introduce the similar\nflexibility in RTE Flow API?\n\nLet's check what we already have merged in our project, and\nwe see the nice raw item (rte_flow_item_raw). At the first\nglance, it looks superior and we can try to implement a flow\nmatching on the header of some relatively new tunnel protocol,\nsay on the GENEVE header with variable length options. And,\nunder further consideration, we run into the raw item\nlimitations:\n\n- only fixed size network header can be represented\n- the entire network header pattern of fixed format\n  (header field offsets are fixed) must be provided\n- the search for patterns is not robust (the wrong matches\n  might be triggered), and actually is not supported\n  by existing PMDs\n- no explicitly specified relations with preceding\n  and following items\n- no tunnel hint support\n\nAs the result, implementing the support for tunnel protocols\nlike aforementioned GENEVE with variable extra protocol option\nwith flow raw item becomes very complicated and would require\nmultiple flows and multiple raw items chained in the same\nflow (by the way, there is no support found for chained raw\nitems in implemented drivers).\n\nThis RFC introduces the dedicated flex item (rte_flow_item_flex)\nto handle matches with existing and new network protocol headers\nin a unified fashion.\n\n2. Flex Item Life Cycle\n\nLet's assume there are the requirements to support the new\nnetwork protocol with RTE Flows. What is given within protocol\nspecification:\n\n  - header format\n  - header length, (can be variable, depending on options)\n  - potential presence of extra options following or included\n    in the header the header\n  - the relations with preceding protocols. For example,\n    the GENEVE follows UDP, eCPRI can follow either UDP\n    or L2 header\n  - the relations with following protocols. For example,\n    the next layer after tunnel header can be L2 or L3\n  - whether the new protocol is a tunnel and the header\n    is a splitting point between outer and inner layers\n\nThe supposed way to operate with flex item:\n\n  - application defines the header structures according to\n    protocol specification\n\n  - application calls rte_flow_flex_item_create() with desired\n    configuration according to the protocol specification, it\n    creates the flex item object over specified ethernet device\n    and prepares PMD and underlying hardware to handle flex\n    item. On item creation call PMD backing the specified\n    ethernet device returns the opaque handle identifying\n    the object has been created\n\n  - application uses the rte_flow_item_flex with obtained handle\n    in the flows, the values/masks to match with fields in the\n    header are specified in the flex item per flow as for regular\n    items (except that pattern buffer combines all fields)\n\n  - flows with flex items match with packets in a regular fashion,\n    the values and masks for the new protocol header match are\n    taken from the flex items in the flows\n\n  - application destroys flows with flex items\n\n  - application calls rte_flow_flex_item_release() as part of\n    ethernet device API and destroys the flex item object in\n    PMD and releases the engaged hardware resources\n\n3. Flex Item Structure\n\nThe flex item structure is intended to be used as part of the flow\npattern like regular RTE flow items and provides the mask and\nvalue to match with fields of the protocol item was configured\nfor.\n\n  struct rte_flow_item_flex {\n    void *handle;\n    uint32_t length;\n    const uint8_t* pattern;\n  };\n\nThe handle is some opaque object maintained on per device basis\nby underlying driver.\n\nThe protocol header fields are considered as bit fields, all\noffsets and widths are expressed in bits. The pattern is the\nbuffer containing the bit concatenation of all the fields\npresented at item configuration time, in the same order and\nsame amount. If byte boundary alignment is needed an application\ncan use a dummy type field, this is just some kind of gap filler.\n\nThe length field specifies the pattern buffer length in bytes\nand is needed to allow rte_flow_copy() operations. The approach\nof multiple pattern pointers and lengths (per field) was\nconsidered and found clumsy - it seems to be much suitable for\nthe application to maintain the single structure within the\nsingle pattern buffer.\n\n4. Flex Item Configuration\n\nThe flex item configuration consists of the following parts:\n\n  - header field descriptors:\n    - next header\n    - next protocol\n    - sample to match\n  - input link descriptors\n  - output link descriptors\n\nThe field descriptors tell the driver and hardware what data should\nbe extracted from the packet and then control the packet handling\nin the flow engine. Besides this, sample fields can be presented\nto match with patterns in the flows. Each field is a bit pattern.\nIt has width, offset from the header beginning, mode of offset\ncalculation, and offset related parameters.\n\nThe next header field is special, no data are actually taken\nfrom the packet, but its offset is used as a pointer to the next\nheader in the packet, in other words the next header offset\nspecifies the size of the header being parsed by flex item.\n\nThere is one more special field - next protocol, it specifies\nwhere the next protocol identifier is contained and packet data\nsampled from this field will be used to determine the next\nprotocol header type to continue packet parsing. The next\nprotocol field is like eth_type field in MAC2, or proto field\nin IPv4/v6 headers.\n\nThe sample fields are used to represent the data be sampled\nfrom the packet and then matched with established flows.\n\nThere are several methods supposed to calculate field offset\nin runtime depending on configuration and packet content:\n\n  - FIELD_MODE_FIXED - fixed offset. The bit offset from\n    header beginning is permanent and defined by field_base\n    configuration parameter.\n\n  - FIELD_MODE_OFFSET - the field bit offset is extracted\n    from other header field (indirect offset field). The\n    resulting field offset to match is calculated from as:\n\n  field_base + (*offset_base & offset_mask) << offset_shift\n\n    This mode is useful to sample some extra options following\n    the main header with field containing main header length.\n    Also, this mode can be used to calculate offset to the\n    next protocol header, for example - IPv4 header contains\n    the 4-bit field with IPv4 header length expressed in dwords.\n    One more example - this mode would allow us to skip GENEVE\n    header variable length options.\n\n  - FIELD_MODE_BITMASK - the field bit offset is extracted\n    from other header field (indirect offset field), the latter\n    is considered as bitmask containing some number of one bits,\n    the resulting field offset to match is calculated as:\n\n  field_base + bitcount(*offset_base & offset_mask) << offset_shift\n\n    This mode would be useful to skip the GTP header and its\n    extra options with specified flags.\n\n  - FIELD_MODE_DUMMY - dummy field, optionally used for byte\n    boundary alignment in pattern. Pattern mask and data are\n    ignored in the match. All configuration parameters besides\n    field size and offset are ignored.\n\n  Note:  \"*\" - means the indirect field offset is calculated\n  and actual data are extracted from the packet by this\n  offset (like data are fetched by pointer *p from memory).\n\nThe offset mode list can be extended by vendors according to\nhardware supported options.\n\nThe input link configuration section tells the driver after\nwhat protocols and at what conditions the flex item can follow.\nInput link specified the preceding header pattern, for example\nfor GENEVE it can be UDP item specifying match on destination\nport with value 6081. The flex item can follow multiple header\ntypes and multiple input links should be specified. At flow\ncreation time the item with one of the input link types should\nprecede the flex item and driver will select the correct flex\nitem settings, depending on the actual flow pattern.\n\nThe output link configuration section tells the driver how\nto continue packet parsing after the flex item protocol.\nIf multiple protocols can follow the flex item header the\nflex item should contain the field with the next protocol\nidentifier and the parsing will be continued depending\non the data contained in this field in the actual packet.\n\nThe flex item fields can participate in RSS hash calculation,\nthe dedicated flag is present in the field description to specify\nwhat fields should be provided for hashing.\n\n5. Flex Item Chaining\n\nIf there are multiple protocols supposed to be supported with\nflex items in chained fashion - two or more flex items within\nthe same flow and these ones might be neighbors in the pattern,\nit means the flex items are mutual referencing.  In this case,\nthe item that occurred first should be created with empty\noutput link list or with the list including existing items,\nand then the second flex item should be created referencing\nthe first flex item as input arc, drivers should adjust\nthe item configuration.\n\nAlso, the hardware resources used by flex items to handle\nthe packet can be limited. If there are multiple flex items\nthat are supposed to be used within the same flow it would\nbe nice to provide some hint for the driver that these two\nor more flex items are intended for simultaneous usage.\nThe fields of items should be assigned with hint indices\nand these indices from two or more flex items supposed\nto be provided within the same flow should be the same\nas well. In other words, the field hint index specifies\nthe group of fields that can be matched simultaneously\nwithin a single flow. If hint indices are specified,\nthe driver will try to engage not overlapping hardware\nresources and provide independent handling of the field\ngroups with unique indices. If the hint index is zero\nthe driver assigns resources on its own.\n\n6. Example of New Protocol Handling\n\nLet's suppose we have the requirements to handle the new tunnel\nprotocol that follows UDP header with destination port 0xFADE\nand is followed by MAC header. Let the new protocol header format\nbe like this:\n\n  struct new_protocol_header {\n    rte_be32 header_length; /* length in dwords, including options */\n    rte_be32 specific0;     /* some protocol data, no intention */\n    rte_be32 specific1;     /* to match in flows on these fields */\n    rte_be32 crucial;       /* data of interest, match is needed */\n    rte_be32 options[0];    /* optional protocol data, variable length */\n  };\n\nThe supposed flex item configuration:\n\n  struct rte_flow_item_flex_field field0 = {\n    .field_mode = FIELD_MODE_DUMMY,  /* Affects match pattern only */\n    .field_size = 96,                /* three dwords from the beginning */\n  };\n  struct rte_flow_item_flex_field field1 = {\n    .field_mode = FIELD_MODE_FIXED,\n    .field_size = 32,       /* Field size is one dword */\n    .field_base = 96,       /* Skip three dwords from the beginning */\n  };\n  struct rte_flow_item_udp spec0 = {\n    .hdr = {\n      .dst_port = RTE_BE16(0xFADE),\n    }\n  };\n  struct rte_flow_item_udp mask0 = {\n    .hdr = {\n      .dst_port = RTE_BE16(0xFFFF),\n    }\n  };\n  struct rte_flow_item_flex_link link0 = {\n    .item = {\n       .type = RTE_FLOW_ITEM_TYPE_UDP,\n       .spec = &spec0,\n       .mask = &mask0,\n  };\n\n  struct rte_flow_item_flex_conf conf = {\n    .next_header = {\n      .tunnel = FLEX_TUNNEL_MODE_SINGLE,\n      .field_mode = FIELD_MODE_OFFSET,\n      .field_base = 0,\n      .offset_base = 0,\n      .offset_mask = 0xFFFFFFFF,\n      .offset_shift = 2\t   /* Expressed in dwords, shift left by 2 */\n    },\n    .sample = {\n       &field0,\n       &field1,\n    },\n    .nb_samples = 2,\n    .input_link[0] = &link0,\n    .nb_inputs = 1\n  };\n\nLet's suppose we have created the flex item successfully, and PMD\nreturned the handle 0x123456789A. We can use the following item\npattern to match the crucial field in the packet with value 0x00112233:\n\n  struct new_protocol_header spec_pattern =\n  {\n    .crucial = RTE_BE32(0x00112233),\n  };\n  struct new_protocol_header mask_pattern =\n  {\n    .crucial = RTE_BE32(0xFFFFFFFF),\n  };\n  struct rte_flow_item_flex spec_flex = {\n    .handle = 0x123456789A\n    .length = sizeiof(struct new_protocol_header),\n    .pattern = &spec_pattern,\n  };\n  struct rte_flow_item_flex mask_flex = {\n    .length = sizeof(struct new_protocol_header),\n    .pattern = &mask_pattern,\n  };\n  struct rte_flow_item item_to_match = {\n    .type = RTE_FLOW_ITEM_TYPE_FLEX,\n    .spec = &spec_flex,\n    .mask = &mask_flex,\n  };\n\nSigned-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>\nAcked-by: Ori Kam <orika@nvidia.com>\n---\n doc/guides/prog_guide/rte_flow.rst     |  25 +++\n doc/guides/rel_notes/release_21_11.rst |   7 +\n lib/ethdev/rte_flow.c                  |  55 ++++++\n lib/ethdev/rte_flow.h                  | 225 +++++++++++++++++++++++++\n lib/ethdev/rte_flow_driver.h           |   8 +\n lib/ethdev/version.map                 |   2 +\n 6 files changed, 322 insertions(+)",
    "diff": "diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst\nindex fa05fe0845..aeba374182 100644\n--- a/doc/guides/prog_guide/rte_flow.rst\n+++ b/doc/guides/prog_guide/rte_flow.rst\n@@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.\n \n See also `Action: REPRESENTED_PORT`_.\n \n+Item: ``FLEX``\n+^^^^^^^^^^^^^^\n+\n+Matches with the custom network protocol header that was created\n+using rte_flow_flex_item_create() API. The application describes\n+the desired header structure, defines the header fields attributes\n+and header relations with preceding and following protocols and\n+configures the ethernet devices accordingly via\n+rte_flow_flex_item_create() routine.\n+\n+- ``handle``: the flex item handle returned by the PMD on successful\n+  rte_flow_flex_item_create() call, mask for this field is ignored.\n+- ``length``: match pattern length in bytes. If the length does not cover\n+  all fields defined in item configuration, the pattern spec and mask are\n+  considered by the driver as padded with trailing zeroes till the full\n+  configured item pattern length.\n+- ``pattern``: pattern to match. The pattern is concatenation of bit fields\n+  configured at item creation. At configuration the fields are presented\n+  by sample_data array. The order of the bitfields is defined by the order\n+  of sample_data elements. The width of each bitfield is defined by the width\n+  specified in the corresponding sample_data element as well. If pattern\n+  length is smaller than configured fields overall length it is considered\n+  as padded with trailing zeroes up to full configured length, both for\n+  value and mask.\n+\n Actions\n ~~~~~~~\n \ndiff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst\nindex 44379da5af..e2b1a5882d 100644\n--- a/doc/guides/rel_notes/release_21_11.rst\n+++ b/doc/guides/rel_notes/release_21_11.rst\n@@ -80,6 +80,13 @@ New Features\n   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and\n   TCP/UDP/SCTP header checksum field can be used as input set for RSS.\n \n+* **Introduced flow flex item.**\n+\n+  * The configurable flow flex item provides the capability to introduce\n+    the arbitrary user specified network protocol header, configure the device\n+    hardware accordingly, and perform match on this header with desired patterns\n+    and masks.\n+\n * **Added ethdev support to control delivery of Rx metadata from the HW to the PMD**\n \n   A new API, ``rte_eth_rx_metadata_negotiate()``, was added.\ndiff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c\nindex c8e12404a7..14294017ed 100644\n--- a/lib/ethdev/rte_flow.c\n+++ b/lib/ethdev/rte_flow.c\n@@ -63,6 +63,19 @@ rte_flow_conv_copy(void *buf, const void *data, const size_t size,\n \treturn sz;\n }\n \n+static size_t\n+rte_flow_item_flex_conv(void *buf, const void *data)\n+{\n+\tstruct rte_flow_item_flex *dst = buf;\n+\tconst struct rte_flow_item_flex *src = data;\n+\tif (buf) {\n+\t\tdst->pattern = rte_memcpy\n+\t\t\t((void *)((uintptr_t)(dst + 1)), src->pattern,\n+\t\t\t src->length);\n+\t}\n+\treturn src->length;\n+}\n+\n /** Generate flow_item[] entry. */\n #define MK_FLOW_ITEM(t, s) \\\n \t[RTE_FLOW_ITEM_TYPE_ ## t] = { \\\n@@ -141,6 +154,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {\n \tMK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),\n \tMK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),\n \tMK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),\n+\tMK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),\n+\t\t\trte_flow_item_flex_conv),\n };\n \n /** Generate flow_action[] entry. */\n@@ -1332,3 +1347,43 @@ rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,\n \t\t\tops->pick_transfer_proxy(dev, proxy_port_id, error),\n \t\t\terror);\n }\n+\n+struct rte_flow_item_flex_handle *\n+rte_flow_flex_item_create(uint16_t port_id,\n+\t\t\t  const struct rte_flow_item_flex_conf *conf,\n+\t\t\t  struct rte_flow_error *error)\n+{\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\tstruct rte_flow_item_flex_handle *handle;\n+\n+\tif (unlikely(!ops))\n+\t\treturn NULL;\n+\tif (unlikely(!ops->flex_item_create)) {\n+\t\trte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t   NULL, rte_strerror(ENOTSUP));\n+\t\treturn NULL;\n+\t}\n+\thandle = ops->flex_item_create(dev, conf, error);\n+\tif (handle == NULL)\n+\t\tflow_err(port_id, -rte_errno, error);\n+\treturn handle;\n+}\n+\n+int\n+rte_flow_flex_item_release(uint16_t port_id,\n+\t\t\t   const struct rte_flow_item_flex_handle *handle,\n+\t\t\t   struct rte_flow_error *error)\n+{\n+\tint ret;\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\n+\tif (unlikely(!ops || !ops->flex_item_release))\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, rte_strerror(ENOTSUP));\n+\tret = ops->flex_item_release(dev, handle, error);\n+\treturn flow_err(port_id, ret, error);\n+}\ndiff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h\nindex d5bfdaaaf2..ba069f2f63 100644\n--- a/lib/ethdev/rte_flow.h\n+++ b/lib/ethdev/rte_flow.h\n@@ -635,6 +635,15 @@ enum rte_flow_item_type {\n \t * @see struct rte_flow_item_ethdev\n \t */\n \tRTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,\n+\n+\t/**\n+\t * Matches a configured set of fields at runtime calculated offsets\n+\t * over the generic network header with variable length and\n+\t * flexible pattern\n+\t *\n+\t * @see struct rte_flow_item_flex.\n+\t */\n+\tRTE_FLOW_ITEM_TYPE_FLEX,\n };\n \n /**\n@@ -1931,6 +1940,177 @@ struct rte_flow_item {\n \tconst void *mask; /**< Bit-mask applied to spec and last. */\n };\n \n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this structure may change without prior notice\n+ *\n+ * RTE_FLOW_ITEM_TYPE_FLEX\n+ *\n+ * Matches a specified set of fields within the network protocol\n+ * header. Each field is presented as set of bits with specified width, and\n+ * bit offset from the header beginning.\n+ *\n+ * The pattern is concatenation of bit fields configured at item creation\n+ * by rte_flow_flex_item_create(). At configuration the fields are presented\n+ * by sample_data array.\n+ *\n+ * This type does not support ranges (struct rte_flow_item.last).\n+ */\n+struct rte_flow_item_flex {\n+\tstruct rte_flow_item_flex_handle *handle; /**< Opaque item handle. */\n+\tuint32_t length; /**< Pattern length in bytes. */\n+\tconst uint8_t *pattern; /**< Combined bitfields pattern to match. */\n+};\n+/**\n+ * Field bit offset calculation mode.\n+ */\n+enum rte_flow_item_flex_field_mode {\n+\t/**\n+\t * Dummy field, used for byte boundary alignment in pattern.\n+\t * Pattern mask and data are ignored in the match. All configuration\n+\t * parameters besides field size are ignored.\n+\t */\n+\tFIELD_MODE_DUMMY = 0,\n+\t/**\n+\t * Fixed offset field. The bit offset from header beginning\n+\t * is permanent and defined by field_base parameter.\n+\t */\n+\tFIELD_MODE_FIXED,\n+\t/**\n+\t * The field bit offset is extracted from other header field (indirect\n+\t * offset field). The resulting field offset to match is calculated as:\n+\t *\n+\t *    field_base + (*offset_base & offset_mask) << offset_shift\n+\t */\n+\tFIELD_MODE_OFFSET,\n+\t/**\n+\t * The field bit offset is extracted from other header field (indirect\n+\t * offset field), the latter is considered as bitmask containing some\n+\t * number of one bits, the resulting field offset to match is\n+\t * calculated as:\n+\t *\n+\t *    field_base + bitcount(*offset_base & offset_mask) << offset_shift\n+\t */\n+\tFIELD_MODE_BITMASK,\n+};\n+\n+/**\n+ * Flex item field tunnel mode\n+ */\n+enum rte_flow_item_flex_tunnel_mode {\n+\t/**\n+\t * The protocol header can be present in the packet only once.\n+\t * No multiple flex item flow inclusions (for inner/outer) are allowed.\n+\t * No any relations with tunnel protocols are imposed. The drivers\n+\t * can optimize hardware resource usage to handle match on single flex\n+\t * item of specific type.\n+\t */\n+\tFLEX_TUNNEL_MODE_SINGLE = 0,\n+\t/**\n+\t * Flex item presents outer header only.\n+\t */\n+\tFLEX_TUNNEL_MODE_OUTER,\n+\t/**\n+\t * Flex item presents inner header only.\n+\t */\n+\tFLEX_TUNNEL_MODE_INNER,\n+\t/**\n+\t * Flex item presents either inner or outer header. The driver\n+\t * handles as many multiple inners as hardware supports.\n+\t */\n+\tFLEX_TUNNEL_MODE_MULTI,\n+\t/**\n+\t * Flex item presents tunnel protocol header.\n+\t */\n+\tFLEX_TUNNEL_MODE_TUNNEL,\n+};\n+\n+/**\n+ *\n+ * @warning\n+ * @b EXPERIMENTAL: this structure may change without prior notice\n+ */\n+__extension__\n+struct rte_flow_item_flex_field {\n+\t/** Defines how match field offset is calculated over the packet. */\n+\tenum rte_flow_item_flex_field_mode field_mode;\n+\tuint32_t field_size; /**< Field size in bits. */\n+\tint32_t field_base; /**< Field offset in bits. */\n+\tuint32_t offset_base; /**< Indirect offset field offset in bits. */\n+\tuint32_t offset_mask; /**< Indirect offset field bit mask. */\n+\tint32_t offset_shift; /**< Indirect offset multiply factor. */\n+\tuint32_t field_id:16; /**< Device hint, for multiple items in flow. */\n+\tuint32_t reserved:16; /**< Reserved field. */\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this structure may change without prior notice\n+ */\n+struct rte_flow_item_flex_link {\n+\t/**\n+\t * Preceding/following header. The item type must be always provided.\n+\t * For preceding one item must specify the header value/mask to match\n+\t * for the link be taken and start the flex item header parsing.\n+\t */\n+\tstruct rte_flow_item item;\n+\t/**\n+\t * Next field value to match to continue with one of the configured\n+\t * next protocols.\n+\t */\n+\tuint32_t next;\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this structure may change without prior notice\n+ */\n+struct rte_flow_item_flex_conf {\n+\t/**\n+\t * Specifies the flex item and tunnel relations and tells the PMD\n+\t * whether flex item can be used for inner, outer or both headers,\n+\t * or whether flex item presents the tunnel protocol itself.\n+\t */\n+\tenum rte_flow_item_flex_tunnel_mode tunnel;\n+\t/**\n+\t * The next header offset, it presents the network header size covered\n+\t * by the flex item and can be obtained with all supported offset\n+\t * calculating methods (fixed, dedicated field, bitmask, etc).\n+\t */\n+\tstruct rte_flow_item_flex_field next_header;\n+\t/**\n+\t * Specifies the next protocol field to match with link next protocol\n+\t * values and continue packet parsing with matching link.\n+\t */\n+\tstruct rte_flow_item_flex_field next_protocol;\n+\t/**\n+\t * The fields will be sampled and presented for explicit match\n+\t * with pattern in the rte_flow_flex_item. There can be multiple\n+\t * fields descriptors, the number should be specified by nb_samples.\n+\t */\n+\tstruct rte_flow_item_flex_field *sample_data;\n+\t/** Number of field descriptors in the sample_data array. */\n+\tuint32_t nb_samples;\n+\t/**\n+\t * Input link defines the flex item relation with preceding\n+\t * header. It specified the preceding item type and provides pattern\n+\t * to match. The flex item will continue parsing and will provide the\n+\t * data to flow match in case if there is the match with one of input\n+\t * links.\n+\t */\n+\tstruct rte_flow_item_flex_link *input_link;\n+\t/** Number of link descriptors in the input link array. */\n+\tuint32_t nb_inputs;\n+\t/**\n+\t * Output link defines the next protocol field value to match and\n+\t * the following protocol header to continue packet parsing. Also\n+\t * defines the tunnel-related behaviour.\n+\t */\n+\tstruct rte_flow_item_flex_link *output_link;\n+\t/** Number of link descriptors in the output link array. */\n+\tuint32_t nb_outputs;\n+};\n+\n /**\n  * Action types.\n  *\n@@ -4477,6 +4657,51 @@ __rte_experimental\n int\n rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,\n \t\t\t     struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Create the flex item with specified configuration over\n+ * the Ethernet device.\n+ *\n+ * @param port_id\n+ *   Port identifier of Ethernet device.\n+ * @param[in] conf\n+ *   Item configuration.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ *\n+ * @return\n+ *   Non-NULL opaque pointer on success, NULL otherwise and rte_errno is set.\n+ */\n+__rte_experimental\n+struct rte_flow_item_flex_handle *\n+rte_flow_flex_item_create(uint16_t port_id,\n+\t\t\t  const struct rte_flow_item_flex_conf *conf,\n+\t\t\t  struct rte_flow_error *error);\n+\n+/**\n+ * Release the flex item on the specified Ethernet device.\n+ *\n+ * @param port_id\n+ *   Port identifier of Ethernet device.\n+ * @param[in] handle\n+ *   Handle of the item existing on the specified device.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   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_flex_item_release(uint16_t port_id,\n+\t\t\t   const struct rte_flow_item_flex_handle *handle,\n+\t\t\t   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 ed52e59a0a..f691b04af4 100644\n--- a/lib/ethdev/rte_flow_driver.h\n+++ b/lib/ethdev/rte_flow_driver.h\n@@ -144,6 +144,14 @@ struct rte_flow_ops {\n \t\t(struct rte_eth_dev *dev,\n \t\t uint16_t *proxy_port_id,\n \t\t struct rte_flow_error *error);\n+\tstruct rte_flow_item_flex_handle *(*flex_item_create)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_item_flex_conf *conf,\n+\t\t struct rte_flow_error *error);\n+\tint (*flex_item_release)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_item_flex_handle *handle,\n+\t\t struct rte_flow_error *error);\n };\n \n /**\ndiff --git a/lib/ethdev/version.map b/lib/ethdev/version.map\nindex 5e6f59c6d3..102353a4cd 100644\n--- a/lib/ethdev/version.map\n+++ b/lib/ethdev/version.map\n@@ -253,6 +253,8 @@ EXPERIMENTAL {\n \trte_eth_macaddrs_get;\n \trte_eth_rx_metadata_negotiate;\n \trte_flow_pick_transfer_proxy;\n+\trte_flow_flex_item_create;\n+\trte_flow_flex_item_release;\n };\n \n INTERNAL {\n",
    "prefixes": [
        "v8",
        "2/4"
    ]
}