ethdev: introduce generic modify flow action
authorAlexander Kozyrev <akozyrev@nvidia.com>
Mon, 18 Jan 2021 21:40:25 +0000 (21:40 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 19 Jan 2021 02:30:32 +0000 (03:30 +0100)
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 <akozyrev@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
doc/guides/prog_guide/rte_flow.rst
doc/guides/rel_notes/release_21_02.rst
lib/librte_ethdev/rte_flow.c
lib/librte_ethdev/rte_flow.h

index 86b3444..0b8c243 100644 (file)
@@ -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
 ~~~~~~~~~~~~~~
 
index 55aba13..3350fa7 100644 (file)
@@ -64,6 +64,14 @@ New Features
 
   Added support for matching and raw encap/decap of GENEVE TLV option.
 
+* **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:
index 2af7d96..241af6c 100644 (file)
@@ -177,6 +177,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
index 151e4d2..46e8ee7 100644 (file)
@@ -2225,6 +2225,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,
 };
 
 /**
@@ -2804,7 +2815,6 @@ struct rte_flow_action_set_dscp {
        uint8_t dscp;
 };
 
-
 /**
  * RTE_FLOW_ACTION_TYPE_SHARED
  *
@@ -2818,6 +2828,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;