DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC] ethdev: introduce copy_field rte flow action
@ 2020-12-18  1:31 Alexander Kozyrev
  2021-01-05 22:12 ` Alexander Kozyrev
  2021-01-05 22:16 ` Thomas Monjalon
  0 siblings, 2 replies; 16+ messages in thread
From: Alexander Kozyrev @ 2020-12-18  1:31 UTC (permalink / raw)
  To: dev; +Cc: viacheslavo, orika, thomas, ferruh.yigit, andrew.rybchenko

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@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


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-01-10  6:50 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-18  1:31 [dpdk-dev] [RFC] ethdev: introduce copy_field rte flow action Alexander Kozyrev
2021-01-05 22:12 ` Alexander Kozyrev
2021-01-05 22:18   ` Thomas Monjalon
2021-01-05 22:16 ` Thomas Monjalon
2021-01-07 14:17   ` Alexander Kozyrev
2021-01-07 15:06     ` Thomas Monjalon
2021-01-07 15:10       ` Alexander Kozyrev
2021-01-07 15:17         ` Thomas Monjalon
2021-01-07 15:22           ` Alexander Kozyrev
2021-01-07 16:54             ` Thomas Monjalon
2021-01-07 16:57               ` Alexander Kozyrev
2021-01-07 17:05                 ` Thomas Monjalon
2021-01-07 20:14                   ` Alexander Kozyrev
2021-01-07 20:21                     ` Thomas Monjalon
2021-01-08 12:16                   ` Slava Ovsiienko
2021-01-10  6:50                     ` Ori Kam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).