From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 984DDA0A03; Mon, 18 Jan 2021 22:40:36 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 365A6140EBF; Mon, 18 Jan 2021 22:40:36 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id 94168140EBE for ; Mon, 18 Jan 2021 22:40:34 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from akozyrev@nvidia.com) with SMTP; 18 Jan 2021 23:40:29 +0200 Received: from nvidia.com (pegasus02.mtr.labs.mlnx [10.210.16.122]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10ILeS5m008977; Mon, 18 Jan 2021 23:40:29 +0200 From: Alexander Kozyrev To: dev@dpdk.org Cc: viacheslavo@nvidia.com, orika@nvidia.com, thomas@monjalon.net, ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru, jerinjacobk@gmail.com, ajit.khaparde@broadcom.com Date: Mon, 18 Jan 2021 21:40:25 +0000 Message-Id: <20210118214026.12009-2-akozyrev@nvidia.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20210118214026.12009-1-akozyrev@nvidia.com> References: <20210118161825.31516-1-akozyrev@nvidia.com> <20210118214026.12009-1-akozyrev@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v9 1/2] ethdev: introduce generic modify rte flow action 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" Implement the generic modify flow API to allow manipulations on an arbitrary header field (as well as mark, metadata or tag) using data from another field or a user-specified value. This generic modify mechanism removes the necessity to implement a separate RTE Flow action every time we need to modify a new packet field in the future. Supported operation are: - set: copy data from source to destination. - add: integer addition, stores the result in destination. - sub: integer subtraction, stores the result in destination. The field ID is used to specify the desired source/destination packet field in order to simplify the API for various encapsulation models. Specifying the packet field ID with the needed encapsulation level is able to quickly get a packet field for any inner packet header. Alternatively, the special ID (ITEM_START) can be used to point to the very beginning of a packet. This ID in conjunction with the offset parameter provides great flexibility to copy/modify any part of a packet as needed. The number of bits to use from a source as well as the offset can be be specified to allow a partial copy or dividing a big packet field into multiple small fields (e.g. copying 128 bits of IPv6 to 4 tags). An immediate value (or a pointer to it) can be specified instead of the level and the offset for the special FIELD_VALUE ID (or FIELD_POINTER). Can be used as a source only. Signed-off-by: Alexander Kozyrev Acked-by: Ori Kam Acked-by: Thomas Monjalon Acked-by: Ajit Khaparde --- v1: Initialy RTE_FLOW_ACTION_TYPE_COPY_ITEM v2: Renamed to RTE_FLOW_ACTION_TYPE_COPY_FIELD v3: Redesigned as RTE_FLOW_ACTION_TYPE_MODIFY_FIELD v4: Fixed typos in documentation, renamed mov operation to set v5: Added doxygen comments v6: Minor documentation edits. --- doc/guides/prog_guide/rte_flow.rst | 66 ++++++++++++++++++ doc/guides/rel_notes/release_21_02.rst | 8 +++ lib/librte_ethdev/rte_flow.c | 2 + lib/librte_ethdev/rte_flow.h | 93 +++++++++++++++++++++++++- 4 files changed, 168 insertions(+), 1 deletion(-) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 86b3444803..0b8c243fe1 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -2766,6 +2766,72 @@ The behaviour of the shared action defined by ``action`` argument of type | no properties | +---------------+ +Action: ``MODIFY_FIELD`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Modify ``dst`` field according to ``op`` selected (set, addition, +subtraction) with ``width`` bits of data from ``src`` field. + +Any arbitrary header field (as well as mark, metadata or tag values) +can be used as both source and destination fields as set by ``field``. +The immediate value ``RTE_FLOW_FIELD_VALUE`` (or a pointer to it +``RTE_FLOW_FIELD_POINTER``) is allowed as a source only. +``RTE_FLOW_FIELD_START`` is used to point to the beginning of a packet. + +``op`` selects the operation to perform on a destination field. +- ``set`` copies the data from ``src`` field to ``dst`` field. +- ``add`` adds together ``dst`` and ``src`` and stores the result into ``dst``. +- ``sub`` subtracts ``src`` from ``dst`` and stores the result into ``dst`` + +``width`` defines a number of bits to use from ``src`` field. + +``level`` is used to access any packet field on any encapsulation level +as well as any tag element in the tag array. +- ``0`` means the default behaviour. Depending on the packet type, it can +mean outermost, innermost or anything in between. +- ``1`` requests access to the outermost packet encapsulation level. +- ``2`` and subsequent values requests access to the specified packet +encapsulation level, from outermost to innermost (lower to higher values). +For the tag array (in case of multiple tags are supported and present) +``level`` translates directly into the array index. + +``offset`` specifies the number of bits to skip from a field's start. +That allows performing a partial copy of the needed part or to divide a big +packet field into multiple smaller fields. Alternatively, ``offset`` allows +going past the specified packet field boundary to copy a field to an +arbitrary place in a packet, essentially providing a way to copy any part of +a packet to any other part of it. + +``value`` sets an immediate value to be used as a source or points to a +location of the value in memory. It is used instead of ``level`` and ``offset`` +for ``RTE_FLOW_FIELD_VALUE`` and ``RTE_FLOW_FIELD_POINTER`` respectively. + +.. _table_rte_flow_action_modify_field: + +.. table:: MODIFY_FIELD + + +-----------------------------------------+ + | Field | Value | + +===============+=========================+ + | ``op`` | operation to perform | + | ``dst`` | destination field | + | ``src`` | source field | + | ``width`` | number of bits to use | + +---------------+-------------------------+ + +.. _table_rte_flow_action_modify_data: + +.. table:: destination/source field definition + + +--------------------------------------------------------------------------+ + | Field | Value | + +===============+==========================================================+ + | ``field`` | ID: packet field, mark, meta, tag, immediate, pointer | + | ``level`` | encapsulation level of a packet field or tag array index | + | ``offset`` | number of bits to skip at the beginning | + | ``value`` | immediate value or a pointer to this value | + +---------------+----------------------------------------------------------+ + Negative types ~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst index 3bb0b9a9ed..bb3cccd2e3 100644 --- a/doc/guides/rel_notes/release_21_02.rst +++ b/doc/guides/rel_notes/release_21_02.rst @@ -55,6 +55,14 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added support of modify field action in the flow API.** + + Added modify action support to perform various operations on + any arbitrary header field (as well as mark, metadata or tag values): + ``RTE_FLOW_ACTION_TYPE_MODIFY_FIELD``. + supported operations are: overwriting a field with the content from + another field, addition and subtraction using an immediate value. + * **Updated Broadcom bnxt driver.** Updated the Broadcom bnxt driver with fixes and improvements, including: diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index a06f64c271..9dd051f3c2 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -176,6 +176,8 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)), MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)), MK_FLOW_ACTION(SAMPLE, sizeof(struct rte_flow_action_sample)), + MK_FLOW_ACTION(MODIFY_FIELD, + sizeof(struct rte_flow_action_modify_field)), /** * Shared action represented as handle of type * (struct rte_flow_shared action *) stored in conf field (see diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 0977a78270..d63fd79e1a 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -2198,6 +2198,17 @@ enum rte_flow_action_type { * struct rte_flow_shared_action). */ RTE_FLOW_ACTION_TYPE_SHARED, + + /** + * Modify a packet header field, tag, mark or metadata. + * + * Allow the modification of an arbitrary header field via + * set, add and sub operations or copying its content into + * tag, meta or mark for future processing. + * + * See struct rte_flow_action_modify_field. + */ + RTE_FLOW_ACTION_TYPE_MODIFY_FIELD, }; /** @@ -2777,7 +2788,6 @@ struct rte_flow_action_set_dscp { uint8_t dscp; }; - /** * RTE_FLOW_ACTION_TYPE_SHARED * @@ -2791,6 +2801,87 @@ struct rte_flow_action_set_dscp { */ struct rte_flow_shared_action; +/** + * Field IDs for MODIFY_FIELD action. + */ +enum rte_flow_field_id { + RTE_FLOW_FIELD_START = 0, /**< Start of a packet. */ + RTE_FLOW_FIELD_MAC_DST, + RTE_FLOW_FIELD_MAC_SRC, + RTE_FLOW_FIELD_VLAN_TYPE, + RTE_FLOW_FIELD_VLAN_ID, + RTE_FLOW_FIELD_MAC_TYPE, + RTE_FLOW_FIELD_IPV4_DSCP, + RTE_FLOW_FIELD_IPV4_TTL, + RTE_FLOW_FIELD_IPV4_SRC, + RTE_FLOW_FIELD_IPV4_DST, + RTE_FLOW_FIELD_IPV6_HOPLIMIT, + RTE_FLOW_FIELD_IPV6_SRC, + RTE_FLOW_FIELD_IPV6_DST, + RTE_FLOW_FIELD_TCP_PORT_SRC, + RTE_FLOW_FIELD_TCP_PORT_DST, + RTE_FLOW_FIELD_TCP_SEQ_NUM, + RTE_FLOW_FIELD_TCP_ACK_NUM, + RTE_FLOW_FIELD_TCP_FLAGS, + RTE_FLOW_FIELD_UDP_PORT_SRC, + RTE_FLOW_FIELD_UDP_PORT_DST, + RTE_FLOW_FIELD_VXLAN_VNI, + RTE_FLOW_FIELD_GENEVE_VNI, + RTE_FLOW_FIELD_GTP_TEID, + RTE_FLOW_FIELD_TAG, + RTE_FLOW_FIELD_MARK, + RTE_FLOW_FIELD_META, + RTE_FLOW_FIELD_POINTER, /**< Memory pointer. */ + RTE_FLOW_FIELD_VALUE, /**< Immediate value. */ +}; + +/** + * Field description for MODIFY_FIELD action. + */ +struct rte_flow_action_modify_data { + enum rte_flow_field_id field; /**< Field or memory type ID. */ + RTE_STD_C11 + union { + struct { + /**< Encapsulation level or tag index. */ + uint32_t level; + /**< Number of bits to skip from a field. */ + uint32_t offset; + }; + /** + * Immediate value for RTE_FLOW_FIELD_VALUE or + * memory address for RTE_FLOW_FIELD_POINTER. + */ + uint64_t value; + }; +}; + +/** + * Operation types for MODIFY_FIELD action. + */ +enum rte_flow_modify_op { + RTE_FLOW_MODIFY_SET = 0, /**< Set a new value. */ + RTE_FLOW_MODIFY_ADD, /**< Add a value to a field. */ + RTE_FLOW_MODIFY_SUB, /**< Subtract a value from a field. */ +}; + +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_MODIFY_FIELD + * + * Modify a destination header field according to the specified + * operation. Another packet field can be used as a source as well + * as tag, mark, metadata, immediate value or a pointer to it. + */ +struct rte_flow_action_modify_field { + enum rte_flow_modify_op operation; /**< Operation to perform. */ + struct rte_flow_action_modify_data dst; /**< Destination field. */ + struct rte_flow_action_modify_data src; /**< Source field. */ + uint32_t width; /**< Number of bits to use from a source field. */ +}; + /* Mbuf dynamic field offset for metadata. */ extern int32_t rte_flow_dynf_metadata_offs; -- 2.24.1