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-boun...@dpdk.org> On Behalf Of Alexander Kozyrev > Sent: Thursday, December 17, 2020 20:31 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viachesl...@nvidia.com>; Ori Kam <or...@nvidia.com>; > NBU-Contact-Thomas Monjalon <tho...@monjalon.net>; > ferruh.yi...@intel.com; andrew.rybche...@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 <akozy...@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