[dpdk-dev] [RFC] ethdev: introduce copy_field rte flow action

Alexander Kozyrev akozyrev at nvidia.com
Tue Jan 5 23:12:48 CET 2021


Happy New Year Gentlemen, would you mind to share your thought on the proposed changes?
I was thinking about renaming it to more general "copy item" to cover all packet fields, tags  and metadata.
Other than that it is ready for a formal patch integration in my opinion if there are no objections. Please advise.

Regards,
Alex

> -----Original Message-----
> From: dev <dev-bounces at dpdk.org> On Behalf Of Alexander Kozyrev
> Sent: Thursday, December 17, 2020 20:31
> To: dev at dpdk.org
> Cc: Slava Ovsiienko <viacheslavo at nvidia.com>; Ori Kam <orika at nvidia.com>;
> NBU-Contact-Thomas Monjalon <thomas at monjalon.net>;
> ferruh.yigit at intel.com; andrew.rybchenko at oktetlabs.ru
> Subject: [dpdk-dev] [RFC] ethdev: introduce copy_field rte flow action
> 
> RTE Flows API lacks the ability to save an arbitrary header field in
> order to use it later for advanced packet manipulations. Examples
> include the usage of VxLAN ID after the packet is decapsulated or
> storing this ID inside the packet payload itself or swapping an
> arbitrary inner and outer packet fields.
> 
> The idea is to allow a copy of a specified number of bits form any
> packet header field into another header field:
> RTE_FLOW_ACTION_TYPE_COPY_FIELD with the structure defined below.
> 
> struct rte_flow_action_copy_field {
> 	struct rte_flow_action_copy_data dest;
> 	struct rte_flow_action_copy_data src;
> 	uint16_t width;
> };
> 
> Arbitrary header field (as well as mark, metadata or tag values) can be
> used as both source and destination fields. This way we can save an
> arbitrary header field by copying its value to a tag/mark/metadata or
> copy it into another header field directly. tag/mark/metadata can also
> be used as a value to be stored in an arbitrary packet header field.
> 
> struct rte_flow_action_copy_data {
> 	enum rte_flow_field_id field;
> 	uint16_t index;
> 	uint16_t offset;
> };
> 
> The rte_flow_field_id specifies the particular packet field (or
> tag/mark/metadata) to be used as a copy source or destination.
> The index gives access to inner packet headers or elements in the tags
> array. The offset allows to copy a packet field value into the payload.
> 
> It is proposed to implement the "set copy_field" command to store all
> the required parameters and then to use this template by specifying the
> index of the needed copy action. For example, to modify the GTP tunnel
> ID after the packet is encapsulated following testpmd rules are used:
> 
>       set copy_field width 32 src field tag index 1 offset 0
>         dst field teid index 0 offset 0
>       flow create 0 ingress pattern ... / end
>         raw_decap index 1 / raw_encap index 2 /
>         copy_field index 1 / end
> 
> A more generic mechanism to overwrite an arbitrary header field may be
> introduced to the RTE flows implementation later:
> RTE_FLOW_ACTION_TYPE_SET_FIELD with the structure defined below.
> 
> struct rte_flow_action_copy_field {
> 	struct rte_flow_action_copy_data dest;
> 	uint8_t *data;
> 	uint16_t width;
> };
> 
> This way we can have the generic way to specify an immediate value and
> use it as data for any packet header field instead of having separate
> RTE Flow action for each of the packet fields. Deprecation notice may
> be issued to RTE_FLOW_ACTION_TYPE_SET_XXX actions after the unified
> method of setting a value to any packet field is implemented.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev at nvidia.com>
> ---
>  lib/librte_ethdev/rte_flow.c |  1 +
>  lib/librte_ethdev/rte_flow.h | 59 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
> index a06f64c271..c3154a29e2 100644
> --- a/lib/librte_ethdev/rte_flow.c
> +++ b/lib/librte_ethdev/rte_flow.c
> @@ -176,6 +176,7 @@ 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(COPY_FIELD, sizeof(struct
> rte_flow_action_copy_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..8f1798487c 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -2198,6 +2198,16 @@ enum rte_flow_action_type {
>  	 * struct rte_flow_shared_action).
>  	 */
>  	RTE_FLOW_ACTION_TYPE_SHARED,
> +
> +	/**
> +	 * Copy a packet header field, tag, mark or metadata.
> +	 *
> +	 * Allow saving an arbitrary header field by copying its value
> +	 * to a tag/mark/metadata or copy it into another header field.
> +	 *
> +	 * See struct rte_flow_action_copy_field.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_COPY_FIELD,
>  };
> 
>  /**
> @@ -2791,6 +2801,55 @@ struct rte_flow_action_set_dscp {
>   */
>  struct rte_flow_shared_action;
> 
> +enum rte_flow_field_id {
> +	RTE_FLOW_FIELD_NONE = 0,
> +	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,
> +};
> +
> +struct rte_flow_action_copy_data {
> +	enum rte_flow_field_id field;
> +	uint16_t index;
> +	uint16_t offset;
> +};
> +
> +/**
> + * RTE_FLOW_ACTION_TYPE_COPY_FIELD
> + *
> + * Copies a specified number of bits from a source header field
> + * to a destination header field. Tag, mark or metadata can also
> + * be used as a source/destination to allow saving/overwriting
> + * an arbituary header field with a user-specified value.
> + */
> +struct rte_flow_action_copy_field {
> +	struct rte_flow_action_copy_data dest;
> +	struct rte_flow_action_copy_data src;
> +	uint16_t width;
> +};
> +
>  /* Mbuf dynamic field offset for metadata. */
>  extern int32_t rte_flow_dynf_metadata_offs;
> 
> --
> 2.24.1



More information about the dev mailing list