From patchwork Tue Oct 12 11:32:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 101202 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 6FC68A0C47; Tue, 12 Oct 2021 13:33:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3C5B541150; Tue, 12 Oct 2021 13:32:58 +0200 (CEST) Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2069.outbound.protection.outlook.com [40.107.92.69]) by mails.dpdk.org (Postfix) with ESMTP id 15B8341147 for ; Tue, 12 Oct 2021 13:32:57 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Q4ikqfebSC9u/K+T/Nyj9V5yTXsOXv5pR32vr+GINWllMleQSws87JX1tsi5SDvwrSj/KItdGW4DE+lxGR/BHnZ9a6CsLSM0dm6hVTXIzSoy6CSKEZrF5+1yOuS+2Kg87+DuZm13BO5atkwlbqaX6hN7dZKc4ADhLlybh8llLWylDj7iZpAhxn83q/jRfs8HuTniN45+39jR/97uA2ZQoHYBaNd4QqgycCreDeLPlAXeRfqtC21Qar6dQ8QXGnxFdUpHjyEy2ILZ4ftpAwCY/1tFOja3xmA1l8p9Uf2L8GruKOnpIEWVkazbWZ3VjToe6yKm4A+FCURUcuLSqKQwEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=O/cV3SRvxCZMA/Y7tOXz3H6KpiHGGN914F6P0rRe8U4=; b=JUwNAhKnmH6CLw+l5gFGXkTtm/tGcTo6pkIVXqdQnYK7tpt5Jgx45oUUSjsxXecQ8qjTrlM8pSJR/bVGqvTg92fWos28VwZN17KxLN5o0gCDw90XBR/LNL7MQ+zssxjA3XbgKmylwVtPu1xTkwi3uplH3g940oZqyGiSdkHFWIh34StG58h2JV0oFothvDgkeXlGTGyS95e42YH24L12jjCqhChi5bAEwQkMqEiqeWVxHdNVAeMl9EMDmpLAmw2WI2ESTBE53hk47kBdrNDI403Z8HVyGQdZEthg8LuLIrZTOkv+Amb6UdkDs4l6eAPR64floRUKtbRKdz5w6TjptQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=O/cV3SRvxCZMA/Y7tOXz3H6KpiHGGN914F6P0rRe8U4=; b=ebrJc+rvijfnLaK407L+F8QJfrxFEvZVIoJYjqzi2+L0/pb4L0M3ZnoAY+ByyDwOQts11fK74IlIFiDto5oKZNDlqzTa/lLRho338zsqqBkrLRuqiov7YBuB6rWJGJU8nR47pezxjPvYARANXffwfpHF9558vjDIk9/AiDgrhBuLCWzkhEhQ2ToTrqh+56uXBHXsznmA/bxn2ojYFo5YW6nMeZhX7EXV/VUKFF2XS6gJefH3/Z4W1rCXvJIdV3qH8pgLl8ddVfUOnaUXrXW+AtfRJaviWmE1f97mgW7AW3CL3NCYgqd6fcUr89/iJbBghkfh6rovgzt1aLoPG2tPuQ== Received: from BN9PR03CA0805.namprd03.prod.outlook.com (2603:10b6:408:13f::30) by BN6PR12MB1620.namprd12.prod.outlook.com (2603:10b6:405:10::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.24; Tue, 12 Oct 2021 11:32:55 +0000 Received: from BN8NAM11FT064.eop-nam11.prod.protection.outlook.com (2603:10b6:408:13f:cafe::b7) by BN9PR03CA0805.outlook.office365.com (2603:10b6:408:13f::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.25 via Frontend Transport; Tue, 12 Oct 2021 11:32:54 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT064.mail.protection.outlook.com (10.13.176.160) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Tue, 12 Oct 2021 11:32:54 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 11:32:51 +0000 From: Viacheslav Ovsiienko To: CC: , , , , , Date: Tue, 12 Oct 2021 14:32:31 +0300 Message-ID: <20211012113235.24975-2-viacheslavo@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20211012113235.24975-1-viacheslavo@nvidia.com> References: <20210922180418.20663-1-viacheslavo@nvidia.com> <20211012113235.24975-1-viacheslavo@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: baf88003-8929-4eca-f3e8-08d98d740864 X-MS-TrafficTypeDiagnostic: BN6PR12MB1620: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: 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: d7HipMi3fDpoeDx2F+4bBb7hJ+ZTOmX+Fz2PltErXqfHf6xjRuph1Tq6WXbhwj/SEgYHY0V3TfEpjcXxe9egp/xQ4A6DL0HYKi0orcNoLIdDjU3gOJyjqGG3fW8rJp7Ntl4REVQyPaAT5DTehLsvOiL4XXc8ld4B9Tx6HwJCCSsrHEn7fA+ou3n95FvoG8hK3t/ZYXY2YNTGx4Aj75yogh6Wd0GbbgRT7DpFuKmvMuCZ48hzrzpC4VD2w1eyplZJM6kYGikn9BGypxo2QSscbXSfUGQUWyTRBhvAjTrtHaC7vjUyZh2F+x2AvJ1rFj4EuH+G/O6z369915PFsul14DWo8QTOSfRdnRscWBY5feXdAM72XDvxaOeKxQeNUhRp3bw8s0hqJMlYzsSgq/GltvzN848ne8nzQgwvxJTvws7li1U2qvuB8y7fMvSM3vca32aXo6bj1DczHcFZoPu1WTe2yTWNskN5D1fA9ltX2vG9AIawDB4Ny97Owj1uQ0fFeiwWzOedcAg7VeV5kw0hP+WzGj0ATUlkqg6WVHscW/Lw/PSTPEf6i5cqy4/uCLYD8AV/BIoIMY7+srUVdmTI2D1tlM4MM+h6oFD+ECVB4UQxB8G2iWAnSqzXyWHxG4mpkw4hHymCDnTH9kBuivwt9RyBm0+7K4s5VbDYEG7BC/edTbjdOB0EiTpojGF3LWMpUV7JuHtoYHqQXcmnfRI2Sg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(36860700001)(36756003)(82310400003)(30864003)(47076005)(8936002)(54906003)(336012)(426003)(2616005)(83380400001)(16526019)(4326008)(8676002)(26005)(7696005)(316002)(86362001)(186003)(55016002)(2906002)(6916009)(508600001)(70586007)(7636003)(5660300002)(70206006)(1076003)(6286002)(6666004)(356005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2021 11:32:54.4363 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: baf88003-8929-4eca-f3e8-08d98d740864 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT064.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR12MB1620 Subject: [dpdk-dev] [PATCH v4 1/5] ethdev: introduce configurable flexible item X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 1. Introduction and Retrospective Nowadays the networks are evolving fast and wide, the network structures are getting more and more complicated, the new application areas are emerging. To address these challenges the new network protocols are continuously being developed, considered by technical communities, adopted by industry and, eventually implemented in hardware and software. The DPDK framework follows the common trends and if we bother to glance at the RTE Flow API header we see the multiple new items were introduced during the last years since the initial release. The new protocol adoption and implementation process is not straightforward and takes time, the new protocol passes development, consideration, adoption, and implementation phases. The industry tries to mitigate and address the forthcoming network protocols, for example, many hardware vendors are implementing flexible and configurable network protocol parsers. As DPDK developers, could we anticipate the near future in the same fashion and introduce the similar flexibility in RTE Flow API? Let's check what we already have merged in our project, and we see the nice raw item (rte_flow_item_raw). At the first glance, it looks superior and we can try to implement a flow matching on the header of some relatively new tunnel protocol, say on the GENEVE header with variable length options. And, under further consideration, we run into the raw item limitations: - only fixed size network header can be represented - the entire network header pattern of fixed format (header field offsets are fixed) must be provided - the search for patterns is not robust (the wrong matches might be triggered), and actually is not supported by existing PMDs - no explicitly specified relations with preceding and following items - no tunnel hint support As the result, implementing the support for tunnel protocols like aforementioned GENEVE with variable extra protocol option with flow raw item becomes very complicated and would require multiple flows and multiple raw items chained in the same flow (by the way, there is no support found for chained raw items in implemented drivers). This RFC introduces the dedicated flex item (rte_flow_item_flex) to handle matches with existing and new network protocol headers in a unified fashion. 2. Flex Item Life Cycle Let's assume there are the requirements to support the new network protocol with RTE Flows. What is given within protocol specification: - header format - header length, (can be variable, depending on options) - potential presence of extra options following or included in the header the header - the relations with preceding protocols. For example, the GENEVE follows UDP, eCPRI can follow either UDP or L2 header - the relations with following protocols. For example, the next layer after tunnel header can be L2 or L3 - whether the new protocol is a tunnel and the header is a splitting point between outer and inner layers The supposed way to operate with flex item: - application defines the header structures according to protocol specification - application calls rte_flow_flex_item_create() with desired configuration according to the protocol specification, it creates the flex item object over specified ethernet device and prepares PMD and underlying hardware to handle flex item. On item creation call PMD backing the specified ethernet device returns the opaque handle identifying the object has been created - application uses the rte_flow_item_flex with obtained handle in the flows, the values/masks to match with fields in the header are specified in the flex item per flow as for regular items (except that pattern buffer combines all fields) - flows with flex items match with packets in a regular fashion, the values and masks for the new protocol header match are taken from the flex items in the flows - application destroys flows with flex items - application calls rte_flow_flex_item_release() as part of ethernet device API and destroys the flex item object in PMD and releases the engaged hardware resources 3. Flex Item Structure The flex item structure is intended to be used as part of the flow pattern like regular RTE flow items and provides the mask and value to match with fields of the protocol item was configured for. struct rte_flow_item_flex { void *handle; uint32_t length; const uint8_t* pattern; }; The handle is some opaque object maintained on per device basis by underlying driver. The protocol header fields are considered as bit fields, all offsets and widths are expressed in bits. The pattern is the buffer containing the bit concatenation of all the fields presented at item configuration time, in the same order and same amount. If byte boundary alignment is needed an application can use a dummy type field, this is just some kind of gap filler. The length field specifies the pattern buffer length in bytes and is needed to allow rte_flow_copy() operations. The approach of multiple pattern pointers and lengths (per field) was considered and found clumsy - it seems to be much suitable for the application to maintain the single structure within the single pattern buffer. 4. Flex Item Configuration The flex item configuration consists of the following parts: - header field descriptors: - next header - next protocol - sample to match - input link descriptors - output link descriptors The field descriptors tell the driver and hardware what data should be extracted from the packet and then control the packet handling in the flow engine. Besides this, sample fields can be presented to match with patterns in the flows. Each field is a bit pattern. It has width, offset from the header beginning, mode of offset calculation, and offset related parameters. The next header field is special, no data are actually taken from the packet, but its offset is used as a pointer to the next header in the packet, in other words the next header offset specifies the size of the header being parsed by flex item. There is one more special field - next protocol, it specifies where the next protocol identifier is contained and packet data sampled from this field will be used to determine the next protocol header type to continue packet parsing. The next protocol field is like eth_type field in MAC2, or proto field in IPv4/v6 headers. The sample fields are used to represent the data be sampled from the packet and then matched with established flows. There are several methods supposed to calculate field offset in runtime depending on configuration and packet content: - FIELD_MODE_FIXED - fixed offset. The bit offset from header beginning is permanent and defined by field_base configuration parameter. - FIELD_MODE_OFFSET - the field bit offset is extracted from other header field (indirect offset field). The resulting field offset to match is calculated from as: field_base + (*offset_base & offset_mask) << offset_shift This mode is useful to sample some extra options following the main header with field containing main header length. Also, this mode can be used to calculate offset to the next protocol header, for example - IPv4 header contains the 4-bit field with IPv4 header length expressed in dwords. One more example - this mode would allow us to skip GENEVE header variable length options. - FIELD_MODE_BITMASK - the field bit offset is extracted from other header field (indirect offset field), the latter is considered as bitmask containing some number of one bits, the resulting field offset to match is calculated as: field_base + bitcount(*offset_base & offset_mask) << offset_shift This mode would be useful to skip the GTP header and its extra options with specified flags. - FIELD_MODE_DUMMY - dummy field, optionally used for byte boundary alignment in pattern. Pattern mask and data are ignored in the match. All configuration parameters besides field size and offset are ignored. Note: "*" - means the indirect field offset is calculated and actual data are extracted from the packet by this offset (like data are fetched by pointer *p from memory). The offset mode list can be extended by vendors according to hardware supported options. The input link configuration section tells the driver after what protocols and at what conditions the flex item can follow. Input link specified the preceding header pattern, for example for GENEVE it can be UDP item specifying match on destination port with value 6081. The flex item can follow multiple header types and multiple input links should be specified. At flow creation time the item with one of the input link types should precede the flex item and driver will select the correct flex item settings, depending on the actual flow pattern. The output link configuration section tells the driver how to continue packet parsing after the flex item protocol. If multiple protocols can follow the flex item header the flex item should contain the field with the next protocol identifier and the parsing will be continued depending on the data contained in this field in the actual packet. The flex item fields can participate in RSS hash calculation, the dedicated flag is present in the field description to specify what fields should be provided for hashing. 5. Flex Item Chaining If there are multiple protocols supposed to be supported with flex items in chained fashion - two or more flex items within the same flow and these ones might be neighbors in the pattern, it means the flex items are mutual referencing. In this case, the item that occurred first should be created with empty output link list or with the list including existing items, and then the second flex item should be created referencing the first flex item as input arc, drivers should adjust the item configuration. Also, the hardware resources used by flex items to handle the packet can be limited. If there are multiple flex items that are supposed to be used within the same flow it would be nice to provide some hint for the driver that these two or more flex items are intended for simultaneous usage. The fields of items should be assigned with hint indices and these indices from two or more flex items supposed to be provided within the same flow should be the same as well. In other words, the field hint index specifies the group of fields that can be matched simultaneously within a single flow. If hint indices are specified, the driver will try to engage not overlapping hardware resources and provide independent handling of the field groups with unique indices. If the hint index is zero the driver assigns resources on its own. 6. Example of New Protocol Handling Let's suppose we have the requirements to handle the new tunnel protocol that follows UDP header with destination port 0xFADE and is followed by MAC header. Let the new protocol header format be like this: struct new_protocol_header { rte_be32 header_length; /* length in dwords, including options */ rte_be32 specific0; /* some protocol data, no intention */ rte_be32 specific1; /* to match in flows on these fields */ rte_be32 crucial; /* data of interest, match is needed */ rte_be32 options[0]; /* optional protocol data, variable length */ }; The supposed flex item configuration: struct rte_flow_item_flex_field field0 = { .field_mode = FIELD_MODE_DUMMY, /* Affects match pattern only */ .field_size = 96, /* three dwords from the beginning */ }; struct rte_flow_item_flex_field field1 = { .field_mode = FIELD_MODE_FIXED, .field_size = 32, /* Field size is one dword */ .field_base = 96, /* Skip three dwords from the beginning */ }; struct rte_flow_item_udp spec0 = { .hdr = { .dst_port = RTE_BE16(0xFADE), } }; struct rte_flow_item_udp mask0 = { .hdr = { .dst_port = RTE_BE16(0xFFFF), } }; struct rte_flow_item_flex_link link0 = { .item = { .type = RTE_FLOW_ITEM_TYPE_UDP, .spec = &spec0, .mask = &mask0, }; struct rte_flow_item_flex_conf conf = { .next_header = { .tunnel = FLEX_TUNNEL_MODE_SINGLE, .field_mode = FIELD_MODE_OFFSET, .field_base = 0, .offset_base = 0, .offset_mask = 0xFFFFFFFF, .offset_shift = 2 /* Expressed in dwords, shift left by 2 */ }, .sample = { &field0, &field1, }, .nb_samples = 2, .input_link[0] = &link0, .nb_inputs = 1 }; Let's suppose we have created the flex item successfully, and PMD returned the handle 0x123456789A. We can use the following item pattern to match the crucial field in the packet with value 0x00112233: struct new_protocol_header spec_pattern = { .crucial = RTE_BE32(0x00112233), }; struct new_protocol_header mask_pattern = { .crucial = RTE_BE32(0xFFFFFFFF), }; struct rte_flow_item_flex spec_flex = { .handle = 0x123456789A .length = sizeiof(struct new_protocol_header), .pattern = &spec_pattern, }; struct rte_flow_item_flex mask_flex = { .length = sizeof(struct new_protocol_header), .pattern = &mask_pattern, }; struct rte_flow_item item_to_match = { .type = RTE_FLOW_ITEM_TYPE_FLEX, .spec = &spec_flex, .mask = &mask_flex, }; Signed-off-by: Viacheslav Ovsiienko Acked-by: Ori Kam --- doc/guides/prog_guide/rte_flow.rst | 25 +++ doc/guides/rel_notes/release_21_11.rst | 7 + lib/ethdev/rte_flow.h | 222 +++++++++++++++++++++++++ 3 files changed, 254 insertions(+) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 2b42d5ec8c..495d08a6a9 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1425,6 +1425,31 @@ Matches a conntrack state after conntrack action. - ``flags``: conntrack packet state flags. - Default ``mask`` matches all state bits. +Item: ``FLEX`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Matches with the custom network protocol header that was created +using rte_flow_flex_item_create() API. The application describes +the desired header structure, defines the header fields attributes +and header relations with preceding and following protocols and +configures the ethernet devices accordingly via +rte_flow_flex_item_create() routine. + +- ``handle``: the flex item handle returned by the PMD on successful + rte_flow_flex_item_create() call, mask for this field is ignored. +- ``length``: match pattern length in bytes. If the length does not cover + all fields defined in item configuration, the pattern spec and mask are + considered by the driver as padded with trailing zeroes till the full + configured item pattern length. +- ``pattern``: pattern to match. The pattern is concatenation of bit fields + configured at item creation. At configuration the fields are presented + by sample_data array. The order of the bitfields is defined by the order + of sample_data elements. The width of each bitfield is defined by the width + specified in the corresponding sample_data element as well. If pattern + length is smaller than configured fields overall length it is considered + as padded with trailing zeroes up to full configured length, both for + value and mask. + Actions ~~~~~~~ diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 73e377a007..4b8cac60d4 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -55,6 +55,13 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Introduced RTE Flow Flex Item.** + + * The configurable RTE Flow Flex Item provides the capability to introduce + the arbitrary user specified network protocol header, configure the device + hardware accordingly, and perform match on this header with desired patterns + and masks. + * **Enabled new devargs parser.** * Enabled devargs syntax diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 7b1ed7f110..fb226d9f52 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -574,6 +574,15 @@ enum rte_flow_item_type { * @see struct rte_flow_item_conntrack. */ RTE_FLOW_ITEM_TYPE_CONNTRACK, + + /** + * Matches a configured set of fields at runtime calculated offsets + * over the generic network header with variable length and + * flexible pattern + * + * @see struct rte_flow_item_flex. + */ + RTE_FLOW_ITEM_TYPE_FLEX, }; /** @@ -1839,6 +1848,177 @@ struct rte_flow_item { const void *mask; /**< Bit-mask applied to spec and last. */ }; +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ITEM_TYPE_FLEX + * + * Matches a specified set of fields within the network protocol + * header. Each field is presented as set of bits with specified width, and + * bit offset from the header beginning. + * + * The pattern is concatenation of bit fields configured at item creation + * by rte_flow_flex_item_create(). At configuration the fields are presented + * by sample_data array. + * + * This type does not support ranges (struct rte_flow_item.last). + */ +struct rte_flow_item_flex { + struct rte_flow_item_flex_handle *handle; /**< Opaque item handle. */ + uint32_t length; /**< Pattern length in bytes. */ + const uint8_t *pattern; /**< Combined bitfields pattern to match. */ +}; +/** + * Field bit offset calculation mode. + */ +enum rte_flow_item_flex_field_mode { + /** + * Dummy field, used for byte boundary alignment in pattern. + * Pattern mask and data are ignored in the match. All configuration + * parameters besides field size are ignored. + */ + FIELD_MODE_DUMMY = 0, + /** + * Fixed offset field. The bit offset from header beginning + * is permanent and defined by field_base parameter. + */ + FIELD_MODE_FIXED, + /** + * The field bit offset is extracted from other header field (indirect + * offset field). The resulting field offset to match is calculated as: + * + * field_base + (*offset_base & offset_mask) << offset_shift + */ + FIELD_MODE_OFFSET, + /** + * The field bit offset is extracted from other header field (indirect + * offset field), the latter is considered as bitmask containing some + * number of one bits, the resulting field offset to match is + * calculated as: + * + * field_base + bitcount(*offset_base & offset_mask) << offset_shift + */ + FIELD_MODE_BITMASK, +}; + +/** + * Flex item field tunnel mode + */ +enum rte_flow_item_flex_tunnel_mode { + /** + * The protocol header can be present in the packet only once. + * No multiple flex item flow inclusions (for inner/outer) are allowed. + * No any relations with tunnel protocols are imposed. The drivers + * can optimize hardware resource usage to handle match on single flex + * item of specific type. + */ + FLEX_TUNNEL_MODE_SINGLE = 0, + /** + * Flex item presents outer header only. + */ + FLEX_TUNNEL_MODE_OUTER, + /** + * Flex item presents inner header only. + */ + FLEX_TUNNEL_MODE_INNER, + /** + * Flex item presents either inner or outer header. The driver + * handles as many multiple inners as hardware supports. + */ + FLEX_TUNNEL_MODE_MULTI, + /** + * Flex item presents tunnel protocol header. + */ + FLEX_TUNNEL_MODE_TUNNEL, +}; + +/** + * + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + */ +__extension__ +struct rte_flow_item_flex_field { + /** Defines how match field offset is calculated over the packet. */ + enum rte_flow_item_flex_field_mode field_mode; + uint32_t field_size; /**< Field size in bits. */ + int32_t field_base; /**< Field offset in bits. */ + uint32_t offset_base; /**< Indirect offset field offset in bits. */ + uint32_t offset_mask; /**< Indirect offset field bit mask. */ + int32_t offset_shift; /**< Indirect offset multiply factor. */ + uint32_t field_id:16; /**< Device hint, for multiple items in flow. */ + uint32_t reserved:16; /**< Reserved field. */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + */ +struct rte_flow_item_flex_link { + /** + * Preceding/following header. The item type must be always provided. + * For preceding one item must specify the header value/mask to match + * for the link be taken and start the flex item header parsing. + */ + struct rte_flow_item item; + /** + * Next field value to match to continue with one of the configured + * next protocols. + */ + uint32_t next; +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + */ +struct rte_flow_item_flex_conf { + /** + * Specifies the flex item and tunnel relations and tells the PMD + * whether flex item can be used for inner, outer or both headers, + * or whether flex item presents the tunnel protocol itself. + */ + enum rte_flow_item_flex_tunnel_mode tunnel; + /** + * The next header offset, it presents the network header size covered + * by the flex item and can be obtained with all supported offset + * calculating methods (fixed, dedicated field, bitmask, etc). + */ + struct rte_flow_item_flex_field next_header; + /** + * Specifies the next protocol field to match with link next protocol + * values and continue packet parsing with matching link. + */ + struct rte_flow_item_flex_field next_protocol; + /** + * The fields will be sampled and presented for explicit match + * with pattern in the rte_flow_flex_item. There can be multiple + * fields descriptors, the number should be specified by nb_samples. + */ + struct rte_flow_item_flex_field *sample_data; + /** Number of field descriptors in the sample_data array. */ + uint32_t nb_samples; + /** + * Input link defines the flex item relation with preceding + * header. It specified the preceding item type and provides pattern + * to match. The flex item will continue parsing and will provide the + * data to flow match in case if there is the match with one of input + * links. + */ + struct rte_flow_item_flex_link *input_link; + /** Number of link descriptors in the input link array. */ + uint32_t nb_inputs; + /** + * Output link defines the next protocol field value to match and + * the following protocol header to continue packet parsing. Also + * defines the tunnel-related behaviour. + */ + struct rte_flow_item_flex_link *output_link; + /** Number of link descriptors in the output link array. */ + uint32_t nb_outputs; +}; + /** * Action types. * @@ -4288,6 +4468,48 @@ rte_flow_tunnel_item_release(uint16_t port_id, struct rte_flow_item *items, uint32_t num_of_items, struct rte_flow_error *error); + +/** + * Create the flex item with specified configuration over + * the Ethernet device. + * + * @param port_id + * Port identifier of Ethernet device. + * @param[in] conf + * Item configuration. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * Non-NULL opaque pointer on success, NULL otherwise and rte_errno is set. + */ +__rte_experimental +struct rte_flow_item_flex_handle * +rte_flow_flex_item_create(uint16_t port_id, + const struct rte_flow_item_flex_conf *conf, + struct rte_flow_error *error); + +/** + * Release the flex item on the specified Ethernet device. + * + * @param port_id + * Port identifier of Ethernet device. + * @param[in] handle + * Handle of the item existing on the specified device. + * @param[out] error + * Perform verbose error reporting if not NULL. PMDs initialize this + * structure in case of error only. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +__rte_experimental +int +rte_flow_flex_item_release(uint16_t port_id, + const struct rte_flow_item_flex_handle *handle, + struct rte_flow_error *error); + #ifdef __cplusplus } #endif From patchwork Tue Oct 12 11:32:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 101203 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 3EC6AA0C47; Tue, 12 Oct 2021 13:33:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8C48641161; Tue, 12 Oct 2021 13:33:00 +0200 (CEST) Received: from NAM02-DM3-obe.outbound.protection.outlook.com (mail-dm3nam07on2062.outbound.protection.outlook.com [40.107.95.62]) by mails.dpdk.org (Postfix) with ESMTP id 352864115D for ; Tue, 12 Oct 2021 13:32:59 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=X8GxTzYUvgh4zI3JvbnBjocf9eY3qBJhqTRoTGhgtchXY4HSwUSAiotXkMvUsp37gwD2WfV1iLIyvwVu7Ob8k2DJLkb3soDrx3pdsjRei1Wj9ritSkXjNSt8pJJErc5JYGY4nL/7L/Ia6SJIibImNDn7YHRCB/Cy95eQFuoXAfDwM7sUxEDi6WwyNWbMv+/2kMtLTc8dZzGKprB6wgrbMW2FpdxhN4Eg2OePtxMYNQPFZXbXujkLFqC71DAofk2443/SaCB4yeW1Fugv+RQTVwGdXpz2DWNaNef5bNywdc98RBJPn3peIFJ3OVBWmukLPcwJ9wWu3dRuSY2duW+uvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5M/NBeLmm7ln36O8i6I3rmQyC6ip2HifE3x0+WFKDFk=; b=j0aCTJLsvNtP1ZcNuD9ETYSUJZHYQZtaDJXf+siGXprqLPaV+IYPq0x1/0CTVWdIXilzU/tSgXPH3P7EzP7m2mKLyq64H1DVU1yju/smIR8L9U9Qi9OIRA43m77ZGGGFvC5Yt3jXCnGdbUAfOQ7/r/MPa5iSky6PPRy4RD9OLpF75Qb1i7UbrVA8GRYtxEbI66RAvr32YbzZdsGEYR4aaiRxUTFLOiTfZ8F0vUhxcX1lMWO3zDx4nbMvOs/MluMinZFmajoMAWtltnoN6EDn9QHIlwp1MKsacGAjjtFwYBMU0ohuT3FLAAZHI774sdcSpHhmgyczAgBc9yIFGSoDzA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5M/NBeLmm7ln36O8i6I3rmQyC6ip2HifE3x0+WFKDFk=; b=YWApDglbkqftqJr8GT/alm3xWi5Xt/D3++nxwp1oTLknU9kh4rh0GcZuuyxn2mgU9BN7oQNsHBdL4r9rSd5lEkvm4NASnZcELFRfUpD86At/my9DsAMb4m8BM0dRxEfhN7crFlBrqLBuYG0cLOf5aREcMDF1Gwu5naR4k7oMtNxAe5AnECMJrzER7tux8XaS4qG1K8JYNJFfuH7nnZ81VhbrRrg7a3gIfgxLqdkDc8KX8QJ6+SlGkp3YiAzrEw21vgZiDEKgdBwbOTWoQPqoAvgwDDLRCrkovqrHs4d1jX6U4owor3bXwjmBvbujp/hqfVcKOitTkgi4/JYtVN4GVQ== Received: from BN6PR22CA0051.namprd22.prod.outlook.com (2603:10b6:404:ca::13) by SJ0PR12MB5408.namprd12.prod.outlook.com (2603:10b6:a03:305::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Tue, 12 Oct 2021 11:32:57 +0000 Received: from BN8NAM11FT022.eop-nam11.prod.protection.outlook.com (2603:10b6:404:ca:cafe::db) by BN6PR22CA0051.outlook.office365.com (2603:10b6:404:ca::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.14 via Frontend Transport; Tue, 12 Oct 2021 11:32:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT022.mail.protection.outlook.com (10.13.176.112) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Tue, 12 Oct 2021 11:32:56 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 11:32:53 +0000 From: Viacheslav Ovsiienko To: CC: , , , , , Date: Tue, 12 Oct 2021 14:32:32 +0300 Message-ID: <20211012113235.24975-3-viacheslavo@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20211012113235.24975-1-viacheslavo@nvidia.com> References: <20210922180418.20663-1-viacheslavo@nvidia.com> <20211012113235.24975-1-viacheslavo@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 248d4113-aa64-499c-ebb2-08d98d7409bf X-MS-TrafficTypeDiagnostic: SJ0PR12MB5408: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:923; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: p143M6/ZKzhkWLWmpd5hjomDJ+bOOnCV+/ZeFv3TAd4dydf/2iIxgNpq6chDA33l7rwhMn/PXtRsT01Waya43w1lXjAfNBGXES0HhSlAUima1PT0IHgo6X78GLlqKoFMbGtTJzjRoFFs/IYnpbWZ9nxBAuERuCZXm55BBdTuOGGYQa42JgCiGqSMG9oVOnK/V9iQjiTIJSUM155snc1Vy/vrMCXHyslppHIGiuEgoSphEgMqJOAxdaXdVdTjT9xD8wqufH+Ix4MHNIkPPBycjbXOxF40939zmo5nPmabiBAKbB0sk1JxTQg+smIaQ+8TVc/YBCOLob7NlLnIciAJOYF67ppO+x4AMekIl32VmrAGQ4ayl5+5OraFfX7y+uBNr3F/u4xseyM7jMpACwYpV0tFbQtbOGQ9oJeIpNoZ4vnH3vJDJuIWkdfLOHm6H7GfkKlSbfnGPTeMe3/6lcJaM+dcwTAxBRQfbbFaHk0qF6ZoCWhkGcaKs1hecde2/bqhP02utKzQKeek6xSblKcH208eAKklBhRJS1ZOMyusvVEmAZttbOuxj+q9dI6L18Zy8d7nmDwn+Q31VoU/0mtDO3t8QQgY+UE54xjNyhzf27B5uZrEv782asS/hJbyQEFiLdiqbrxNs7BaHfAsTX3sCP1h2vfu3MLgj8WVuxo0c7Kg1kkmwZAatxKDZhyp2kggz3rE+Mla2466hDnPnts8MA== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(426003)(86362001)(1076003)(6666004)(7696005)(6286002)(2616005)(5660300002)(316002)(83380400001)(8936002)(70586007)(26005)(36860700001)(70206006)(54906003)(2906002)(55016002)(186003)(8676002)(336012)(82310400003)(508600001)(4326008)(16526019)(47076005)(36756003)(6916009)(7636003)(356005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2021 11:32:56.7122 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 248d4113-aa64-499c-ebb2-08d98d7409bf X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT022.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR12MB5408 Subject: [dpdk-dev] [PATCH v4 2/5] ethdev: support flow elements with variable length X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gregory Etelson RTE flow API provides RAW item type for packet patterns of variable length. The RAW item structure has fixed size members that describe the variable pattern length and methods to process it. There is the new RTE Flow items with variable lengths coming - flex item). In order to handle this item (and potentially other new ones with variable pattern length) in RTE flow copy and conversion routines the helper function is introduced. Signed-off-by: Gregory Etelson Reviewed-by: Viacheslav Ovsiienko --- lib/ethdev/rte_flow.c | 83 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 8cb7a069c8..100983ca59 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -30,13 +30,67 @@ uint64_t rte_flow_dynf_metadata_mask; struct rte_flow_desc_data { const char *name; size_t size; + size_t (*desc_fn)(void *dst, const void *src); }; +/** + * + * @param buf + * Destination memory. + * @param data + * Source memory + * @param size + * Requested copy size + * @param desc + * rte_flow_desc_item - for flow item conversion. + * rte_flow_desc_action - for flow action conversion. + * @param type + * Offset into the desc param or negative value for private flow elements. + */ +static inline size_t +rte_flow_conv_copy(void *buf, const void *data, const size_t size, + const struct rte_flow_desc_data *desc, int type) +{ + /** + * allow PMD private flow item + * see 5d1bff8fe2 + * "ethdev: allow negative values in flow rule types" + */ + size_t sz = type >= 0 ? desc[type].size : sizeof(void *); + if (buf == NULL || data == NULL) + return 0; + rte_memcpy(buf, data, (size > sz ? sz : size)); + if (desc[type].desc_fn) + sz += desc[type].desc_fn(size > 0 ? buf : NULL, data); + return sz; +} + +static size_t +rte_flow_item_flex_conv(void *buf, const void *data) +{ + struct rte_flow_item_flex *dst = buf; + const struct rte_flow_item_flex *src = data; + if (buf) { + dst->pattern = rte_memcpy + ((void *)((uintptr_t)(dst + 1)), src->pattern, + src->length); + } + return src->length; +} + /** Generate flow_item[] entry. */ #define MK_FLOW_ITEM(t, s) \ [RTE_FLOW_ITEM_TYPE_ ## t] = { \ .name = # t, \ - .size = s, \ + .size = s, \ + .desc_fn = NULL,\ + } + +#define MK_FLOW_ITEM_FN(t, s, fn) \ + [RTE_FLOW_ITEM_TYPE_ ## t] = {\ + .name = # t, \ + .size = s, \ + .desc_fn = fn, \ } /** Information about known flow pattern items. */ @@ -100,6 +154,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)), MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)), MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)), + MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex), + rte_flow_item_flex_conv), }; /** Generate flow_action[] entry. */ @@ -107,8 +163,17 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { [RTE_FLOW_ACTION_TYPE_ ## t] = { \ .name = # t, \ .size = s, \ + .desc_fn = NULL,\ + } + +#define MK_FLOW_ACTION_FN(t, fn) \ + [RTE_FLOW_ACTION_TYPE_ ## t] = { \ + .name = # t, \ + .size = 0, \ + .desc_fn = fn,\ } + /** Information about known flow actions. */ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(END, 0), @@ -527,12 +592,8 @@ rte_flow_conv_item_spec(void *buf, const size_t size, } break; default: - /** - * allow PMD private flow item - */ - off = (int)item->type >= 0 ? - rte_flow_desc_item[item->type].size : sizeof(void *); - rte_memcpy(buf, data, (size > off ? off : size)); + off = rte_flow_conv_copy(buf, data, size, + rte_flow_desc_item, item->type); break; } return off; @@ -634,12 +695,8 @@ rte_flow_conv_action_conf(void *buf, const size_t size, } break; default: - /** - * allow PMD private flow action - */ - off = (int)action->type >= 0 ? - rte_flow_desc_action[action->type].size : sizeof(void *); - rte_memcpy(buf, action->conf, (size > off ? off : size)); + off = rte_flow_conv_copy(buf, action->conf, size, + rte_flow_desc_action, action->type); break; } return off; From patchwork Tue Oct 12 11:32:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 101204 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 845B3A0C47; Tue, 12 Oct 2021 13:33:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 97FF541162; Tue, 12 Oct 2021 13:33:03 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2051.outbound.protection.outlook.com [40.107.223.51]) by mails.dpdk.org (Postfix) with ESMTP id BB6304116C for ; Tue, 12 Oct 2021 13:33:01 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M2trZkCjNvyG/DZt9641XCXxKnqTQ5g4Vz61RqaIFBEp0YkPRdTm0iZWMv02DL2C8KBUufXV2SfDpVdRHXJ5O9uyx42WMVtbPi/Cco+ewu/o2MeGcFN0MdC0DPyMIcfcVs6Ge27N4Z1kXJROh0XhiLNG3iGB6KZ+7Vo5nlNLmUrhaGRTDy4gllnenF0UHNa1Lq2Nne5nMupqg7AdZX8sfefDuQ9q8Eeor+w6OuzbzjVN1D6qJYEL/61KgjEYIdt4peW5UD5db6KvEe6MYiWGpF+oMjqM23q287kPPgvX+T23K0o0y72mBUO8W5GUqvia/jrxdmHYp98fiAomfYRHnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=FSUq5XLPKW1Z1TrcklGTiZjgsBVA/amVA3yqHYcXEDs=; b=Z+B6BUVbq5kvD+8Dwy8Z/j7C27EKirN3SwsxrONA+bfKZQFTjBagt8Pzt1Bw5yFug4LY0dsNbFxyl5AMTAv8iK1WpYYlwTMnTf0e+FXJN7pE0VUAyidhJkUhtPQ0Vm7M/0w4G5l0mbqVTqlgF3VcAcgGnw8wl5UL4rUlALMUpBdto3BxLTqT5BIoNr/g/f223/gIqkBLoJGVtDLpvtIHWhPSzLRkfpaX7AadvcVJmDRBr/kLoGqTcYKtlccR8P4BiIB+pUVJblbEZqqyXH/IPzQTq428+yPQFAs0/C7G2TF01QMgZ/FUQH4+KybAUv0UZZig0V7LXKQVzKWk+v6B2A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FSUq5XLPKW1Z1TrcklGTiZjgsBVA/amVA3yqHYcXEDs=; b=HBf2GQWYLw/xn3gu0jlwdi5tInII+KfGnoxqFrQDUYG0fnZLHLLZDEDuCtgaQcXEzdVWhAh5sEslmvo2di9MgM1WJx28A8xQTfSvGtfl+fuY9llMsMWkJCMu//sgA9C4+GUZBzmPTptbOnPmmeubKG7pInLtZps9bmg03zLXOr/OKNvDYz5uFL+gbgvoE2jMyXfJBIGV0YMZ1BOsPU71JPNbnEPUUx+PkXvIGFtdbV5Qe9Nlt87z/DxLtutws1QmpbUycmxvOhfNoVikjQ0nv72Z941n5UXGe54ALhBAHBi8TjNFc65gQSSrpkswK0/tRcAbN3ZnGwcoWgCr55iLdQ== Received: from BN6PR22CA0062.namprd22.prod.outlook.com (2603:10b6:404:ca::24) by MWHPR12MB1215.namprd12.prod.outlook.com (2603:10b6:300:d::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18; Tue, 12 Oct 2021 11:32:58 +0000 Received: from BN8NAM11FT022.eop-nam11.prod.protection.outlook.com (2603:10b6:404:ca:cafe::af) by BN6PR22CA0062.outlook.office365.com (2603:10b6:404:ca::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.24 via Frontend Transport; Tue, 12 Oct 2021 11:32:58 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT022.mail.protection.outlook.com (10.13.176.112) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Tue, 12 Oct 2021 11:32:58 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 11:32:55 +0000 From: Viacheslav Ovsiienko To: CC: , , , , , Date: Tue, 12 Oct 2021 14:32:33 +0300 Message-ID: <20211012113235.24975-4-viacheslavo@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20211012113235.24975-1-viacheslavo@nvidia.com> References: <20210922180418.20663-1-viacheslavo@nvidia.com> <20211012113235.24975-1-viacheslavo@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 77173a2f-bf3c-421b-33b7-08d98d740a94 X-MS-TrafficTypeDiagnostic: MWHPR12MB1215: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 8/BQxDD66VVH22dZL8st9xfGShPczajhzEf+ScMlrJBYxV+sWWXdZHNpBtG0/vQUN4TO8UErorolvgCNMozb16lfA48SPPoxAwZ+KXlBFiKOz6wZjxB5W8KHbLY7vkUH6kWSgfCwu37qtjOuesU6hiA63b9Pz8MbZJoi7QAsmxFMXw3rvdF8Kx+qQoPXf5cQAIvTjAN7EFhA/RY58iD/wjdTCVQKWTDf3nmKvOFg5TRj0RyNYDZ18QYwV2BtD9mDPSOn9ShREjwmPaoe9C0ocliethFBT8PkgjL3Pg0K/wY8o62ngpPzXXz4Vc0WYVDjYBrmpWyT1uFuE+DW6x7ZEyggwu9f2vvKtHylnq7G3+xEYiDmAFZco/NFUPvkLybuZYWtCtgGpUU8g4KfyfKPPRh2yJcBb/Mr7vRXxoeatCg/Py09oxNrh6appIg/NmjieiUwLl5nEZ5gByQv+uiJMhIBzVGqNVfhsx0bp+AS+VcdcQLKAZGMNS9XggFxihqm5OlAxiq37u9jff1fImI+Ar2Uog5ICLyN5Dz2lqC2VMdDXz1Jkg+SXQ3GCBKqDqmdIXUTG0hWXjrhRWbuvJEdHUSIJrzceugLytySkWTOWaQ6pvz73BTTbIop4wpiVOT35koyo/KwgtS4NoM3cbTgz6jIEzwAEGriDzVPXnKDwr+tv9xtuYgRhgY0ERuFfLWiBe2EZcYFQhrk2H5pM0tFiA== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(7636003)(70586007)(5660300002)(47076005)(86362001)(4326008)(54906003)(2616005)(7696005)(336012)(426003)(356005)(316002)(70206006)(1076003)(36756003)(508600001)(6916009)(2906002)(26005)(55016002)(6666004)(82310400003)(6286002)(8676002)(16526019)(186003)(36860700001)(8936002)(83380400001); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2021 11:32:58.0864 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 77173a2f-bf3c-421b-33b7-08d98d740a94 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT022.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1215 Subject: [dpdk-dev] [PATCH v4 3/5] ethdev: implement RTE flex item API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gregory Etelson RTE flex item API was introduced in "ethdev: introduce configurable flexible item" patch. The API allows DPDK application to define parser for custom network header in port hardware and offload flows that will match the custom header elements. Signed-off-by: Gregory Etelson Reviewed-by: Viacheslav Ovsiienko --- lib/ethdev/rte_flow.c | 40 ++++++++++++++++++++++++++++++++++++ lib/ethdev/rte_flow_driver.h | 8 ++++++++ lib/ethdev/version.map | 4 ++++ 3 files changed, 52 insertions(+) diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 100983ca59..a858dc31e3 100644 --- a/lib/ethdev/rte_flow.c +++ b/lib/ethdev/rte_flow.c @@ -1323,3 +1323,43 @@ rte_flow_tunnel_item_release(uint16_t port_id, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, rte_strerror(ENOTSUP)); } + +struct rte_flow_item_flex_handle * +rte_flow_flex_item_create(uint16_t port_id, + const struct rte_flow_item_flex_conf *conf, + struct rte_flow_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + struct rte_flow_item_flex_handle *handle; + + if (unlikely(!ops)) + return NULL; + if (unlikely(!ops->flex_item_create)) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); + return NULL; + } + handle = ops->flex_item_create(dev, conf, error); + if (handle == NULL) + flow_err(port_id, -rte_errno, error); + return handle; +} + +int +rte_flow_flex_item_release(uint16_t port_id, + const struct rte_flow_item_flex_handle *handle, + struct rte_flow_error *error) +{ + int ret; + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); + + if (unlikely(!ops || !ops->flex_item_release)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOTSUP)); + ret = ops->flex_item_release(dev, handle, error); + return flow_err(port_id, ret, error); +} diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h index 46f62c2ec2..34a5a5bcd0 100644 --- a/lib/ethdev/rte_flow_driver.h +++ b/lib/ethdev/rte_flow_driver.h @@ -139,6 +139,14 @@ struct rte_flow_ops { struct rte_flow_item *pmd_items, uint32_t num_of_items, struct rte_flow_error *err); + struct rte_flow_item_flex_handle *(*flex_item_create) + (struct rte_eth_dev *dev, + const struct rte_flow_item_flex_conf *conf, + struct rte_flow_error *error); + int (*flex_item_release) + (struct rte_eth_dev *dev, + const struct rte_flow_item_flex_handle *handle, + struct rte_flow_error *error); }; /** diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index 904bce6ea1..ec3b66d7a1 100644 --- a/lib/ethdev/version.map +++ b/lib/ethdev/version.map @@ -247,6 +247,10 @@ EXPERIMENTAL { rte_mtr_meter_policy_delete; rte_mtr_meter_policy_update; rte_mtr_meter_policy_validate; + + # added in 21.11 + rte_flow_flex_item_create; + rte_flow_flex_item_release; }; INTERNAL { From patchwork Tue Oct 12 11:32:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 101205 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id EEB26A0C47; Tue, 12 Oct 2021 13:33:22 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AE77941172; Tue, 12 Oct 2021 13:33:04 +0200 (CEST) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2042.outbound.protection.outlook.com [40.107.236.42]) by mails.dpdk.org (Postfix) with ESMTP id 7F41441136 for ; Tue, 12 Oct 2021 13:33:02 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dUOHGaagpbJrFl98eEqylWRagk6pWooArk2ZVYTgnSGiHWsj3pMu+dgnTGZAFuzbI0puHPatGBuO55dl0x7Yp0AGn+OTKy8PmdM8y1A5o2lFSB39fgTvShhIVYlkFFwZmqX3kpfzGIK+MXrCuIDBiVJHUVFBArYCaEOSctyzE3izKyHmydk8hhAp3loZRk5gm0InWh5bV5OAq+Uh6lOSVW4y9LcaxFmn4elIZBHGLdFlOmZl9qAHz8pOQFMcMQsfo5WX/4r6Fn8JR6Y0C005IKwi/yaD3ZAWn5TTIjcMFupACuIXr9MZzBn4SKbg5fOxTk4oyOSQ3aHzq8PsLYUceg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Th6mRJECj2+LDCnZoirMbbHqgUs+5Nu32Kg2+jF4tSE=; b=NlQOgFpJz/xDpe5Lsv34xDc0GVU5UT5uI6iGd0H/3GooBhBL/1zCF+rhU/1ewVfBuzlFgEtvrdFWhPaGb3nBqyL8UTRWSAhKqP7W/DQs2d6832hm+bFaIHwZFlwKGcqzhWf00tLEmqqO4VUXIqq8hBT4WkLmL4BAc9YV6n0tQ2w+TQIu91Ts2SIinmA+TxvAQKqX8A3DUmtgVz/bYMJhyiir0OBPcy96n6wL+phuf23/camPa60ngFThGCM6sLcEPRkzis/RyI68ApHG8Eu/xS8li3j4dRHc0j7nECiruwfkbB14H0oHHQGEml3d2SHm3zlFv3OL1qT3wu+veA2/Ag== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Th6mRJECj2+LDCnZoirMbbHqgUs+5Nu32Kg2+jF4tSE=; b=dywS7UZrCgqa1BnbuGw9JdKUZ2CcJ665mkHiH4dK0VPOIby8O0S1de5cP6I9IhEETPvfmfs91hPf8EALMuwWmiNGiNsVIMY4kFQV+1Vai2qGMlONb6+lYg806jI68ddHhJa9dRgWHp2FGl5yPAXwos5iJ+JVWe/i1qfZSobUp65PizQAFxm18kUMac1MZiwyoNgL32/ihgxfjSi0zOnxcdrawGcEKI+v0vdWhWEHZy/DhFwfpxLYMSn14aLT5S7ZVtifaPe2JIlDEMRzdwKATW6s9UAIUMs1qStv9bcc9/Gb6zkU/0UznzRgvYaU5IOgOqhMc74q/5P1M2eoHC7aOg== Received: from BN0PR02CA0055.namprd02.prod.outlook.com (2603:10b6:408:e5::30) by DM6PR12MB4092.namprd12.prod.outlook.com (2603:10b6:5:214::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.18; Tue, 12 Oct 2021 11:33:01 +0000 Received: from BN8NAM11FT025.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e5:cafe::a5) by BN0PR02CA0055.outlook.office365.com (2603:10b6:408:e5::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.24 via Frontend Transport; Tue, 12 Oct 2021 11:33:01 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT025.mail.protection.outlook.com (10.13.177.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Tue, 12 Oct 2021 11:33:00 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 11:32:58 +0000 From: Viacheslav Ovsiienko To: CC: , , , , , Date: Tue, 12 Oct 2021 14:32:34 +0300 Message-ID: <20211012113235.24975-5-viacheslavo@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20211012113235.24975-1-viacheslavo@nvidia.com> References: <20210922180418.20663-1-viacheslavo@nvidia.com> <20211012113235.24975-1-viacheslavo@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2c462b95-d945-4178-8b2f-08d98d740c2c X-MS-TrafficTypeDiagnostic: DM6PR12MB4092: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:4502; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: SarFVYP5DCT0YwqPC+ekHQPXdflv91JJ968Z0+flspC8zeHZeyFqezAkvrW8r4mrX7/twt4PxAzUWspSh+bK3j7xOrT4o7g0aGlhSqm7t09QqTWG7dCj8fod6sLWtJntQH76p19h5yHUYTBPK1H8DyJxKMxGINJPSVuvE/V3/36rlB6G+6c2NYke3fWpO6RnNCYTrzC/Eo8roUnY6imOeGQE5RNQYFgMOOZOtf9KSbWIRR6pZHYSWAo1n6PherrGvjnM46zv9fU670aTbRmxjzRSfRTi5JDRppW2uIlFiAwiOVxIQ/RQ+QTTZYR4VHPxaLf2ghin5NN3Wc3yCviCueZSJE/xG+HdbKZhDDJgiiAYZLcnrb8ZkYyapnXEO/VmmAMiWqVCiClnQAhjCwsLgN7GBnCuEXG8agnum04DBDL50LEPAJSm6tPMNR65eqIrO2Qgn/nbmTkEs34qcmiyCOg0topmb3hsJCCTbmnK5GoZFxGDdVmyHO+vxhfLCcBlmIO2Y6uEZ9hNe5uBEU/C/7N0D4vOeTrha2nECG4fyNz/Q9rzzL0xM7/tukcGYleb1w3qVcoF235o4tQEIFy0tL5lYMmBV18tGZDLb8tImgZ1g4GVQqUA0QbOGlGcsPBj+bYC96KlSBrPd+MrUIzNrxU5CjPmJKow/i0o5eurE7LcrwiCchk+Q2k/jS6d+F2DxBIMJV5QL03yMYwOub5twA== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(70586007)(36860700001)(6666004)(8936002)(7696005)(6286002)(186003)(16526019)(26005)(8676002)(1076003)(36756003)(86362001)(2906002)(54906003)(70206006)(6916009)(55016002)(7636003)(5660300002)(356005)(508600001)(4326008)(2616005)(336012)(316002)(426003)(82310400003)(47076005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2021 11:33:00.7995 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2c462b95-d945-4178-8b2f-08d98d740c2c X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT025.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4092 Subject: [dpdk-dev] [PATCH v4 4/5] app/testpmd: add jansson library X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gregory Etelson Testpmd interactive mode provides CLI to configure application commands. Testpmd reads CLI command and parameters from STDIN, and converts input into C objects with internal parser. The patch adds jansson dependency to testpmd. With jansson, testpmd can read input in JSON format from STDIN or input file and convert it into C object using jansson library calls. Signed-off-by: Gregory Etelson Reviewed-by: Viacheslav Ovsiienko --- app/test-pmd/meson.build | 5 +++++ app/test-pmd/testpmd.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index 98f3289bdf..3a8babd604 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -61,3 +61,8 @@ if dpdk_conf.has('RTE_LIB_BPF') sources += files('bpf_cmd.c') deps += 'bpf' endif +jansson_dep = dependency('jansson', required: false, method: 'pkg-config') +if jansson_dep.found() + dpdk_conf.set('RTE_HAS_JANSSON', 1) + ext_deps += jansson_dep +endif diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 5863b2f43f..876a341cf0 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -14,6 +14,9 @@ #include #include #include +#ifdef RTE_HAS_JANSSON +#include +#endif #define RTE_PORT_ALL (~(portid_t)0x0) From patchwork Tue Oct 12 11:32:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Slava Ovsiienko X-Patchwork-Id: 101206 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 573D3A0C47; Tue, 12 Oct 2021 13:33:31 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0D3EE41183; Tue, 12 Oct 2021 13:33:06 +0200 (CEST) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2061.outbound.protection.outlook.com [40.107.236.61]) by mails.dpdk.org (Postfix) with ESMTP id 172F341178 for ; Tue, 12 Oct 2021 13:33:05 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JpTReLNtRsPlVXSpIfv1ZGCx9CNt45sAa/4LaMiE7X9Q/ahhOsfTtGDlsnQY23QjSus2hfceV1VNw+7ExhSYljE6KEDRvTGZ36bgwHiAMtTQYBfaD2E+7fqABaKoDnm5XhuUwY8uB3aGHgWrOSgk0XPTPLGeAnlN18gzE/OzXhPDnh7uSgR57hDC/UF+1yKKfZkr5tPg4eiDwrN7TCw+wmOCqSd7O2QOJJi8FYpR1CRC58q7g7wTvxnlvInSxljzHJycOyf2SfBrVPcNmEWU6fenO/cfjEvhWEJZUM9fNTb27rVjxYztXMYFVfarHGSgQDPExylHi4tmMrZHIMd0Ww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Wry8tldQSOhmz6YITFqgdatLuHshM/tjVvbCWAbpDwU=; b=REbXKaixDZ0ZNOv48+8Uvz9HrlFsekNKSdv6MRs+NFYo8pw+8bck/edPAdTOXdZgDgaUNHyMQ1rghri3LzSIJ9ZGMPZvVHCltN8e7UwLonc9JqcEdNEJoSNiU4KuBXcGxWSripShd9hefAd+ylHXlfP2GsOMssRzT2xadOybjlllz5biK6ly5cAJvoyS1090n1wncyu53B2VD853cuxWprJ72hTrVzogyBqskhQoF4mDPkZpVh21BmGpbezJY/MGa2GxTiBfE0xGbM/lf0Cx+6wvDNYftfxKNiMkPOZHrNjEStVMMTGNe4s6I1f2LYrgxRS0iBtvBiQ4djwtGUsgfg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=monjalon.net smtp.mailfrom=nvidia.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Wry8tldQSOhmz6YITFqgdatLuHshM/tjVvbCWAbpDwU=; b=ZhlHjRhOajlIFwidFAwmzh+PB/xZl+gi0OLl6R8bMpisqIJuvDEO9ekvoOigThnmMtUGENAooX1LJyPIh010ihmJG+hCM5aqij9zeAEHbhudZ0A/AG3fbXwaz1soFMbpvJCK3Yq65kCPOGmUs+U+vnBIjvF6zG2Jn5wOxI8Qe2A2d60ZzttckQSeJFMDdXp8YXmi5BTzXOEF8m+40y7IfBW4gaIjrvC2hX7JQaKlHs1j1ZUlvcfKRzvxZQL7zOf/PV1u4VwUTlSwCwRoEm7u9KWCWeraCpWg1iesaKPPVaRHI2DREak3nNnoIUDL01PH+unQx0S0aTOOicxOpZMFAg== Received: from BN0PR02CA0055.namprd02.prod.outlook.com (2603:10b6:408:e5::30) by DM6PR12MB3402.namprd12.prod.outlook.com (2603:10b6:5:3b::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.22; Tue, 12 Oct 2021 11:33:03 +0000 Received: from BN8NAM11FT025.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e5:cafe::a5) by BN0PR02CA0055.outlook.office365.com (2603:10b6:408:e5::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.24 via Frontend Transport; Tue, 12 Oct 2021 11:33:03 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; monjalon.net; dkim=none (message not signed) header.d=none;monjalon.net; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by BN8NAM11FT025.mail.protection.outlook.com (10.13.177.136) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4587.18 via Frontend Transport; Tue, 12 Oct 2021 11:33:02 +0000 Received: from nvidia.com (172.20.187.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 11:33:00 +0000 From: Viacheslav Ovsiienko To: CC: , , , , , Date: Tue, 12 Oct 2021 14:32:35 +0300 Message-ID: <20211012113235.24975-6-viacheslavo@nvidia.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20211012113235.24975-1-viacheslavo@nvidia.com> References: <20210922180418.20663-1-viacheslavo@nvidia.com> <20211012113235.24975-1-viacheslavo@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [172.20.187.6] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9f5f4f07-1916-4d1b-3159-08d98d740d48 X-MS-TrafficTypeDiagnostic: DM6PR12MB3402: X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:240; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: FmjzFkYi4rhTfSJjPtAvYDD2xWpWT3qE03+6FV3zQPMik/iQoc+NiV0TeaBJ72ia9QGHnUdJocmZQRn6X3SYTdlPSD/Ar86aDDFj61FarTdQK5jttMKK8YbgstCoSmbCTZgWiBniXsm36KU4TLgwVerBLqvBpexnEe71N/S4iomG0VHMkKi3SKKh9ijsqTZH2g9b6OwBYX7PTg1TkaLHttlxDjhuRbj+MM7HHqCsImG8QGzcXyWTx7mFf5Qtloh71tKtFeq0Ti0NncAIaa53koPHoxIukM+DcMt3wt3MFmzIksaRCBHxeNchABfXa+Nlj8qJrSmNOqRTFExO60eixyAKcIGF9UxsD2/mtKVcnGFr0uQMDulPNiagM6SJs5W4FaC36dClnLNqp4WInVWSxHXvGa6myd8wQ/3YTUO+wAGi+QeeftD6fezGBYd0TT79aI9hWIbK/1DU2KtgvhmWCqcKOlUjkSTaH+nqJjBa+KfRLzhAJQda6bvIRaODF8QhcGAPrIZrrk8vBRcr5grhxC95wF4Ipno9PNBhRvV2wGWoUypRxaMJTikAg1xXps56yb/60dA1nZRafKPQVKeywBwqRQzxNi4TPYYCTurlHy1KFl/xi6AG3JdkUVhin3kG7t+ySaC/wSpS0wywTJtYWTMf8AACKMNYgDa9v50JnUOhf05+RccpJGG1hRCXl2vPpIUqlKsbd/GFAehlRppAQg== X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(30864003)(54906003)(4326008)(186003)(7636003)(83380400001)(8936002)(316002)(2616005)(508600001)(26005)(1076003)(36860700001)(16526019)(36756003)(8676002)(2906002)(356005)(336012)(6916009)(55016002)(426003)(5660300002)(86362001)(6286002)(82310400003)(70206006)(6666004)(47076005)(7696005)(70586007); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Oct 2021 11:33:02.6574 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9f5f4f07-1916-4d1b-3159-08d98d740d48 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT025.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3402 Subject: [dpdk-dev] [PATCH v4 5/5] app/testpmd: add flex item CLI commands X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gregory Etelson Network port hardware is shipped with fixed number of supported network protocols. If application must work with a protocol that is not included in the port hardware by default, it can try to add the new protocol to port hardware. Flex item or flex parser is port infrastructure that allows application to add support for a custom network header and offload flows to match the header elements. Application must complete the following tasks to create a flow rule that matches custom header: 1. Create flow item object in port hardware. Application must provide custom header configuration to PMD. PMD will use that configuration to create flex item object in port hardware. 2. Create flex patterns to match. Flex pattern has a spec and a mask components, like a regular flow item. Combined together, spec and mask can target unique data sequence or a number of data sequences in the custom header. Flex patterns of the same flex item can have different lengths. Flex pattern is identified by unique handler value. 3. Create a flow rule with a flex flow item that references flow pattern. Testpmd flex CLI commands are: testpmd> flow flex_item create testpmd> set flex_pattern \ spec mask testpmd> set flex_pattern is testpmd> flow create ... \ / flex item is pattern is / ... The patch works with the jansson library API. Jansson development files must be present: jansson.pc, jansson.h libjansson.[a,so] Signed-off-by: Gregory Etelson Reviewed-by: Viacheslav Ovsiienko --- app/test-pmd/cmdline.c | 2 + app/test-pmd/cmdline_flow.c | 764 +++++++++++++++++++- app/test-pmd/testpmd.c | 2 +- app/test-pmd/testpmd.h | 16 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 119 +++ 5 files changed, 901 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index a9efd027c3..a673e6ef08 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -17822,6 +17822,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_show_fec_mode, (cmdline_parse_inst_t *)&cmd_set_fec_mode, (cmdline_parse_inst_t *)&cmd_show_capability, + (cmdline_parse_inst_t *)&cmd_set_flex_is_pattern, + (cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern, NULL, }; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index bb22294dd3..b8dd9369b1 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -54,6 +54,8 @@ enum index { COMMON_PRIORITY_LEVEL, COMMON_INDIRECT_ACTION_ID, COMMON_POLICY_ID, + COMMON_FLEX_HANDLE, + COMMON_FLEX_TOKEN, /* TOP-level command. */ ADD, @@ -81,6 +83,12 @@ enum index { AGED, ISOLATE, TUNNEL, + FLEX, + + /* Flex arguments */ + FLEX_ITEM_INIT, + FLEX_ITEM_CREATE, + FLEX_ITEM_DESTROY, /* Tunnel arguments. */ TUNNEL_CREATE, @@ -306,6 +314,9 @@ enum index { ITEM_POL_PORT, ITEM_POL_METER, ITEM_POL_POLICY, + ITEM_FLEX, + ITEM_FLEX_ITEM_HANDLE, + ITEM_FLEX_PATTERN_HANDLE, /* Validate/create actions. */ ACTIONS, @@ -844,6 +855,11 @@ struct buffer { struct { uint32_t policy_id; } policy;/**< Policy arguments. */ + struct { + uint16_t token; + uintptr_t uintptr; + char filename[128]; + } flex; /**< Flex arguments*/ } args; /**< Command arguments. */ }; @@ -871,6 +887,13 @@ struct parse_action_priv { .size = s, \ }) +static const enum index next_flex_item[] = { + FLEX_ITEM_INIT, + FLEX_ITEM_CREATE, + FLEX_ITEM_DESTROY, + ZERO, +}; + static const enum index next_ia_create_attr[] = { INDIRECT_ACTION_CREATE_ID, INDIRECT_ACTION_INGRESS, @@ -1000,6 +1023,7 @@ static const enum index next_item[] = { ITEM_GENEVE_OPT, ITEM_INTEGRITY, ITEM_CONNTRACK, + ITEM_FLEX, END_SET, ZERO, }; @@ -1368,6 +1392,13 @@ static const enum index item_integrity_lv[] = { ZERO, }; +static const enum index item_flex[] = { + ITEM_FLEX_PATTERN_HANDLE, + ITEM_FLEX_ITEM_HANDLE, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -1724,6 +1755,9 @@ static int parse_set_sample_action(struct context *, const struct token *, static int parse_set_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int +parse_flex_handle(struct context *, const struct token *, + const char *, unsigned int, void *, unsigned int); static int parse_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1840,6 +1874,8 @@ static int parse_isolate(struct context *, const struct token *, static int parse_tunnel(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_flex(struct context *, const struct token *, + const char *, unsigned int, void *, unsigned int); static int parse_int(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1904,6 +1940,17 @@ static int comp_set_modify_field_op(struct context *, const struct token *, unsigned int, char *, unsigned int); static int comp_set_modify_field_id(struct context *, const struct token *, unsigned int, char *, unsigned int); +static void flex_item_create(portid_t port_id, uint16_t flex_id, + const char *filename); +static void flex_item_destroy(portid_t port_id, uint16_t flex_id); +struct flex_pattern { + struct rte_flow_item_flex spec, mask; + uint8_t spec_pattern[FLEX_MAX_FLOW_PATTERN_LENGTH]; + uint8_t mask_pattern[FLEX_MAX_FLOW_PATTERN_LENGTH]; +}; + +static struct flex_item *flex_items[RTE_MAX_ETHPORTS][FLEX_MAX_PARSERS_NUM]; +static struct flex_pattern flex_patterns[FLEX_MAX_PATTERNS_NUM]; /** Token definitions. */ static const struct token token_list[] = { @@ -2040,6 +2087,20 @@ static const struct token token_list[] = { .call = parse_int, .comp = comp_none, }, + [COMMON_FLEX_TOKEN] = { + .name = "{flex token}", + .type = "flex token", + .help = "flex token", + .call = parse_int, + .comp = comp_none, + }, + [COMMON_FLEX_HANDLE] = { + .name = "{flex handle}", + .type = "FLEX HANDLE", + .help = "fill flex item data", + .call = parse_flex_handle, + .comp = comp_none, + }, /* Top-level command. */ [FLOW] = { .name = "flow", @@ -2056,7 +2117,8 @@ static const struct token token_list[] = { AGED, QUERY, ISOLATE, - TUNNEL)), + TUNNEL, + FLEX)), .call = parse_init, }, /* Top-level command. */ @@ -2168,6 +2230,41 @@ static const struct token token_list[] = { ARGS_ENTRY(struct buffer, port)), .call = parse_isolate, }, + [FLEX] = { + .name = "flex_item", + .help = "flex item API", + .next = NEXT(next_flex_item), + .call = parse_flex, + }, + [FLEX_ITEM_INIT] = { + .name = "init", + .help = "flex item init", + .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), + ARGS_ENTRY(struct buffer, port)), + .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), + NEXT_ENTRY(COMMON_PORT_ID)), + .call = parse_flex + }, + [FLEX_ITEM_CREATE] = { + .name = "create", + .help = "flex item create", + .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), + ARGS_ENTRY(struct buffer, args.flex.token), + ARGS_ENTRY(struct buffer, port)), + .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), + NEXT_ENTRY(COMMON_FLEX_TOKEN), + NEXT_ENTRY(COMMON_PORT_ID)), + .call = parse_flex + }, + [FLEX_ITEM_DESTROY] = { + .name = "destroy", + .help = "flex item destroy", + .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), + ARGS_ENTRY(struct buffer, port)), + .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), + NEXT_ENTRY(COMMON_PORT_ID)), + .call = parse_flex + }, [TUNNEL] = { .name = "tunnel", .help = "new tunnel API", @@ -3608,6 +3705,27 @@ static const struct token token_list[] = { item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), }, + [ITEM_FLEX] = { + .name = "flex", + .help = "match flex header", + .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), + .next = NEXT(item_flex), + .call = parse_vc, + }, + [ITEM_FLEX_ITEM_HANDLE] = { + .name = "item", + .help = "flex item handle", + .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), + NEXT_ENTRY(ITEM_PARAM_IS)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), + }, + [ITEM_FLEX_PATTERN_HANDLE] = { + .name = "pattern", + .help = "flex pattern handle", + .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), + NEXT_ENTRY(ITEM_PARAM_IS)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -6999,6 +7117,43 @@ parse_isolate(struct context *ctx, const struct token *token, return len; } +static int +parse_flex(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (out->command == ZERO) { + if (ctx->curr != FLEX) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + } else { + switch (ctx->curr) { + default: + break; + case FLEX_ITEM_INIT: + case FLEX_ITEM_CREATE: + case FLEX_ITEM_DESTROY: + out->command = ctx->curr; + break; + } + } + + return len; +} + static int parse_tunnel(struct context *ctx, const struct token *token, const char *str, unsigned int len, @@ -7661,6 +7816,71 @@ parse_set_init(struct context *ctx, const struct token *token, return len; } +/* + * Replace testpmd handles in a flex flow item with real values. + */ +static int +parse_flex_handle(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct rte_flow_item_flex *spec, *mask; + const struct rte_flow_item_flex *src_spec, *src_mask; + const struct arg *arg = pop_args(ctx); + uint32_t offset; + uint16_t handle; + int ret; + + if (!arg) { + printf("Bad environment\n"); + return -1; + } + offset = arg->offset; + push_args(ctx, arg); + ret = parse_int(ctx, token, str, len, buf, size); + if (ret <= 0 || !ctx->object) + return ret; + if (ctx->port >= RTE_MAX_ETHPORTS) { + printf("Bad port\n"); + return -1; + } + if (offset == offsetof(struct rte_flow_item_flex, handle)) { + const struct flex_item *fp; + struct rte_flow_item_flex *item_flex = ctx->object; + handle = (uint16_t)(uintptr_t)item_flex->handle; + if (handle >= FLEX_MAX_PARSERS_NUM) { + printf("Bad flex item handle\n"); + return -1; + } + fp = flex_items[ctx->port][handle]; + if (!fp) { + printf("Bad flex item handle\n"); + return -1; + } + item_flex->handle = fp->flex_handle; + } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { + handle = (uint16_t)(uintptr_t) + ((struct rte_flow_item_flex *)ctx->object)->pattern; + if (handle >= FLEX_MAX_PATTERNS_NUM) { + printf("Bad pattern handle\n"); + return -1; + } + src_spec = &flex_patterns[handle].spec; + src_mask = &flex_patterns[handle].mask; + spec = ctx->object; + mask = spec + 2; /* spec, last, mask */ + /* fill flow rule spec and mask parameters */ + spec->length = src_spec->length; + spec->pattern = src_spec->pattern; + mask->length = src_mask->length; + mask->pattern = src_mask->pattern; + } else { + printf("Bad arguments - unknown flex item offset\n"); + return -1; + } + return ret; +} + /** No completion. */ static int comp_none(struct context *ctx, const struct token *token, @@ -8167,6 +8387,13 @@ cmd_flow_parsed(const struct buffer *in) port_meter_policy_add(in->port, in->args.policy.policy_id, in->args.vc.actions); break; + case FLEX_ITEM_CREATE: + flex_item_create(in->port, in->args.flex.token, + in->args.flex.filename); + break; + case FLEX_ITEM_DESTROY: + flex_item_destroy(in->port, in->args.flex.token); + break; default: break; } @@ -8618,6 +8845,11 @@ cmd_set_raw_parsed(const struct buffer *in) case RTE_FLOW_ITEM_TYPE_PFCP: size = sizeof(struct rte_flow_item_pfcp); break; + case RTE_FLOW_ITEM_TYPE_FLEX: + size = item->spec ? + ((const struct rte_flow_item_flex *) + item->spec)->length : 0; + break; default: fprintf(stderr, "Error - Not supported item\n"); goto error; @@ -8800,3 +9032,533 @@ cmdline_parse_inst_t cmd_show_set_raw_all = { NULL, }, }; + +#ifdef RTE_HAS_JANSSON +static __rte_always_inline bool +match_strkey(const char *key, const char *pattern) +{ + return strncmp(key, pattern, strlen(key)) == 0; +} + +static struct flex_item * +flex_parser_fetch(uint16_t port_id, uint16_t flex_id) +{ + if (port_id >= RTE_MAX_ETHPORTS) { + printf("Invalid port_id: %u\n", port_id); + return FLEX_PARSER_ERR; + } + if (flex_id >= FLEX_MAX_PARSERS_NUM) { + printf("Invalid flex item flex_id: %u\n", flex_id); + return FLEX_PARSER_ERR; + } + return flex_items[port_id][flex_id]; +} + +static void +flex_item_destroy(portid_t port_id, uint16_t flex_id) +{ + int ret; + struct rte_flow_error error; + struct flex_item *fp = flex_parser_fetch(port_id, flex_id); + if (fp == FLEX_PARSER_ERR) { + printf("Bad parameters: port_id=%u flex_id=%u\n", + port_id, flex_id); + return; + } + if (!fp) + return; + ret = rte_flow_flex_item_release(port_id, fp->flex_handle, &error); + if (!ret) { + free(fp); + flex_items[port_id][flex_id] = NULL; + printf("port-%u: released flex item #%u\n", + port_id, flex_id); + + } else { + printf("port-%u: cannot release flex item #%u: %s\n", + port_id, flex_id, error.message); + } +} + +static int +flex_tunnel_parse(json_t *jtun, enum rte_flow_item_flex_tunnel_mode *tunnel) +{ + int tun = -1; + + if (json_is_integer(jtun)) + tun = (int)json_integer_value(jtun); + else if (json_is_real(jtun)) + tun = (int)json_real_value(jtun); + else if (json_is_string(jtun)) { + const char *mode = json_string_value(jtun); + + if (match_strkey(mode, "FLEX_TUNNEL_MODE_SINGLE")) + tun = FLEX_TUNNEL_MODE_SINGLE; + else if (match_strkey(mode, "FLEX_TUNNEL_MODE_OUTER")) + tun = FLEX_TUNNEL_MODE_OUTER; + else if (match_strkey(mode, "FLEX_TUNNEL_MODE_INNER")) + tun = FLEX_TUNNEL_MODE_INNER; + else if (match_strkey(mode, "FLEX_TUNNEL_MODE_MULTI")) + tun = FLEX_TUNNEL_MODE_MULTI; + else if (match_strkey(mode, "FLEX_TUNNEL_MODE_TUNNEL")) + tun = FLEX_TUNNEL_MODE_TUNNEL; + else + return -EINVAL; + } else + return -EINVAL; + *tunnel = (enum rte_flow_item_flex_tunnel_mode)tun; + return 0; +} + +static int +flex_field_parse(json_t *jfld, struct rte_flow_item_flex_field *fld) +{ + const char *key; + json_t *je; + +#define FLEX_FIELD_GET(fm, t) \ +do { \ + if (!strncmp(key, # fm, strlen(# fm))) { \ + if (json_is_real(je)) \ + fld->fm = (t) json_real_value(je); \ + else if (json_is_integer(je)) \ + fld->fm = (t) json_integer_value(je); \ + else \ + return -EINVAL; \ + } \ +} while (0) + + json_object_foreach(jfld, key, je) { + FLEX_FIELD_GET(field_size, uint32_t); + FLEX_FIELD_GET(field_base, int32_t); + FLEX_FIELD_GET(offset_base, uint32_t); + FLEX_FIELD_GET(offset_mask, uint32_t); + FLEX_FIELD_GET(offset_shift, int32_t); + FLEX_FIELD_GET(field_id, uint16_t); + if (match_strkey(key, "field_mode")) { + const char *mode; + if (!json_is_string(je)) + return -EINVAL; + mode = json_string_value(je); + if (match_strkey(mode, "FIELD_MODE_DUMMY")) + fld->field_mode = FIELD_MODE_DUMMY; + else if (match_strkey(mode, "FIELD_MODE_FIXED")) + fld->field_mode = FIELD_MODE_FIXED; + else if (match_strkey(mode, "FIELD_MODE_OFFSET")) + fld->field_mode = FIELD_MODE_OFFSET; + else if (match_strkey(mode, "FIELD_MODE_BITMASK")) + fld->field_mode = FIELD_MODE_BITMASK; + else + return -EINVAL; + } + } + return 0; +} + +enum flex_link_type { + FLEX_LINK_IN = 0, + FLEX_LINK_OUT = 1 +}; + +static int +flex_link_item_parse(const char *pattern, struct rte_flow_item *item) +{ +#define FLEX_PARSE_DATA_SIZE 1024 + + int ret; + uint8_t *ptr, data[FLEX_PARSE_DATA_SIZE] = {0,}; + char flow_rule[256]; + struct context saved_flow_ctx = cmd_flow_context; + + sprintf(flow_rule, "flow create 0 pattern %s / end", pattern); + pattern = flow_rule; + cmd_flow_context_init(&cmd_flow_context); + do { + ret = cmd_flow_parse(NULL, pattern, (void *)data, sizeof(data)); + if (ret > 0) { + pattern += ret; + while (isspace(*pattern)) + pattern++; + } + } while (ret > 0 && strlen(pattern)); + if (ret >= 0 && !strlen(pattern)) { + struct buffer *pbuf = (struct buffer *)(uintptr_t)data; + struct rte_flow_item *src = pbuf->args.vc.pattern; + + item->type = src->type; + if (src->spec) { + ptr = (void *)(uintptr_t)item->spec; + memcpy(ptr, src->spec, FLEX_MAX_FLOW_PATTERN_LENGTH); + } else { + item->spec = NULL; + } + if (src->mask) { + ptr = (void *)(uintptr_t)item->mask; + memcpy(ptr, src->mask, FLEX_MAX_FLOW_PATTERN_LENGTH); + } else { + item->mask = NULL; + } + if (src->last) { + ptr = (void *)(uintptr_t)item->last; + memcpy(ptr, src->last, FLEX_MAX_FLOW_PATTERN_LENGTH); + } else { + item->last = NULL; + } + ret = 0; + } + cmd_flow_context = saved_flow_ctx; + return ret; +} + +static int +flex_link_parse(json_t *jobj, struct rte_flow_item_flex_link *link, + enum flex_link_type link_type) +{ + const char *key; + json_t *je; + int ret; + json_object_foreach(jobj, key, je) { + if (match_strkey(key, "item")) { + if (!json_is_string(je)) + return -EINVAL; + ret = flex_link_item_parse(json_string_value(je), + &link->item); + if (ret) + return -EINVAL; + if (link_type == FLEX_LINK_IN) { + if (!link->item.spec || !link->item.mask) + return -EINVAL; + if (link->item.last) + return -EINVAL; + } + } + if (match_strkey(key, "next")) { + if (json_is_integer(je)) + link->next = (typeof(link->next)) + json_integer_value(je); + else if (json_is_real(je)) + link->next = (typeof(link->next)) + json_real_value(je); + else + return -EINVAL; + } + } + return 0; +} + +static int flex_item_config(json_t *jroot, + struct rte_flow_item_flex_conf *flex_conf) +{ + const char *key; + json_t *jobj = NULL; + int ret = 0; + + json_object_foreach(jroot, key, jobj) { + if (match_strkey(key, "tunnel")) { + ret = flex_tunnel_parse(jobj, &flex_conf->tunnel); + if (ret) { + printf("Can't parse tunnel value\n"); + goto out; + } + } else if (match_strkey(key, "next_header")) { + ret = flex_field_parse(jobj, &flex_conf->next_header); + if (ret) { + printf("Can't parse next_header field\n"); + goto out; + } + } else if (match_strkey(key, "next_protocol")) { + ret = flex_field_parse(jobj, + &flex_conf->next_protocol); + if (ret) { + printf("Can't parse next_protocol field\n"); + goto out; + } + } else if (match_strkey(key, "sample_data")) { + json_t *ji; + uint32_t i, size = json_array_size(jobj); + for (i = 0; i < size; i++) { + ji = json_array_get(jobj, i); + ret = flex_field_parse + (ji, flex_conf->sample_data + i); + if (ret) { + printf("Can't parse sample_data field(s)\n"); + goto out; + } + } + flex_conf->nb_samples = size; + } else if (match_strkey(key, "input_link")) { + json_t *ji; + uint32_t i, size = json_array_size(jobj); + for (i = 0; i < size; i++) { + ji = json_array_get(jobj, i); + ret = flex_link_parse(ji, + flex_conf->input_link + i, + FLEX_LINK_IN); + if (ret) { + printf("Can't parse input_link(s)\n"); + goto out; + } + } + flex_conf->nb_inputs = size; + } else if (match_strkey(key, "output_link")) { + json_t *ji; + uint32_t i, size = json_array_size(jobj); + for (i = 0; i < size; i++) { + ji = json_array_get(jobj, i); + ret = flex_link_parse + (ji, flex_conf->output_link + i, + FLEX_LINK_OUT); + if (ret) { + printf("Can't parse output_link(s)\n"); + goto out; + } + } + flex_conf->nb_outputs = size; + } + } +out: + return ret; +} + +static struct flex_item * +flex_item_init(void) +{ + size_t base_size, samples_size, links_size, spec_size; + struct rte_flow_item_flex_conf *conf; + struct flex_item *fp; + uint8_t (*pattern)[FLEX_MAX_FLOW_PATTERN_LENGTH]; + int i; + + base_size = RTE_ALIGN(sizeof(*conf), sizeof(uintptr_t)); + samples_size = RTE_ALIGN(FLEX_ITEM_MAX_SAMPLES_NUM * + sizeof(conf->sample_data[0]), + sizeof(uintptr_t)); + links_size = RTE_ALIGN(FLEX_ITEM_MAX_LINKS_NUM * + sizeof(conf->input_link[0]), + sizeof(uintptr_t)); + /* spec & mask for all input links */ + spec_size = 2 * FLEX_MAX_FLOW_PATTERN_LENGTH * FLEX_ITEM_MAX_LINKS_NUM; + fp = calloc(1, base_size + samples_size + 2 * links_size + spec_size); + if (fp == NULL) { + printf("Can't allocate memory for flex item\n"); + return NULL; + } + conf = &fp->flex_conf; + conf->sample_data = (typeof(conf->sample_data)) + ((uint8_t *)fp + base_size); + conf->input_link = (typeof(conf->input_link)) + ((uint8_t *)conf->sample_data + samples_size); + conf->output_link = (typeof(conf->output_link)) + ((uint8_t *)conf->input_link + links_size); + pattern = (typeof(pattern))((uint8_t *)conf->output_link + links_size); + for (i = 0; i < FLEX_ITEM_MAX_LINKS_NUM; i++) { + struct rte_flow_item_flex_link *in = conf->input_link + i; + in->item.spec = pattern++; + in->item.mask = pattern++; + } + return fp; +} + +static void +flex_item_create(portid_t port_id, uint16_t flex_id, const char *filename) +{ + struct rte_flow_error flow_error; + json_error_t json_error; + json_t *jroot = NULL; + struct flex_item *fp = flex_parser_fetch(port_id, flex_id); + int ret; + + if (fp == FLEX_PARSER_ERR) { + printf("Bad parameters: port_id=%u flex_id=%u\n", + port_id, flex_id); + return; + } + if (fp) { + printf("port-%u: flex item #%u is already in use\n", + port_id, flex_id); + return; + } + jroot = json_load_file(filename, 0, &json_error); + if (!jroot) { + printf("Bad JSON file \"%s\": %s\n", filename, json_error.text); + return; + } + fp = flex_item_init(); + if (!fp) { + printf("Could not allocate flex item\n"); + goto out; + } + ret = flex_item_config(jroot, &fp->flex_conf); + if (ret) + goto out; + fp->flex_handle = rte_flow_flex_item_create(port_id, + &fp->flex_conf, + &flow_error); + if (fp->flex_handle) { + flex_items[port_id][flex_id] = fp; + printf("port-%u: created flex item #%u\n", port_id, flex_id); + fp = NULL; + } else { + printf("port-%u: flex item #%u creation failed: %s\n", + port_id, flex_id, + flow_error.message ? flow_error.message : ""); + } +out: + if (fp) + free(fp); + if (jroot) + json_decref(jroot); +} + +#else /* RTE_HAS_JANSSON */ +static void flex_item_create(__rte_unused portid_t port_id, + __rte_unused uint16_t flex_id, + __rte_unused const char *filename) +{ + printf("no JSON library\n"); +} + +static void flex_item_destroy(__rte_unused portid_t port_id, + __rte_unused uint16_t flex_id) +{ + printf("no JSON library\n"); +} +#endif /* RTE_HAS_JANSSON */ + +void +port_flex_item_flush(portid_t port_id) +{ + uint16_t i; + + for (i = 0; i < FLEX_MAX_PARSERS_NUM; i++) { + flex_item_destroy(port_id, i); + flex_items[port_id][i] = NULL; + } +} + +struct flex_pattern_set { + cmdline_fixed_string_t set, flex_pattern; + cmdline_fixed_string_t is_spec, mask; + cmdline_fixed_string_t spec_data, mask_data; + uint16_t id; +}; + +static cmdline_parse_token_string_t flex_pattern_set_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, set, "set"); +static cmdline_parse_token_string_t flex_pattern_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, + flex_pattern, "flex_pattern"); +static cmdline_parse_token_string_t flex_pattern_is_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, + is_spec, "is"); +static cmdline_parse_token_string_t flex_pattern_spec_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, + is_spec, "spec"); +static cmdline_parse_token_string_t flex_pattern_mask_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, mask, "mask"); +static cmdline_parse_token_string_t flex_pattern_spec_data_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, spec_data, NULL); +static cmdline_parse_token_string_t flex_pattern_mask_data_token = + TOKEN_STRING_INITIALIZER(struct flex_pattern_set, mask_data, NULL); +static cmdline_parse_token_num_t flex_pattern_id_token = + TOKEN_NUM_INITIALIZER(struct flex_pattern_set, id, RTE_UINT16); + +/* + * flex pattern data - spec or mask is a string representation of byte array + * in hexadecimal format. Each byte in data string must have 2 characters: + * 0x15 - "15" + * 0x1 - "01" + * Bytes in data array are in network order. + */ +static uint32_t +flex_pattern_data(const char *str, uint8_t *data) +{ + uint32_t i, len = strlen(str); + char b[3], *endptr; + + if (len & 01) + return 0; + len /= 2; + if (len >= FLEX_MAX_FLOW_PATTERN_LENGTH) + return 0; + for (i = 0, b[2] = '\0'; i < len; i++) { + b[0] = str[2 * i]; + b[1] = str[2 * i + 1]; + data[i] = strtoul(b, &endptr, 16); + if (endptr != &b[2]) + return 0; + } + return len; +} + +static void +flex_pattern_parsed_fn(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct flex_pattern_set *res = parsed_result; + struct flex_pattern *fp; + bool full_spec; + + if (res->id >= FLEX_MAX_PATTERNS_NUM) { + printf("Bad flex pattern id\n"); + return; + } + fp = flex_patterns + res->id; + memset(fp->spec_pattern, 0, sizeof(fp->spec_pattern)); + memset(fp->mask_pattern, 0, sizeof(fp->mask_pattern)); + fp->spec.length = flex_pattern_data(res->spec_data, fp->spec_pattern); + if (!fp->spec.length) { + printf("Bad flex pattern spec\n"); + return; + } + full_spec = strncmp(res->is_spec, "spec", strlen("spec")) == 0; + if (full_spec) { + fp->mask.length = flex_pattern_data(res->mask_data, + fp->mask_pattern); + if (!fp->mask.length) { + printf("Bad flex pattern mask\n"); + return; + } + } else { + memset(fp->mask_pattern, 0xFF, fp->spec.length); + fp->mask.length = fp->spec.length; + } + if (fp->mask.length != fp->spec.length) { + printf("Spec length do not match mask length\n"); + return; + } + fp->spec.pattern = fp->spec_pattern; + fp->mask.pattern = fp->mask_pattern; + printf("created pattern #%u\n", res->id); +} + +cmdline_parse_inst_t cmd_set_flex_is_pattern = { + .f = flex_pattern_parsed_fn, + .data = NULL, + .help_str = "set flex_pattern is ", + .tokens = { + (void *)&flex_pattern_set_token, + (void *)&flex_pattern_token, + (void *)&flex_pattern_id_token, + (void *)&flex_pattern_is_token, + (void *)&flex_pattern_spec_data_token, + NULL, + } +}; + +cmdline_parse_inst_t cmd_set_flex_spec_pattern = { + .f = flex_pattern_parsed_fn, + .data = NULL, + .help_str = "set flex_pattern spec mask ", + .tokens = { + (void *)&flex_pattern_set_token, + (void *)&flex_pattern_token, + (void *)&flex_pattern_id_token, + (void *)&flex_pattern_spec_token, + (void *)&flex_pattern_spec_data_token, + (void *)&flex_pattern_mask_token, + (void *)&flex_pattern_mask_data_token, + NULL, + } +}; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 97ae52e17e..26357bc6e3 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -2886,6 +2886,7 @@ close_port(portid_t pid) if (is_proc_primary()) { port_flow_flush(pi); + port_flex_item_flush(pi); rte_eth_dev_close(pi); } } @@ -4017,7 +4018,6 @@ main(int argc, char** argv) rte_stats_bitrate_reg(bitrate_data); } #endif - #ifdef RTE_LIB_CMDLINE if (strlen(cmdline_filename) != 0) cmdline_read_from_file(cmdline_filename); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 876a341cf0..3437d7607d 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -282,6 +282,19 @@ struct fwd_engine { packet_fwd_t packet_fwd; /**< Mandatory. */ }; +struct flex_item { + struct rte_flow_item_flex_conf flex_conf; + struct rte_flow_item_flex_handle *flex_handle; + uint32_t flex_id; +}; + +#define FLEX_ITEM_MAX_SAMPLES_NUM 16 +#define FLEX_ITEM_MAX_LINKS_NUM 16 +#define FLEX_MAX_FLOW_PATTERN_LENGTH 64 +#define FLEX_MAX_PARSERS_NUM 8 +#define FLEX_MAX_PATTERNS_NUM 64 +#define FLEX_PARSER_ERR ((struct flex_item *)-1) + #define BURST_TX_WAIT_US 1 #define BURST_TX_RETRIES 64 @@ -306,6 +319,8 @@ extern struct fwd_engine * fwd_engines[]; /**< NULL terminated array. */ extern cmdline_parse_inst_t cmd_set_raw; extern cmdline_parse_inst_t cmd_show_set_raw; extern cmdline_parse_inst_t cmd_show_set_raw_all; +extern cmdline_parse_inst_t cmd_set_flex_is_pattern; +extern cmdline_parse_inst_t cmd_set_flex_spec_pattern; extern uint16_t mempool_flags; @@ -1026,6 +1041,7 @@ uint16_t tx_pkt_set_dynf(uint16_t port_id, __rte_unused uint16_t queue, void add_tx_dynf_callback(portid_t portid); void remove_tx_dynf_callback(portid_t portid); int update_jumbo_frame_offload(portid_t portid); +void port_flex_item_flush(portid_t port_id); /* * Work-around of a compilation error with ICC on invocations of the diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index bbef706374..4f03efd43f 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -5091,3 +5091,122 @@ For example to unload BPF filter from TX queue 0, port 0: .. code-block:: console testpmd> bpf-unload tx 0 0 + +Flex Item Functions +------------------- + +The following sections show functions that configure and create flex item object, +create flex pattern and use it in a flow rule. +The commands will use 20 bytes IPv4 header for examples: + +:: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | ver | IHL | TOS | length | +0 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | identification | flg | frag. offset | +4 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | TTL | protocol | checksum | +8 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | source IP address | +12 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | destination IP address | +16 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Create flex item +~~~~~~~~~~~~~~~~ + +Flex item object is created by PMD according to a new header configuration. The +header configuration is compiled by the testpmd and stored in +``rte_flow_item_flex_conf`` type variable. + +:: + + # flow flex_item create + testpmd> flow flex_item init 0 3 ipv4_flex_config.json + port-0: created flex item #3 + +Flex item configuration is kept in external JSON file. +It describes the following header elements: + +**New header length.** + +Specify whether the new header has fixed or variable length and the basic/minimal +header length value. + +If header length is not fixed, header location with a value that completes header +length calculation and scale/offset function must be added. + +Scale function depends on port hardware. + +**Next protocol.** + +Describes location in the new header that specify following network header type. + +**Flow match samples.** + +Describes locations in the new header that will be used in flow rules. + +Number of flow samples and sample maximal length depend of port hardware. + +**Input trigger.** + +Describes preceding network header configuration. + +**Output trigger.** + +Describes conditions that trigger transfer to following network header + +.. code-block:: json + + { + "next_header": { "field_mode": "FIELD_MODE_FIXED", "field_size": 20}, + "next_protocol": {"field_size": 8, "field_base": 72}, + "sample_data": [ + { "field_mode": "FIELD_MODE_FIXED", "field_size": 32, "field_base": 0}, + { "field_mode": "FIELD_MODE_FIXED", "field_size": 32, "field_base": 32}, + { "field_mode": "FIELD_MODE_FIXED", "field_size": 32, "field_base": 64}, + { "field_mode": "FIELD_MODE_FIXED", "field_size": 32, "field_base": 96} + ], + "input_link": [ + {"item": "eth type is 0x0800"}, + {"item": "vlan inner_type is 0x0800"} + ], + "output_link": [ + {"item": "udp", "next": 17}, + {"item": "tcp", "next": 6}, + {"item": "icmp", "next": 1} + ] + } + + +Flex pattern and flow rules +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Flex pattern describe parts of network header that will trigger flex flow item hit in a flow rule. +Flex pattern directly related to flex item samples configuration. +Flex pattern can be shared between ports. + +**Flex pattern and flow rule to match IPv4 version and 20 bytes length** + +:: + + # set flex_pattern is + testpmd> flow flex_item pattern 5 is 45FF + created pattern #5 + + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3 pattern is 5 / end actions mark id 1 / queue index 0 / end + Flow rule #0 created + +**Flex pattern and flow rule to match packets with source address 1.2.3.4** + +:: + + testpmd> flow flex_item pattern 2 spec 45000000000000000000000001020304 mask FF0000000000000000000000FFFFFFFF + created pattern #2 + + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3 pattern is 2 / end actions mark id 1 / queue index 0 / end + Flow rule #0 created