DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC PATCH] ethdev: clarify flow attribute and action port ID semantics
@ 2021-09-07 12:51 Ivan Malov
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
  0 siblings, 2 replies; 161+ messages in thread
From: Ivan Malov @ 2021-09-07 12:51 UTC (permalink / raw)
  To: dev; +Cc: Ori Kam, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko

Problems:

1) Existing item PORT_ID and action PORT_ID are ambiguous because
   one can consider the port in question as either an ethdev or
   an embedded switch entity wired to it, as per the use case,
   which is not expressed clearly in code and documentation.

2) Attributes "ingress" and "egress" may not make sense in flows
   with "transfer" attribute for some PMDs. Furthermore, such
   PMDs may face a related problem (see below).

3) A PMD may not be able to handle "transfer" rules on all ethdevs
   it serves. It may have only one (admin) ethdev capable of that.
   Applications should be able to take this into account and
   submit "transfer" rules on that specific ethdev. However,
   meaning of attributes "ingress" and "egress" might be
   skewed in this case as the ethdev used to make flow
   API calls is just a technical entry point.

In order to solve problem (1)¸ one should recognise the existence
of two major application models: traffic consumer / generator and
a vSwitch / forwarder. To the latter, ethdevs used to perform
Rx / Tx burst calls are simply vSwitch ports. Requesting HW
offloads on these ports implies referring to e-switch ports
that correspond to them at the lowest, e-switch, level.
This way, suggested terminology is clear and concise.

The patch suggests using item / action PORT_ID sub-variants to
disambiguate the meaning. In order to avoid breaking existing
behaviour in Open vSwitch DPDK offload, the sub-variant for
e-switch port is declared with enum value of zero.

In order to solve problems (2) and (3), one needs to recognise
the existence of two paradigms of handling "transfer" rules in
PMDs. If the given PMD needs to "proxy" handling of "transfer"
rules via an admin ethdev, this must not be done implicitly
as the application must know the true ethdev responsible
for handling the flows in order to avoid detaching it
before all "transfer" rules get properly dismantled.

The patch suggests to use a generic helper to let applications
discover the paradigm in use and, if need be, communicate
flow rules through the discovered "proxy" ethdev.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
This proposal is an alternative to previously suggested RFCs, [1] and [2].
It covers several related problems and suggests clear API contract to
let vSwitch applications use item PORT_ID and action PORT_ID to refer
to e-switch ports thus preserving existing sense.

[1] https://patches.dpdk.org/project/dpdk/patch/20210601111420.5549-1-ivan.malov@oktetlabs.ru/
[2] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/
---
 lib/ethdev/rte_flow.h | 140 ++++++++++++++++++++++++++++++++----------
 1 file changed, 107 insertions(+), 33 deletions(-)

diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 70f455d47d..bf2b5e752c 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -82,22 +82,32 @@ struct rte_flow_attr {
 	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
 	uint32_t egress:1; /**< Rule applies to egress traffic. */
 	/**
-	 * Instead of simply matching the properties of traffic as it would
-	 * appear on a given DPDK port ID, enabling this attribute transfers
-	 * a flow rule to the lowest possible level of any device endpoints
-	 * found in the pattern.
-	 *
-	 * When supported, this effectively enables an application to
-	 * re-route traffic not necessarily intended for it (e.g. coming
-	 * from or addressed to different physical ports, VFs or
-	 * applications) at the device level.
-	 *
-	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
-	 *
-	 * When transferring flow rules, ingress and egress attributes keep
-	 * their original meaning, as if processing traffic emitted or
-	 * received by the application.
+	 * This "transfers" the rule from the ethdev level to the embedded
+	 * switch (e-switch) level, where it's possible to match traffic
+	 * not necessarily going to the ethdev where the flow is created
+	 * and redirect it to endpoints otherwise not necessarily
+	 * accessible from rules having no such attribute.
+	 *
+	 * Applications willing to use attribute "transfer" should detect its
+	 * paradigm implemented inside the PMD. The paradigms are as follows:
+	 *
+	 * - The PMD supports handling "transfer" flow rules on any ethdevs
+	 *   it serves. With this paradigm, rte_flow_pick_transfer_proxy()
+	 *   call returns (-ENOTSUP) for all ethdevs backed by the PMD.
+	 *   Attributes "ingress" and "egress" are valid and preserve
+	 *   their original meaning, at application standpoint. Also,
+	 *   these attributes typically set some implicit filtering.
+	 *
+	 * - The PMD only supports handling "transfer" flow rules on some
+	 *   specific ethdev pointed out by rte_flow_pick_transfer_proxy().
+	 *   Typically, it's an admin PF ethdev backing a group of VF
+	 *   representor ethdevs. In this case, attributes "ingress"
+	 *   and "egress" cannot maintain their original meaning as
+	 *   the ethdev used to handle "transfer" flow rules is
+	 *   just a technical entry point and does not mean any
+	 *   implicit filtering. Attribute "egress" is rejected,
+	 *   and "ingress" (redundant) means traffic ingressing
+	 *   the embedded switch from any of its endpoints.
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
@@ -191,8 +201,9 @@ enum rte_flow_item_type {
 	/**
 	 * [META]
 	 *
-	 * Matches traffic originating from (ingress) or going to (egress) a
-	 * given DPDK port ID.
+	 * Matches traffic originating from (ingress) or going to (egress) the
+	 * port which, depending on the item sub-variant, is the given ethdev
+	 * or the opposite end of the "wire" attached to this ethdev.
 	 *
 	 * See struct rte_flow_item_port_id.
 	 */
@@ -679,29 +690,61 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 };
 #endif
 
+/** Port types for use with item PORT_ID and action PORT_ID */
+enum rte_flow_item_port_id_type {
+	/**
+	 * The port in question is an embedded switch entity connected
+	 * to or represented by the given ethdev / vSwitch port.
+	 *
+	 * +--------------------------+---------------------------+
+	 * |  Ethdev / vSwitch Port   |   Embedded Switch Entity  |
+	 * +--------------------------+---------------------------+
+	 * |         PF / VF         <->       Network Port       |
+	 * +------------------------------------------------------+
+	 * |   PF / VF Representor   <->      PF / VF Itself      |
+	 * +------------------------------------------------------+
+	 */
+	RTE_FLOW_PORT_TYPE_ESWITCH = 0,
+
+	/**
+	 * The port in question is an ethdev or, synonymously,
+	 * a DPDK-backed vSwitch port.
+	 */
+	RTE_FLOW_PORT_TYPE_ETHDEV,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_PORT_ID
  *
- * Matches traffic originating from (ingress) or going to (egress) a given
- * DPDK port ID.
+ * Matches traffic originating from (ingress) or going to (egress) the
+ * port which, depending on the item sub-variant, is the given ethdev
+ * or the opposite end of the "wire" attached to this ethdev.
  *
- * Normally only supported if the port ID in question is known by the
- * underlying PMD and related to the device the flow rule is created
- * against.
+ * Typically, the ethdev referring to the port in question must be served
+ * by the same PMD as that of the ethdev used to create the flow rule.
+ * Also, the port must normally belong to the same physical board.
  *
- * This must not be confused with @p PHY_PORT which refers to the physical
- * port of a device, whereas @p PORT_ID refers to a struct rte_eth_dev
- * object on the application side (also known as "port representor"
- * depending on the kind of underlying device).
+ * This must not be confused with item @p PHY_PORT
+ * which refers specifically to a physical port.
  */
+RTE_STD_C11
 struct rte_flow_item_port_id {
-	uint32_t id; /**< DPDK port ID. */
+	/** Synonymous defines for ethdev ID property */
+	union {
+		/** Ethdev (vSwitch port) ID */
+		uint32_t ethdev_id;
+		/** Compatibility alias to avoid breaking legacy applications */
+		uint32_t id;
+	};
+
+	/** Port type (item sub-variant) */
+	enum rte_flow_item_port_id_type type;
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_PORT_ID. */
 #ifndef __cplusplus
 static const struct rte_flow_item_port_id rte_flow_item_port_id_mask = {
-	.id = 0xffffffff,
+	.ethdev_id = 0xffffffff,
 };
 #endif
 
@@ -1976,7 +2019,8 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
-	 * Directs matching traffic to a given DPDK port ID.
+	 * Depending on the port type, directs matching traffic either to the
+	 * given ethdev or to the opposite end of the "wire" attached to it.
 	 *
 	 * See struct rte_flow_action_port_id.
 	 */
@@ -2635,14 +2679,26 @@ struct rte_flow_action_phy_port {
 /**
  * RTE_FLOW_ACTION_TYPE_PORT_ID
  *
- * Directs matching traffic to a given DPDK port ID.
+ * Depending on the port type, directs matching traffic either to the
+ * given ethdev or to the opposite end of the "wire" attached to it.
  *
  * @see RTE_FLOW_ITEM_TYPE_PORT_ID
  */
+RTE_STD_C11
 struct rte_flow_action_port_id {
-	uint32_t original:1; /**< Use original DPDK port ID if possible. */
+	uint32_t original:1; /**< Use original ethdev ID if possible. */
 	uint32_t reserved:31; /**< Reserved, must be zero. */
-	uint32_t id; /**< DPDK port ID. */
+
+	/** Synonymous defines for ethdev ID property */
+	union {
+		/** Ethdev (vSwitch port) ID */
+		uint32_t ethdev_id;
+		/** Compatibility alias to avoid breaking legacy applications */
+		uint32_t id;
+	};
+
+	/** Port type (action sub-variant) */
+	enum rte_flow_item_port_id_type type;
 };
 
 /**
@@ -4288,6 +4344,24 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 			     struct rte_flow_item *items,
 			     uint32_t num_of_items,
 			     struct rte_flow_error *error);
+
+/**
+ * Locate the "proxy" ethdev to handle "transfer" flow rules
+ * for the given ethdev. If the API returns (-ENOTSUP), the
+ * caller should assume that no "proxying" is required.
+ *
+ * @param port_id
+ *   Ethdev ID that potentially needs a "proxy"
+ * @param[out] proxy_port_id
+ *   The "proxy" port through which "transfer" rules must be communicated
+ *
+ * @return
+ *   0 on success, a negative error code otherwise
+ */
+__rte_experimental
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id,
+			     uint16_t *proxy_port_id);
 #ifdef __cplusplus
 }
 #endif
-- 
2.20.1


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

* [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API
  2021-09-07 12:51 [dpdk-dev] [RFC PATCH] ethdev: clarify flow attribute and action port ID semantics Ivan Malov
@ 2021-10-01 13:47 ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to " Andrew Rybchenko
                     ` (17 more replies)
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
  1 sibling, 18 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

The patch series provides a number of changesets which are supposed to
orderly address transfer flow API problems: hard to understand,
ambiguous definition, different implemantation of the same actions
by different PMDs etc.

As a starting point, items and actions ETHDEV, ESWITCH_PORT are added
and the corresponding diagrams are placed in relevant documentation
sections to demonstrate the intended meaning of the new primitives.
The use of the new items effectively defines traffic direction in
a clear and concise manner. On this ground, the use of attributes
"ingress" and "egress" in "transfer" flows is deprecated.

At the same time, the patch series deprecates the use of items and
actions PF, VF and PHY_PORT. They’re hard-to-use by applications as they
suggest that applications have some extra knowledge of the underlying HW.
Items and actions PORT_ID are also deprecated on similar grounds: they
are ambiguous (which attendees of the said gathering can attest to) as
they do not specify precisely whether the target port is an ethdev or
an e-switch port connected to that ethdev.

The patch series address deprecation notices about PORT_ID semantics,
ingress/egress attributes and implicit filtering in the case of transfer
flow rules.

The patch series is the next step in accordance with ideas previously
shared in RFC [1]. It supersedes patches [2] and [3] which should be
discarded since they are step in different direction.

The patch series updates PMDs which support PORT_ID item and action
to support added replacements except:
 - PORT_ID item in the case of net/mlx5 since code is really complicated
   there and it would be better if it is updated by the maintainer and
   tested appropriately;
 - ESWITCH_PORT action in the case of net/sfc since required code
   depends on port representors patch series (patches exist but should
   be submitted in a right order to apply cleanly and build successfully
   by automation)

Patches for transfer proxy mentioned in RFC [1] are in progress.

[1] https://patches.dpdk.org/project/dpdk/patch/20210907125157.3843-1-ivan.malov@oktetlabs.ru/
[2] https://patches.dpdk.org/project/dpdk/patch/20210901151104.3923889-1-andrew.rybchenko@oktetlabs.ru/
[3] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/

Andrew Rybchenko (6):
  net/bnxt: support ethdev and E-Switch port flow items
  net/bnxt: support ethdev and E-Switch port flow actions
  net/enic: support ethdev and E-Switch port flow actions
  net/mlx5: support E-Switch port flow action
  net/octeontx2: support ethdev flow action
  net/sfc: support ethdev flow item

Ivan Malov (6):
  ethdev: add ethdev item to flow API
  ethdev: add eswitch port item to flow API
  ethdev: add ethdev action to flow API
  ethdev: add eswitch port action to flow API
  ethdev: deprecate hard-to-use or ambiguous items and actions
  ethdev: deprecate direction attributes in transfer flows

 app/test-pmd/cmdline_flow.c                   | 102 +++++++++++
 doc/guides/prog_guide/rte_flow.rst            | 157 +++++++++++++++--
 doc/guides/rel_notes/deprecation.rst          |  18 +-
 doc/guides/rel_notes/release_21_11.rst        |   9 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst   |  16 ++
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |  22 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 164 +++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  18 +-
 drivers/net/enic/enic_fm_flow.c               |  93 ++++++++--
 drivers/net/mlx5/mlx5_flow_dv.c               |  62 +++++--
 drivers/net/octeontx2/otx2_flow_parse.c       |  16 +-
 drivers/net/sfc/sfc_mae.c                     |  72 ++++++++
 lib/ethdev/rte_flow.c                         |   4 +
 lib/ethdev/rte_flow.h                         | 157 ++++++++++++++++-
 14 files changed, 793 insertions(+), 117 deletions(-)

-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-03 11:52     ` Ori Kam
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port " Andrew Rybchenko
                     ` (16 subsequent siblings)
  17 siblings, 1 reply; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Xiaoyun Li, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

For use with "transfer" flows. Supposed to match traffic transmitted
by the DPDK application via the specified ethdev, at e-switch level.

Must not be combined with attributes "ingress" / "egress".

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 27 ++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 35 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 27 ++++++++++++++++
 6 files changed, 96 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index bb22294dd3..e05b0d83d2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -306,6 +306,8 @@ enum index {
 	ITEM_POL_PORT,
 	ITEM_POL_METER,
 	ITEM_POL_POLICY,
+	ITEM_ETHDEV,
+	ITEM_ETHDEV_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
+	ITEM_ETHDEV,
 	END_SET,
 	ZERO,
 };
@@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_ethdev[] = {
+	ITEM_ETHDEV_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
 	},
+	[ITEM_ETHDEV] = {
+		.name = "ethdev",
+		.help = "match traffic at e-switch going from (sent by) the given ethdev",
+		.priv = PRIV_ITEM(ETHDEV,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_ethdev),
+		.call = parse_vc,
+	},
+	[ITEM_ETHDEV_ID] = {
+		.name = "id",
+		.help = "ethdev ID",
+		.next = NEXT(item_ethdev, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_ETHDEV:
+		mask = &rte_flow_item_ethdev_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2b42d5ec8c..ab628d9139 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,41 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``ETHDEV``
+^^^^^^^^^^^^^^^^
+
+Matches traffic at e-switch going from (sent by) the given ethdev.
+
+::
+
+   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) >>>> [] ~~~~ (External Port)
+   *    :  SW                 :   Logical                    Net / Guest :
+   *    :                     :                                          :
+   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
+   *
+   *    [] shows the effective ("transfer") standpoint, the match engine;
+   *    >> shows the traffic flow in question hitting the match engine;
+   *    ~~ shows logical interconnects between the endpoints.
+
+Use this with attribute **transfer**. Attributes **ingress** and
+**egress** (`Attribute: Traffic direction`_) must not be used.
+
+- Default ``mask`` provides exact match behaviour.
+
+.. _table_rte_flow_item_ethdev:
+
+.. table:: ETHDEV
+
+   +----------+----------+---------------------------+
+   | Field    | Subfield | Value                     |
+   +==========+==========+===========================+
+   | ``spec`` | ``id``   | ethdev ID                 |
+   +----------+----------+---------------------------+
+   | ``last`` | ``id``   | upper range value         |
+   +----------+----------+---------------------------+
+   | ``mask`` | ``id``   | zeroed for wildcard match |
+   +----------+----------+---------------------------+
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index f099b1cca2..91631adb4e 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,8 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added item ``ETHDEV`` to flow API.
+
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
   well as PMD to check whether the device is valid or not.
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index bbef706374..6d5de5457c 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3820,6 +3820,10 @@ This section lists supported pattern items and their attributes, if any.
 
 - ``conntrack``: match conntrack state.
 
+- ``ethdev``: match traffic at e-switch going from (sent by) the given ethdev
+
+  - ``id {unsigned}``: ethdev ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..84eb61cb6c 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -100,6 +100,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
+	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 7b1ed7f110..880502098e 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -574,6 +574,15 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic at e-switch going from (sent by) the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_ETHDEV,
 };
 
 /**
@@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev ID for use with items which are as follows:
+ * RTE_FLOW_ITEM_TYPE_ETHDEV.
+ */
+struct rte_flow_item_ethdev {
+	uint16_t id; /**< Ethdev ID */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_ETHDEV */
+#ifndef __cplusplus
+static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
+	.id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-03 12:40     ` Ori Kam
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 03/12] ethdev: add ethdev action " Andrew Rybchenko
                     ` (15 subsequent siblings)
  17 siblings, 1 reply; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Xiaoyun Li, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

For use with "transfer" flows. Supposed to match traffic entering
the e-switch from the external world (network, guests) via the
port which is logically connected with the given ethdev.

Must not be combined with attributes "ingress" / "egress".

This item is meant to use the same structure as ethdev item.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 27 +++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 12 ++++++++-
 6 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e05b0d83d2..188d0ee39d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -308,6 +308,8 @@ enum index {
 	ITEM_POL_POLICY,
 	ITEM_ETHDEV,
 	ITEM_ETHDEV_ID,
+	ITEM_ESWITCH_PORT,
+	ITEM_ESWITCH_PORT_ETHDEV_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
 	ITEM_ETHDEV,
+	ITEM_ESWITCH_PORT,
 	END_SET,
 	ZERO,
 };
@@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
 	ZERO,
 };
 
+static const enum index item_eswitch_port[] = {
+	ITEM_ESWITCH_PORT_ETHDEV_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
 	},
+	[ITEM_ESWITCH_PORT] = {
+		.name = "eswitch_port",
+		.help = "match traffic at e-switch going from the external port associated with the given ethdev",
+		.priv = PRIV_ITEM(ESWITCH_PORT,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_eswitch_port),
+		.call = parse_vc,
+	},
+	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
+		.name = "ethdev_id",
+		.help = "ethdev ID",
+		.next = NEXT(item_eswitch_port, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_ETHDEV:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
+		mask = &rte_flow_item_ethdev_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index ab628d9139..292bb42410 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1460,6 +1460,28 @@ Use this with attribute **transfer**. Attributes **ingress** and
    | ``mask`` | ``id``   | zeroed for wildcard match |
    +----------+----------+---------------------------+
 
+Item: ``ESWITCH_PORT``
+^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic at e-switch going from the external port associated
+with the given ethdev, for example, traffic from net. port or guest.
+
+::
+
+   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External Port)
+   *    :  SW                 :   Logical                    Net / Guest :
+   *    :                     :                                          :
+   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
+   *
+   *    [] shows the effective ("transfer") standpoint, the match engine;
+   *    << shows the traffic flow in question hitting the match engine;
+   *    ~~ shows logical interconnects between the endpoints.
+
+Use this with attribute **transfer**. Attributes **ingress** and
+**egress** (`Attribute: Traffic direction`_) must not be used.
+
+This item is meant to use the same structure as `Item: ETHDEV`_.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 91631adb4e..b2b27de3f0 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,7 +167,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added item ``ETHDEV`` to flow API.
+* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
 
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6d5de5457c..9a5c2a2d82 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3824,6 +3824,10 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``id {unsigned}``: ethdev ID
 
+- ``eswitch_port``: match traffic at e-switch going from the external port associated with the given ethdev
+
+  - ``ethdev_id {unsigned}``: ethdev ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 84eb61cb6c..c4aea5625f 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -101,6 +101,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 880502098e..1a7e4c2e3d 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -583,6 +583,16 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_ETHDEV,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic at e-switch going from the external port associated
+	 * with the given ethdev, for example, traffic from net. port or guest.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
 };
 
 /**
@@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev ID for use with items which are as follows:
- * RTE_FLOW_ITEM_TYPE_ETHDEV.
+ * RTE_FLOW_ITEM_TYPE_ETHDEV, RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
  */
 struct rte_flow_item_ethdev {
 	uint16_t id; /**< Ethdev ID */
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 03/12] ethdev: add ethdev action to flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to " Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 04/12] ethdev: add eswitch port " Andrew Rybchenko
                     ` (14 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Xiaoyun Li, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

For use with "transfer" flows. Supposed to direct matching traffic
to the specified ethdev (to the application), at e-switch level.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 24 ++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 31 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 18 ++++++++++++
 6 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 188d0ee39d..feaa61349e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -460,6 +460,8 @@ enum index {
 	ACTION_POL_G,
 	ACTION_POL_Y,
 	ACTION_POL_R,
+	ACTION_ETHDEV,
+	ACTION_ETHDEV_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1452,6 +1454,7 @@ static const enum index next_action[] = {
 	ACTION_MODIFY_FIELD,
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
+	ACTION_ETHDEV,
 	ZERO,
 };
 
@@ -1733,6 +1736,12 @@ static const enum index action_update_conntrack[] = {
 	ZERO,
 };
 
+static const enum index action_ethdev[] = {
+	ACTION_ETHDEV_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4820,6 +4829,21 @@ static const struct token token_list[] = {
 		.next = NEXT(action_update_conntrack),
 		.call = parse_vc_action_conntrack_update,
 	},
+	[ACTION_ETHDEV] = {
+		.name = "ethdev",
+		.help = "at e-switch level, direct matching packets to the given ethdev",
+		.priv = PRIV_ACTION(ETHDEV,
+				    sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_ethdev),
+		.call = parse_vc,
+	},
+	[ACTION_ETHDEV_ID] = {
+		.name = "id",
+		.help = "ethdev ID",
+		.next = NEXT(action_ethdev, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 292bb42410..f633973181 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3056,6 +3056,37 @@ which is set in the packet meta-data (i.e. struct ``rte_mbuf::sched::color``)
    | ``meter_color`` | Packet color |
    +-----------------+--------------+
 
+Action: ``ETHDEV``
+^^^^^^^^^^^^^^^^^^
+At e-switch level, directs matching packets to the given ethdev.
+
+These packets can originate from any of e-switch ports, not
+just the ones associated with the given ethdev. They come
+from the match engine in general, as per some criteria.
+
+::
+
+   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) <<<< [] ~~~~ (External Port)
+   *    :  SW                 :   Logical                    Net / Guest :
+   *    :                     :                                          :
+   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
+   *
+   *    [] shows the effective ("transfer") standpoint, the action engine;
+   *    << shows the traffic flow in question established by the action;
+   *    ~~ shows logical interconnects between the endpoints.
+
+See `Item: ETHDEV`_.
+
+.. _table_rte_flow_action_ethdev:
+
+.. table:: ETHDEV
+
+   +--------+-----------+
+   | Field  | Value     |
+   +========+===========+
+   | ``id`` | ethdev ID |
+   +--------+-----------+
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index b2b27de3f0..d431dc3804 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,7 +167,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
+* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` and action ``ETHDEV`` to flow API.
 
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 9a5c2a2d82..79126e2f10 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4103,6 +4103,10 @@ This section lists supported actions and their attributes, if any.
 
   - ``type {value}``: Set color type with specified value(green/yellow/red)
 
+- ``ethdev``: at e-switch level, direct matching packets to the given ethdev
+
+  - ``id {unsigned}``: ethdev ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index c4aea5625f..3cc84e2b43 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -191,6 +191,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	 */
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
+	MK_FLOW_ACTION(ETHDEV, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1a7e4c2e3d..3724ebee35 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2446,6 +2446,13 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_meter_color.
 	 */
 	RTE_FLOW_ACTION_TYPE_METER_COLOR,
+
+	/**
+	 * At e-switch level, directs matching packets to the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_ETHDEV,
 };
 
 /**
@@ -3205,6 +3212,17 @@ struct rte_flow_action_meter_color {
 	enum rte_color color; /**< Packet color. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev ID for use with actions which are as follows:
+ * RTE_FLOW_ACTION_TYPE_ETHDEV.
+ */
+struct rte_flow_action_ethdev {
+	uint16_t id; /**< Ethdev ID */
+};
+
 /**
  * Field IDs for MODIFY_FIELD action.
  */
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 04/12] ethdev: add eswitch port action to flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (2 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 03/12] ethdev: add ethdev action " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Andrew Rybchenko
                     ` (13 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Xiaoyun Li, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

For use with "transfer" flows. Supposed to direct matching traffic
at e-switch level to the external world (network, guests) via the
port which is logically connected with the given ethdev.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 24 +++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 24 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 10 ++++++++-
 6 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index feaa61349e..57c7196866 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -462,6 +462,8 @@ enum index {
 	ACTION_POL_R,
 	ACTION_ETHDEV,
 	ACTION_ETHDEV_ID,
+	ACTION_ESWITCH_PORT,
+	ACTION_ESWITCH_PORT_ETHDEV_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1455,6 +1457,7 @@ static const enum index next_action[] = {
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
 	ACTION_ETHDEV,
+	ACTION_ESWITCH_PORT,
 	ZERO,
 };
 
@@ -1742,6 +1745,12 @@ static const enum index action_ethdev[] = {
 	ZERO,
 };
 
+static const enum index action_eswitch_port[] = {
+	ACTION_ESWITCH_PORT_ETHDEV_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4844,6 +4853,21 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_ESWITCH_PORT] = {
+		.name = "eswitch_port",
+		.help = "at e-switch level, direct matching packets to the external port associated with the given ethdev",
+		.priv = PRIV_ACTION(ESWITCH_PORT,
+				sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_eswitch_port),
+		.call = parse_vc,
+	},
+	[ACTION_ESWITCH_PORT_ETHDEV_ID] = {
+		.name = "ethdev_id",
+		.help = "ethdev ID",
+		.next = NEXT(action_eswitch_port, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index f633973181..22f7d327d2 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3087,6 +3087,30 @@ See `Item: ETHDEV`_.
    | ``id`` | ethdev ID |
    +--------+-----------+
 
+Action: ``ESWITCH_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^
+At e-switch level, directs matching packets to the external port
+associated with the given ethdev, that is, to net. port or guest.
+
+These packets can originate from any of e-switch ports, not
+just the ones associated with the given ethdev. They come
+from the match engine in general, as per some criteria.
+
+::
+
+   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] >>>> (External Port)
+   *    :  SW                 :   Logical                    Net / Guest :
+   *    :                     :                                          :
+   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
+   *
+   *    [] shows the effective ("transfer") standpoint, the action engine;
+   *    >> shows the traffic flow in question established by the action;
+   *    ~~ shows logical interconnects between the endpoints.
+
+See `Item: ESWITCH_PORT`_.
+
+This action is meant to use the same structure as `Action: ETHDEV`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index d431dc3804..4f4890c7df 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,7 +167,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` and action ``ETHDEV`` to flow API.
+* ethdev: Added items and actions ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
 
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 79126e2f10..88bd8e743d 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4107,6 +4107,10 @@ This section lists supported actions and their attributes, if any.
 
   - ``id {unsigned}``: ethdev ID
 
+- ``eswitch_port``: at e-switch level, direct matching packets to the external port associated with the given ethdev
+
+  - ``ethdev_id {unsigned}``: ethdev ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 3cc84e2b43..647bbf91ce 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -192,6 +192,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
 	MK_FLOW_ACTION(ETHDEV, sizeof(struct rte_flow_action_ethdev)),
+	MK_FLOW_ACTION(ESWITCH_PORT, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 3724ebee35..5d46b2350d 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2453,6 +2453,14 @@ enum rte_flow_action_type {
 	 * @see struct rte_flow_action_ethdev
 	 */
 	RTE_FLOW_ACTION_TYPE_ETHDEV,
+
+	/**
+	 * At e-switch level, directs matching packets to the external port
+	 * associated with the given ethdev, that is, to net. port or guest.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_ESWITCH_PORT,
 };
 
 /**
@@ -3217,7 +3225,7 @@ struct rte_flow_action_meter_color {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev ID for use with actions which are as follows:
- * RTE_FLOW_ACTION_TYPE_ETHDEV.
+ * RTE_FLOW_ACTION_TYPE_ETHDEV, RTE_FLOW_ACTION_TYPE_ESWITCH_PORT.
  */
 struct rte_flow_action_ethdev {
 	uint16_t id; /**< Ethdev ID */
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (3 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 04/12] ethdev: add eswitch port " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 06/12] ethdev: deprecate direction attributes in transfer flows Andrew Rybchenko
                     ` (12 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Ray Kinsella, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

PF, VF and PHY_PORT require that applications have extra
knowledge of the underlying HW and thus are hard to use.
Also, the corresponding items depend on the direction
attribute (ingress / egress), which complicates their
use in applications and interpretation in PMDs.

The concept of PORT_ID is ambiguous as it doesn't say whether
the port in question is an ethdev or the represented entity.

Items and actions ETHDEV, ESWITCH_PORT should be used instead.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 16 ++++++++
 doc/guides/rel_notes/deprecation.rst   |  9 ++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 53 ++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 22f7d327d2..a5db278e8d 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -504,6 +504,8 @@ Usage example, matching non-TCPv4 packets only:
 Item: ``PF``
 ^^^^^^^^^^^^
 
+This item is DEPRECATED. Consider: `Item: ETHDEV`_, `Item: ESWITCH_PORT`_.
+
 Matches traffic originating from (ingress) or going to (egress) the physical
 function of the current device.
 
@@ -531,6 +533,8 @@ the application and thus not associated with a DPDK port ID.
 Item: ``VF``
 ^^^^^^^^^^^^
 
+This item is DEPRECATED. Consider: `Item: ETHDEV`_, `Item: ESWITCH_PORT`_.
+
 Matches traffic originating from (ingress) or going to (egress) a given
 virtual function of the current device.
 
@@ -562,6 +566,8 @@ separate entities, should be addressed through their own DPDK port IDs.
 Item: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^
 
+This item is DEPRECATED. Consider: `Item: ETHDEV`_, `Item: ESWITCH_PORT`_.
+
 Matches traffic originating from (ingress) or going to (egress) a physical
 port of the underlying device.
 
@@ -596,6 +602,8 @@ associated with a port_id should be retrieved by other means.
 Item: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^
 
+This item is DEPRECATED. Consider: `Item: ETHDEV`_, `Item: ESWITCH_PORT`_.
+
 Matches traffic originating from (ingress) or going to (egress) a given DPDK
 port ID.
 
@@ -1913,6 +1921,8 @@ only matching traffic goes through.
 Action: ``PF``
 ^^^^^^^^^^^^^^
 
+This action is DEPRECATED. Consider: `Action: ETHDEV`_.
+
 Directs matching traffic to the physical function (PF) of the current
 device.
 
@@ -1933,6 +1943,8 @@ See `Item: PF`_.
 Action: ``VF``
 ^^^^^^^^^^^^^^
 
+This action is DEPRECATED. Consider: `Action: ETHDEV`_, `Action: ESWITCH_PORT`_.
+
 Directs matching traffic to a given virtual function of the current device.
 
 Packets matched by a VF pattern item can be redirected to their original VF
@@ -1957,6 +1969,8 @@ See `Item: VF`_.
 Action: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^^^
 
+This action is DEPRECATED. Consider: `Action: ESWITCH_PORT`_.
+
 Directs matching traffic to a given physical port index of the underlying
 device.
 
@@ -1976,6 +1990,8 @@ See `Item: PHY_PORT`_.
 
 Action: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^^^
+This action is DEPRECATED. Consider: `Action: ETHDEV`_, `Action: ESWITCH_PORT`_.
+
 Directs matching traffic to a given DPDK port ID.
 
 See `Item: PORT_ID`_.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index a2fe766d4b..2b6718211f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -128,12 +128,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Definition of the flow API action ``RTE_FLOW_ACTION_TYPE_PORT_ID``
-  is ambiguous and needs clarification.
-  Structure ``rte_flow_action_port_id`` will be extended to specify
-  traffic direction to the represented entity or ethdev port itself
-  in DPDK 21.11.
-
 * ethdev: Flow API documentation is unclear if ethdev port used to create
   a flow rule adds any implicit match criteria in the case of transfer rules.
   The semantics will be clarified in DPDK 21.11 and it will require fixes in
@@ -262,3 +256,6 @@ Deprecation Notices
 * cmdline: ``cmdline`` structure will be made opaque to hide platform-specific
   content. On Linux and FreeBSD, supported prior to DPDK 20.11,
   original structure will be kept until DPDK 21.11.
+
+* ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
+  deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 4f4890c7df..fa0476a290 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -169,6 +169,9 @@ API Changes
 
 * ethdev: Added items and actions ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
 
+* ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
+  Suggested items and actions ``ETHDEV``, ``ESWITCH_PORT`` instead.
+
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
   well as PMD to check whether the device is valid or not.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 5d46b2350d..a9661dd6ae 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -160,6 +160,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_ANY,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+	 * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress)
@@ -170,6 +174,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+	 * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -180,6 +188,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+	 * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -190,6 +202,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+	 * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -640,6 +656,10 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+ * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_VF
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -669,6 +689,10 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+ * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PHY_PORT
  *
  * Matches traffic originating from (ingress) or going to (egress) a
@@ -700,6 +724,10 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_ETHDEV
+ * @see RTE_FLOW_ITEM_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PORT_ID
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -1989,6 +2017,9 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_RSS,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_ETHDEV
+	 *
 	 * Directs matching traffic to the physical function (PF) of the
 	 * current device.
 	 *
@@ -1997,6 +2028,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_ETHDEV
+	 * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+	 *
 	 * Directs matching traffic to a given virtual function of the
 	 * current device.
 	 *
@@ -2005,6 +2040,9 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+	 *
 	 * Directs packets to a given physical port index of the underlying
 	 * device.
 	 *
@@ -2013,6 +2051,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_ETHDEV
+	 * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+	 *
 	 * Directs matching traffic to a given DPDK port ID.
 	 *
 	 * See struct rte_flow_action_port_id.
@@ -2653,6 +2695,10 @@ struct rte_flow_action_rss {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_ETHDEV
+ * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_VF
  *
  * Directs matching traffic to a given virtual function of the current
@@ -2671,6 +2717,9 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PHY_PORT
  *
  * Directs packets to a given physical port index of the underlying
@@ -2685,6 +2734,10 @@ struct rte_flow_action_phy_port {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_ETHDEV
+ * @see RTE_FLOW_ACTION_TYPE_ESWITCH_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PORT_ID
  *
  * Directs matching traffic to a given DPDK port ID.
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (4 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 07/12] net/bnxt: support ethdev and E-Switch port flow items Andrew Rybchenko
                     ` (11 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ori Kam, Ray Kinsella, Thomas Monjalon, Ferruh Yigit; +Cc: dev, Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

Attributes "ingress" and "egress" can only apply unambiguosly
to non-"transfer" flows. In "transfer" flows, the standpoint
is effectively shifted to the underlying e-switch. There can
be many different endpoints connected to the e-switch, so
the use of "ingress" / "egress" doesn't shed light on which
endpoints precisely can be considered as traffic sources.

Add relevant deprecation notices and suggest the use of precise
traffic source items (ETHDEV and ESWITCH_PORT) instead.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 29 +++++++++---------
 doc/guides/rel_notes/deprecation.rst   |  9 +++---
 doc/guides/rel_notes/release_21_11.rst |  4 +++
 lib/ethdev/rte_flow.h                  | 41 ++++++++++++++++++++------
 4 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a5db278e8d..c8b2102b52 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -9,8 +9,8 @@ Overview
 --------
 
 This API provides a generic means to configure hardware to match specific
-ingress or egress traffic, alter its fate and query related counters
-according to any number of user-defined rules.
+traffic, alter its fate and query related counters according to any
+number of user-defined rules.
 
 It is named *rte_flow* after the prefix used for all its symbols, and is
 defined in ``rte_flow.h``.
@@ -146,13 +146,10 @@ Note that support for more than a single priority level is not guaranteed.
 Attribute: Traffic direction
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Flow rule patterns apply to inbound and/or outbound traffic.
-
-In the context of this API, **ingress** and **egress** respectively stand
-for **inbound** and **outbound** based on the standpoint of the application
-creating a flow rule.
-
-There are no exceptions to this definition.
+Unless `Attribute: Transfer`_ is specified, flow rule patterns apply
+to inbound and / or outbound traffic. With this respect, **ingress**
+and **egress** respectively stand for **inbound** and **outbound**
+based on the standpoint of the application creating a flow rule.
 
 Several pattern items and actions are valid and can be used in both
 directions. At least one direction must be specified.
@@ -171,12 +168,14 @@ When supported, this effectively enables an application to reroute traffic
 not necessarily intended for it (e.g. coming from or addressed to different
 physical ports, VFs or applications) at the device level.
 
-It complements the behavior of some pattern items such as `Item: PHY_PORT`_
-and is meaningless without them.
-
-When transferring flow rules, **ingress** and **egress** attributes
-(`Attribute: Traffic direction`_) keep their original meaning, as if
-processing traffic emitted or received by the application.
+In **transfer** flows, the use of **ingress** and **egress** attributes
+(`Attribute: Traffic direction`_) in the sense of implicitly matching
+packets going to or going from the ethdev used to create flow rules
+is DEPRECATED as these attributes are ambiguous. The standpoint is
+shifted to the e-switch, and, over there, terms **ingress** / **egress**
+are not relevant since there're many different ports served by the
+e-switch. If the application needs to match traffic origination from some
+precise locations, it should use `Item: ETHDEV`_ and `Item: ESWITCH_PORT`_.
 
 Pattern item
 ~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 2b6718211f..0c9e739bf2 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -128,11 +128,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Flow API documentation is unclear if ethdev port used to create
-  a flow rule adds any implicit match criteria in the case of transfer rules.
-  The semantics will be clarified in DPDK 21.11 and it will require fixes in
-  drivers and applications which interpret it in a different way.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header.
   Some matching pattern structures implements this by duplicating protocol header
@@ -259,3 +254,7 @@ Deprecation Notices
 
 * ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
   deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
+
+* ethdev: The use of attributes ``ingress`` / ``egress`` in "transfer" flows
+  is deprecated as ambiguous with respect to the e-switch standpoint. Such
+  use of these attributes will become invalid starting from DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index fa0476a290..37776c135e 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -172,6 +172,10 @@ API Changes
 * ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
   Suggested items and actions ``ETHDEV``, ``ESWITCH_PORT`` instead.
 
+* ethdev: Deprecated the use of attributes ``ingress`` / ``egress`` combined
+  with attribute ``transfer``. Items ``ETHDEV``, ``ESWITCH_PORT``
+  should be used instead to specify traffic source(s).
+
 * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
   rte_cryptodev_is_valid_dev as it can be used by the application as
   well as PMD to check whether the device is valid or not.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index a9661dd6ae..f195aa7224 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -67,7 +67,10 @@ extern "C" {
  * Note that support for more than a single group and priority level is not
  * guaranteed.
  *
- * Flow rules can apply to inbound and/or outbound traffic (ingress/egress).
+ * At vNIC / ethdev level, flow rules can apply to inbound and / or outbound
+ * traffic (ingress / egress), with respect to the vNIC / ethdev in question.
+ * At e-switch level, flow rules apply to all traffic seen by the e-switch
+ * unless suitable meta items are used to set concrete traffic source(s).
  *
  * Several pattern items and actions are valid and can be used in both
  * directions. Those valid for only one direction are described as such.
@@ -80,8 +83,32 @@ extern "C" {
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
 	uint32_t priority; /**< Rule priority level within group. */
-	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
-	uint32_t egress:1; /**< Rule applies to egress traffic. */
+	/**
+	 * The rule in question applies to ingress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic going from within the e-switch toward the ethdev
+	 * the flow rule being created through. This behaviour is now
+	 * deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t ingress:1;
+	/**
+	 * The rule in question applies to egress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic sent by the application by virtue of the ethdev
+	 * the flow rule being created through. This behaviour is now
+	 * deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t egress:1;
 	/**
 	 * Instead of simply matching the properties of traffic as it would
 	 * appear on a given DPDK port ID, enabling this attribute transfers
@@ -93,12 +120,8 @@ struct rte_flow_attr {
 	 * from or addressed to different physical ports, VFs or
 	 * applications) at the device level.
 	 *
-	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
-	 *
-	 * When transferring flow rules, ingress and egress attributes keep
-	 * their original meaning, as if processing traffic emitted or
-	 * received by the application.
+	 * In order to match traffic originating from specific source(s), the
+	 * application should use pattern items ETHDEV and ESWITCH_PORT.
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 07/12] net/bnxt: support ethdev and E-Switch port flow items
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (5 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 06/12] ethdev: deprecate direction attributes in transfer flows Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 08/12] net/bnxt: support ethdev and E-Switch port flow actions Andrew Rybchenko
                     ` (10 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ajit Khaparde, Somnath Kotur
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

Add support for RTE_FLOW_ITEM_TYPE_ETHDEV and
RTE_FLOW_ITEM_TYPE_ESWITCH_PORT items based on
RTE_FLOW_ITEM_TYPE_PORT_ID action.

The major difference of these items from PORT_ID is that these new
items define traffic direction itself. ETHDEV is always from the
driver vNIC. ESWITCH_PORT is either from v-port (network) or
VF vNIC (VF representor case).

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 10 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 80 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  9 ++-
 3 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index 9b165c12b5..87914cc845 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -266,7 +266,7 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	},
 	[RTE_FLOW_ITEM_TYPE_PORT_ID] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
-	.proto_hdr_func          = ulp_rte_port_id_hdr_handler
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	},
 	[RTE_FLOW_ITEM_TYPE_RAW] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
@@ -427,6 +427,14 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	[RTE_FLOW_ITEM_TYPE_HIGIG2] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
 	.proto_hdr_func          = NULL
+	},
+	[RTE_FLOW_ITEM_TYPE_ETHDEV] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
+	},
+	[RTE_FLOW_ITEM_TYPE_ESWITCH_PORT] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	}
 };
 
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 3a9c9bba27..c747150864 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -400,7 +400,8 @@ bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
 static int32_t
 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 			uint32_t ifindex,
-			uint16_t mask)
+			uint16_t mask,
+			enum bnxt_ulp_direction_type item_dir)
 {
 	uint16_t svif;
 	enum bnxt_ulp_direction_type dir;
@@ -429,11 +430,14 @@ ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 	bnxt_ulp_rte_parser_direction_compute(params);
 
 	/* Get the computed direction */
-	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_INGRESS) {
+	dir = (item_dir != BNXT_ULP_DIR_INVALID) ? item_dir :
+		ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
+	if (dir == BNXT_ULP_DIR_INGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
 	} else {
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
+		    item_dir != BNXT_ULP_DIR_EGRESS)
 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
 		else
 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
@@ -474,7 +478,8 @@ ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
 	}
 
 	/* Update the SVIF details */
-	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				     BNXT_ULP_DIR_INVALID);
 	return rc;
 }
 
@@ -522,7 +527,8 @@ ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
 	}
 
 	/* Update the SVIF details */
-	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+					BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow item VF Header. */
@@ -555,39 +561,75 @@ ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow item port id  Header. */
+/*
+ * Function to handle the parsing of RTE Flow items port id, ethdev and
+ * E-Switch port Headers.
+ */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params)
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params)
 {
-	const struct rte_flow_item_port_id *port_spec = item->spec;
-	const struct rte_flow_item_port_id *port_mask = item->mask;
+	enum bnxt_ulp_direction_type item_dir;
+	uint16_t ethdev_id;
 	uint16_t mask = 0;
 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
 	uint32_t ifindex;
 
-	if (!port_spec) {
-		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
+	if (!item->spec) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port spec is not valid\n");
 		return rc;
 	}
-	if (!port_mask) {
-		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
+	if (!item->mask) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port mask is not valid\n");
+		return rc;
+	}
+
+	switch (item->type) {
+	case RTE_FLOW_ITEM_TYPE_PORT_ID: {
+		const struct rte_flow_item_port_id *port_spec = item->spec;
+		const struct rte_flow_item_port_id *port_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INVALID;
+		ethdev_id = port_spec->id;
+		mask = port_mask->id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_ETHDEV: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INGRESS;
+		ethdev_id = ethdev_spec->id;
+		mask = ethdev_mask->id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_EGRESS;
+		ethdev_id = ethdev_spec->id;
+		mask = ethdev_mask->id;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "ParseErr:Unexpected item\n");
 		return rc;
 	}
-	mask = port_mask->id;
 
 	/* perform the conversion from dpdk port to bnxt ifindex */
 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
-					      port_spec->id,
+					      ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask, item_dir);
 }
 
 /* Function to handle the parsing of RTE Flow item phy port Header. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e14f86278a..531596b00d 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -90,10 +90,13 @@ int32_t
 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow item port id Header. */
+/*
+ * Function to handle the parsing of RTE Flow items port id, ethdev and
+ * E-Switch port Headers.
+ */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow item port Header. */
 int32_t
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 08/12] net/bnxt: support ethdev and E-Switch port flow actions
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (6 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 07/12] net/bnxt: support ethdev and E-Switch port flow items Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 09/12] net/enic: " Andrew Rybchenko
                     ` (9 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Ajit Khaparde, Somnath Kotur
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

Add support for RTE_FLOW_ACTION_TYPE_ETHDEV and
RTE_FLOW_ACTION_TYPE_ESWITCH_PORT actions based on
RTE_FLOW_ACTION_TYPE_PORT_ID action.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 12 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 84 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  9 +-
 3 files changed, 80 insertions(+), 25 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index 87914cc845..a31728c217 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -67,7 +67,7 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	},
 	[RTE_FLOW_ACTION_TYPE_PORT_ID] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
-	.proto_act_func          = ulp_rte_port_id_act_handler
+	.proto_act_func          = ulp_rte_port_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_METER] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
@@ -212,7 +212,15 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	[RTE_FLOW_ACTION_TYPE_SAMPLE] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
 	.proto_act_func          = ulp_rte_sample_act_handler
-	}
+	},
+	[RTE_FLOW_ACTION_TYPE_ETHDEV] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
+	[RTE_FLOW_ACTION_TYPE_ESWITCH_PORT] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
 };
 
 struct bnxt_ulp_rte_act_info ulp_vendor_act_info[] = {
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index c747150864..8e04229ee7 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -496,10 +496,11 @@ ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
 		return BNXT_TF_RC_SUCCESS;
 	}
 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
+	action_item.type = RTE_FLOW_ACTION_TYPE_PORT_ID;
 	action_item.conf = &port_id;
 
 	/* Update the action port based on incoming port */
-	ulp_rte_port_id_act_handler(&action_item, params);
+	ulp_rte_port_act_handler(&action_item, params);
 
 	/* Reset the action port set bit */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
@@ -2171,7 +2172,8 @@ ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
 /* Function to handle the parsing of action ports. */
 static int32_t
 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
-			    uint32_t ifindex)
+			    uint32_t ifindex,
+			    enum bnxt_ulp_direction_type act_dir)
 {
 	enum bnxt_ulp_direction_type dir;
 	uint16_t pid_s;
@@ -2181,8 +2183,13 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 	uint32_t vnic_type;
 
 	/* Get the direction */
-	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_EGRESS) {
+	/* If action implicitly specifies direction, use the specification. */
+	dir = (act_dir == BNXT_ULP_DIR_INVALID) ?
+		ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION) :
+		act_dir;
+	port_type = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
+	if (dir == BNXT_ULP_DIR_EGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		/* For egress direction, fill vport */
 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
 			return BNXT_TF_RC_ERROR;
@@ -2193,9 +2200,14 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
 	} else {
 		/* For ingress direction, fill vnic */
-		port_type = ULP_COMP_FLD_IDX_RD(param,
-						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		/*
+		 * In ETHDEV action case, destination is a driver
+		 * function of the representor itself, otherwise
+		 * (PORT_ID or ESWITCH_PORT) the destination is
+		 * corresponding VF.
+		 */
+		if (act_dir != BNXT_ULP_DIR_INGRESS &&
+		    port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
 		else
 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
@@ -2242,7 +2254,8 @@ ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
 	}
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow action VF. */
@@ -2293,31 +2306,62 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/*
+ * Function to handle the parsing of RTE Flow actions PORT_ID, ETHDEV and
+ * ESWITCH_PORT.
+ */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *param)
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *param)
 {
-	const struct rte_flow_action_port_id *port_id = act_item->conf;
+	uint32_t ethdev_id;
 	uint32_t ifindex;
 	enum bnxt_ulp_intf_type intf_type;
+	enum bnxt_ulp_direction_type act_dir;
 
-	if (!port_id) {
+	if (!act_item->conf) {
 		BNXT_TF_DBG(ERR,
 			    "ParseErr: Invalid Argument\n");
 		return BNXT_TF_RC_PARSE_ERR;
 	}
-	if (port_id->original) {
-		BNXT_TF_DBG(ERR,
-			    "ParseErr:Portid Original not supported\n");
-		return BNXT_TF_RC_PARSE_ERR;
+	switch (act_item->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *port_id = act_item->conf;
+
+		if (port_id->original) {
+			BNXT_TF_DBG(ERR,
+				    "ParseErr:Portid Original not supported\n");
+			return BNXT_TF_RC_PARSE_ERR;
+		}
+		ethdev_id = port_id->id;
+		act_dir = BNXT_ULP_DIR_INVALID;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_ETHDEV: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->id;
+		act_dir = BNXT_ULP_DIR_INGRESS;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->id;
+		act_dir = BNXT_ULP_DIR_EGRESS;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "Unknown port action\n");
+		return BNXT_TF_RC_ERROR;
 	}
 
 	/* Get the port db ifindex */
-	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, port_id->id,
+	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "Invalid port id\n");
 		return BNXT_TF_RC_ERROR;
@@ -2332,7 +2376,7 @@ ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
 
 	/* Set the action port */
 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(param, ifindex);
+	return ulp_rte_parser_act_port_set(param, ifindex, act_dir);
 }
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index 531596b00d..307bb5c75c 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -207,10 +207,13 @@ int32_t
 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/*
+ * Function to handle the parsing of RTE Flow actions PORT_ID, ETHDEV and
+ * ESWITCH_PORT.
+ */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
 int32_t
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 09/12] net/enic: support ethdev and E-Switch port flow actions
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (7 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 08/12] net/bnxt: support ethdev and E-Switch port flow actions Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 10/12] net/mlx5: support E-Switch port flow action Andrew Rybchenko
                     ` (8 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: John Daley, Hyong Youb Kim
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

Add support for RTE_FLOW_ACTION_TYPE_ETHDEV and
RTE_FLOW_ACTION_TYPE_ESWITCH_PORT actions based on
RTE_FLOW_ACTION_TYPE_PORT_ID action.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/enic/enic_fm_flow.c | 93 ++++++++++++++++++++++++++-------
 1 file changed, 75 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index cd364ee16b..0878b54067 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1242,6 +1242,35 @@ vf_egress_port_id_action(struct enic_flowman *fm,
 	return 0;
 }
 
+static int
+enic_fm_check_transfer_dst(struct enic *enic, uint16_t dst_port_id,
+			   struct rte_eth_dev **dst_dev,
+			   struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev;
+
+	ENICPMD_LOG(DEBUG, "port id %u", dst_port_id);
+	if (!rte_eth_dev_is_valid_port(dst_port_id)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "invalid port_id");
+	}
+	dev = &rte_eth_devices[dst_port_id];
+	if (!dev_is_enic(dev)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "port_id is not enic");
+	}
+	if (enic->switch_domain_id != pmd_priv(dev)->switch_domain_id) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "destination and source ports are not in the same switch domain");
+	}
+
+	*dst_dev = dev;
+	return 0;
+}
+
 /* Translate flow actions to flowman TCAM entry actions */
 static int
 enic_fm_copy_action(struct enic_flowman *fm,
@@ -1446,24 +1475,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
 				vnic_h = enic->fm_vnic_handle; /* This port */
 				break;
 			}
-			ENICPMD_LOG(DEBUG, "port id %u", port->id);
-			if (!rte_eth_dev_is_valid_port(port->id)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "invalid port_id");
-			}
-			dev = &rte_eth_devices[port->id];
-			if (!dev_is_enic(dev)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "port_id is not enic");
-			}
-			if (enic->switch_domain_id !=
-			    pmd_priv(dev)->switch_domain_id) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "destination and source ports are not in the same switch domain");
-			}
+			ret = enic_fm_check_transfer_dst(enic, port->id, &dev,
+							 error);
+			if (ret)
+				return ret;
 			vnic_h = pmd_priv(dev)->fm_vnic_handle;
 			overlap |= PORT_ID;
 			/*
@@ -1560,6 +1575,48 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			ovlan |= rte_be_to_cpu_16(vid->vlan_vid);
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_ETHDEV: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->id, &dev,
+							 error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/*
+			 * ETHDEV action implies ingress destination.
+			 * Noting to do. We add an implicit stree at the
+			 * end if needed.
+			 */
+			ingress = 1;
+			break;
+		}
+		case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			if (overlap & PORT_ID) {
+				ENICPMD_LOG(DEBUG, "cannot have multiple egress PORT_ID actions");
+				goto unsupported;
+			}
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->id, &dev,
+							 error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/* E-Switch port action is always egress destination */
+			ingress = 0;
+			ret = vf_egress_port_id_action(fm, dev, vnic_h, &fm_op,
+				error);
+			if (ret)
+				return ret;
+			break;
+		}
 		default:
 			goto unsupported;
 		}
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 10/12] net/mlx5: support E-Switch port flow action
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (8 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 09/12] net/enic: " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 11/12] net/octeontx2: support ethdev " Andrew Rybchenko
                     ` (7 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Matan Azrad, Viacheslav Ovsiienko
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

PORT_ID action implementation has the same semantics as
ESWITCH_PORT action in net/mlx5 case.

Helper functions keep port_id suffix since internally it is
still a MLX5_FLOW_ACTION_PORT_ID action.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++-------
 1 file changed, 50 insertions(+), 12 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index b610ad3ef4..98f15b328f 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -5048,14 +5048,14 @@ flow_dv_validate_action_jump(struct rte_eth_dev *dev,
 }
 
 /*
- * Validate the port_id action.
+ * Validate the port ID or E-Switch port action.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action_flags
  *   Bit-fields that holds the actions detected until now.
  * @param[in] action
- *   Port_id RTE action structure.
+ *   PORT_ID or ESWITCH_PORT RTE action structure.
  * @param[in] attr
  *   Attributes of flow that includes this action.
  * @param[out] error
@@ -5072,6 +5072,7 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 				struct rte_flow_error *error)
 {
 	const struct rte_flow_action_port_id *port_id;
+	const struct rte_flow_action_ethdev *ethdev;
 	struct mlx5_priv *act_priv;
 	struct mlx5_priv *dev_priv;
 	uint16_t port;
@@ -5080,13 +5081,13 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
-					  "port id action is valid in transfer"
+					  "port action is valid in transfer"
 					  " mode only");
 	if (!action || !action->conf)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  NULL,
-					  "port id action parameters must be"
+					  "port action parameters must be"
 					  " specified");
 	if (action_flags & (MLX5_FLOW_FATE_ACTIONS |
 			    MLX5_FLOW_FATE_ESWITCH_ACTIONS))
@@ -5100,13 +5101,26 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
 					  "failed to obtain E-Switch info");
-	port_id = action->conf;
-	port = port_id->original ? dev->data->port_id : port_id->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		port_id = action->conf;
+		port = port_id->original ? dev->data->port_id : port_id->id;
+		break;
+	case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
+		ethdev = action->conf;
+		port = ethdev->id;
+		break;
+	default:
+		return rte_flow_error_set
+				(error, EINVAL,
+				 RTE_FLOW_ERROR_TYPE_ACTION, action,
+				 "unknown E-Switch action");
+	}
 	act_priv = mlx5_port_to_eswitch_info(port, false);
 	if (!act_priv)
 		return rte_flow_error_set
 				(error, rte_errno,
-				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, port_id,
+				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, action->conf,
 				 "failed to obtain E-Switch port id for port");
 	if (act_priv->domain_id != dev_priv->domain_id)
 		return rte_flow_error_set
@@ -5669,6 +5683,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 			++actions_n;
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      sub_action_flags,
 							      act,
@@ -7296,6 +7311,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      action_flags,
 							      actions,
@@ -10770,12 +10786,12 @@ flow_dv_tag_release(struct rte_eth_dev *dev,
 }
 
 /**
- * Translate port ID action to vport.
+ * Translate port ID or E-Switch port action to vport.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to the port ID action.
+ *   Pointer to the port ID or E-Switch port action.
  * @param[out] dst_port_id
  *   The target port ID.
  * @param[out] error
@@ -10792,10 +10808,28 @@ flow_dv_translate_action_port_id(struct rte_eth_dev *dev,
 {
 	uint32_t port;
 	struct mlx5_priv *priv;
-	const struct rte_flow_action_port_id *conf =
-			(const struct rte_flow_action_port_id *)action->conf;
 
-	port = conf->original ? dev->data->port_id : conf->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *conf;
+
+		conf = (const struct rte_flow_action_port_id *)action->conf;
+		port = conf->original ? dev->data->port_id : conf->id;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT: {
+		const struct rte_flow_action_ethdev *ethdev;
+
+		ethdev = (const struct rte_flow_action_ethdev *)action->conf;
+		port = ethdev->id;
+		break;
+	}
+	default:
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "unknown E-Switch action");
+	}
+
 	priv = mlx5_port_to_eswitch_info(port, false);
 	if (!priv)
 		return rte_flow_error_set(error, -rte_errno,
@@ -11634,6 +11668,7 @@ flow_dv_translate_action_sample(struct rte_eth_dev *dev,
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 		{
 			struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -12714,6 +12749,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 			if (flow_dv_translate_action_port_id(dev, action,
 							     &port_id, error))
 				return -rte_errno;
@@ -15475,6 +15511,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 				break;
 			}
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 			{
 				struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -17683,6 +17720,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 					  NULL, "too many actions");
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_ESWITCH_PORT:
 				if (!priv->config.dv_esw_en)
 					return -rte_mtr_error_set(error,
 					ENOTSUP,
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 11/12] net/octeontx2: support ethdev flow action
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (9 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 10/12] net/mlx5: support E-Switch port flow action Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-04 11:13     ` [dpdk-dev] [EXT] " Kiran Kumar Kokkilagadda
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 12/12] net/sfc: support ethdev flow item Andrew Rybchenko
                     ` (6 subsequent siblings)
  17 siblings, 1 reply; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  To: Jerin Jacob, Nithin Dabilpuram, Kiran Kumar K
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

PORT_ID action implementation works for ingress only and has the same
semantics as ETHDEV action.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/octeontx2/otx2_flow_parse.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/octeontx2/otx2_flow_parse.c b/drivers/net/octeontx2/otx2_flow_parse.c
index 63a33142a5..5dd8464ec9 100644
--- a/drivers/net/octeontx2/otx2_flow_parse.c
+++ b/drivers/net/octeontx2/otx2_flow_parse.c
@@ -900,7 +900,6 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 {
 	struct otx2_eth_dev *hw = dev->data->dev_private;
 	struct otx2_npc_flow_info *npc = &hw->npc_flow;
-	const struct rte_flow_action_port_id *port_act;
 	const struct rte_flow_action_count *act_count;
 	const struct rte_flow_action_mark *act_mark;
 	const struct rte_flow_action_queue *act_q;
@@ -987,9 +986,18 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 			break;
 
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
-			port_act = (const struct rte_flow_action_port_id *)
-				actions->conf;
-			port_id = port_act->id;
+		case RTE_FLOW_ACTION_TYPE_ETHDEV:
+			if (actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
+				const struct rte_flow_action_port_id *port_act;
+
+				port_act = actions->conf;
+				port_id = port_act->id;
+			} else {
+				const struct rte_flow_action_ethdev *ethdev_act;
+
+				ethdev_act = actions->conf;
+				port_id = ethdev_act->id;
+			}
 			if (rte_eth_dev_get_name_by_port(port_id, if_name)) {
 				errmsg = "Name not found for output port id";
 				errcode = EINVAL;
-- 
2.30.2


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

* [dpdk-dev] [PATCH v1 12/12] net/sfc: support ethdev flow item
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (10 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 11/12] net/octeontx2: support ethdev " Andrew Rybchenko
@ 2021-10-01 13:47   ` Andrew Rybchenko
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                     ` (5 subsequent siblings)
  17 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-01 13:47 UTC (permalink / raw)
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

Add support for RTE_FLOW_ITEM_TYPE_ETHDEV which should be used
instead of ambiguous RTE_FLOW_ITEM_TYPE_PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/sfc/sfc_mae.c | 72 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 4b520bc619..1299fc3680 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -1100,6 +1100,66 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
 	return 0;
 }
 
+static int
+sfc_mae_rule_parse_item_ethdev(const struct rte_flow_item *item,
+			       struct sfc_flow_parse_ctx *ctx,
+			       struct rte_flow_error *error)
+{
+	struct sfc_mae_parse_ctx *ctx_mae = ctx->mae;
+	const struct rte_flow_item_ethdev supp_mask = {
+		.id = 0xffff,
+	};
+	const void *def_mask = &rte_flow_item_ethdev_mask;
+	const struct rte_flow_item_ethdev *spec = NULL;
+	const struct rte_flow_item_ethdev *mask = NULL;
+	efx_mport_sel_t mport_sel;
+	int rc;
+
+	if (ctx_mae->match_mport_set) {
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't handle multiple traffic source items");
+	}
+
+	rc = sfc_flow_parse_init(item,
+				 (const void **)&spec, (const void **)&mask,
+				 (const void *)&supp_mask, def_mask,
+				 sizeof(struct rte_flow_item_ethdev), error);
+	if (rc != 0)
+		return rc;
+
+	if (mask->id != supp_mask.id) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Bad mask in the ETHDEV pattern item");
+	}
+
+	/* If "spec" is not set, could be any port ID */
+	if (spec == NULL)
+		return 0;
+
+	rc = sfc_mae_switch_port_by_ethdev(
+			ctx_mae->sa->mae.switch_domain_id,
+			spec->id, &mport_sel);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't find RTE ethdev by the port ID");
+	}
+
+	rc = efx_mae_match_spec_mport_set(ctx_mae->match_spec,
+					  &mport_sel, NULL);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Failed to set MPORT for the port ID");
+	}
+
+	ctx_mae->match_mport_set = B_TRUE;
+
+	return 0;
+}
+
 static int
 sfc_mae_rule_parse_item_phy_port(const struct rte_flow_item *item,
 				 struct sfc_flow_parse_ctx *ctx,
@@ -1995,6 +2055,18 @@ static const struct sfc_flow_item sfc_flow_items[] = {
 		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
 		.parse = sfc_mae_rule_parse_item_port_id,
 	},
+	{
+		.type = RTE_FLOW_ITEM_TYPE_ETHDEV,
+		.name = "ETHDEV",
+		/*
+		 * In terms of RTE flow, this item is a META one,
+		 * and its position in the pattern is don't care.
+		 */
+		.prev_layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
+		.parse = sfc_mae_rule_parse_item_ethdev,
+	},
 	{
 		.type = RTE_FLOW_ITEM_TYPE_PHY_PORT,
 		.name = "PHY_PORT",
-- 
2.30.2


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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to " Andrew Rybchenko
@ 2021-10-03 11:52     ` Ori Kam
  2021-10-03 17:40       ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-03 11:52 UTC (permalink / raw)
  To: Andrew Rybchenko, Xiaoyun Li, NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev, Ivan Malov

Hi Andrew and Ivan,

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, October 1, 2021 4:47 PM
> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
> 
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> 
> For use with "transfer" flows. Supposed to match traffic transmitted by the
> DPDK application via the specified ethdev, at e-switch level.
> 
> Must not be combined with attributes "ingress" / "egress".
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---

[Snip]

>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> 7b1ed7f110..880502098e 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_conntrack.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> +
> +	/**
> +	 * [META]
> +	 *
> +	 * Matches traffic at e-switch going from (sent by) the given ethdev.
> +	 *
> +	 * @see struct rte_flow_item_ethdev
> +	 */
> +	RTE_FLOW_ITEM_TYPE_ETHDEV,
>  };
> 
>  /**
> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * Provides an ethdev ID for use with items which are as follows:
> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
> + */
> +struct rte_flow_item_ethdev {
> +	uint16_t id; /**< Ethdev ID */

True for all above uses,
should this be renamed to port?

> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_ETHDEV */ #ifndef
> __cplusplus
> +static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
> +	.id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> --
> 2.30.2


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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port " Andrew Rybchenko
@ 2021-10-03 12:40     ` Ori Kam
  2021-10-03 18:10       ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-03 12:40 UTC (permalink / raw)
  To: Andrew Rybchenko, Xiaoyun Li, NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev, Ivan Malov

Hi Andrew and Ivan,

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, October 1, 2021 4:47 PM
> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> 
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> 
> For use with "transfer" flows. Supposed to match traffic entering the e-switch
> from the external world (network, guests) via the port which is logically
> connected with the given ethdev.
> 
> Must not be combined with attributes "ingress" / "egress".
> 
> This item is meant to use the same structure as ethdev item.
> 

In case the app is not working with representors, meaning
each switch port is mapped to ethdev.
both items (ethdev and eswitch port ) have the same meaning?

> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
>  app/test-pmd/cmdline_flow.c                 | 27 +++++++++++++++++++++
>  doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
>  doc/guides/rel_notes/release_21_11.rst      |  2 +-
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
>  lib/ethdev/rte_flow.c                       |  1 +
>  lib/ethdev/rte_flow.h                       | 12 ++++++++-
>  6 files changed, 66 insertions(+), 2 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index e05b0d83d2..188d0ee39d 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -308,6 +308,8 @@ enum index {
>  	ITEM_POL_POLICY,
>  	ITEM_ETHDEV,
>  	ITEM_ETHDEV_ID,
> +	ITEM_ESWITCH_PORT,
> +	ITEM_ESWITCH_PORT_ETHDEV_ID,

Like my comment from previous patch, I'm not sure the correct
term for ETHDEV is ID is should be port.

> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
>  	ITEM_INTEGRITY,
>  	ITEM_CONNTRACK,
>  	ITEM_ETHDEV,
> +	ITEM_ESWITCH_PORT,
>  	END_SET,
>  	ZERO,
>  };
> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_eswitch_port[] = {
> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
>  			     item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
>  	},
> +	[ITEM_ESWITCH_PORT] = {
> +		.name = "eswitch_port",
> +		.help = "match traffic at e-switch going from the external port
> associated with the given ethdev",

Missing the word logically since if we are talking about representor the connected port
is the PF while we want to match traffic on one of the FVs.

> +		.priv = PRIV_ITEM(ESWITCH_PORT,
> +				  sizeof(struct rte_flow_item_ethdev)),
> +		.next = NEXT(item_eswitch_port),
> +		.call = parse_vc,
> +	},
> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
> +		.name = "ethdev_id",
> +		.help = "ethdev ID",
> +		.next = NEXT(item_eswitch_port,
> NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
> rte_flow_item *item)
>  	case RTE_FLOW_ITEM_TYPE_ETHDEV:
>  		mask = &rte_flow_item_ethdev_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
> +		mask = &rte_flow_item_ethdev_mask;
> +		break;

Not sure maybe merged the two cases?

>  	default:
>  		break;
>  	}
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index ab628d9139..292bb42410 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**. Attributes
> **ingress** and
>     | ``mask`` | ``id``   | zeroed for wildcard match |
>     +----------+----------+---------------------------+
> 
> +Item: ``ESWITCH_PORT``
> +^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches traffic at e-switch going from the external port associated
> +with the given ethdev, for example, traffic from net. port or guest.

Maybe replace external with e-switch?

> +
> +::
> +
> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External Port)
> +   *    :  SW                 :   Logical                    Net / Guest :
> +   *    :                     :                                          :
> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
> +   *
> +   *    [] shows the effective ("transfer") standpoint, the match engine;
> +   *    << shows the traffic flow in question hitting the match engine;
> +   *    ~~ shows logical interconnects between the endpoints.
> +

I'm not sure I understand this diagram.

> +Use this with attribute **transfer**. Attributes **ingress** and
> +**egress** (`Attribute: Traffic direction`_) must not be used.
> +
> +This item is meant to use the same structure as `Item: ETHDEV`_.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 91631adb4e..b2b27de3f0 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -167,7 +167,7 @@ API Changes
>     Also, make sure to start the actual text at the margin.
>     =======================================================
> 
> -* ethdev: Added item ``ETHDEV`` to flow API.
> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
> 
>  * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
>    rte_cryptodev_is_valid_dev as it can be used by the application as diff --git
> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 6d5de5457c..9a5c2a2d82 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3824,6 +3824,10 @@ This section lists supported pattern items and
> their attributes, if any.
> 
>    - ``id {unsigned}``: ethdev ID
> 
> +- ``eswitch_port``: match traffic at e-switch going from the external
> +port associated with the given ethdev
> +
> +  - ``ethdev_id {unsigned}``: ethdev ID
> +
>  Actions list
>  ^^^^^^^^^^^^
> 
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> 84eb61cb6c..c4aea5625f 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>  	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
> rte_flow_item_ethdev)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> 880502098e..1a7e4c2e3d 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_ethdev
>  	 */
>  	RTE_FLOW_ITEM_TYPE_ETHDEV,
> +
> +	/**
> +	 * [META]
> +	 *
> +	 * Matches traffic at e-switch going from the external port associated
> +	 * with the given ethdev, for example, traffic from net. port or guest.
> +	 *
> +	 * @see struct rte_flow_item_ethdev
> +	 */
> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
>  };
> 
>  /**
> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {
>   * @b EXPERIMENTAL: this structure may change without prior notice
>   *
>   * Provides an ethdev ID for use with items which are as follows:
> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
>   */
>  struct rte_flow_item_ethdev {
>  	uint16_t id; /**< Ethdev ID */
> --
> 2.30.2

Best,
Ori


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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-03 11:52     ` Ori Kam
@ 2021-10-03 17:40       ` Ivan Malov
  2021-10-03 21:09         ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-03 17:40 UTC (permalink / raw)
  To: Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ori,

On 03/10/2021 14:52, Ori Kam wrote:
> Hi Andrew and Ivan,
> 
>> -----Original Message-----
>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Sent: Friday, October 1, 2021 4:47 PM
>> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>
>> For use with "transfer" flows. Supposed to match traffic transmitted by the
>> DPDK application via the specified ethdev, at e-switch level.
>>
>> Must not be combined with attributes "ingress" / "egress".
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> ---
> 
> [Snip]
> 
>>   /** Generate flow_action[] entry. */
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> 7b1ed7f110..880502098e 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>   	 * @see struct rte_flow_item_conntrack.
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_CONNTRACK,
>> +
>> +	/**
>> +	 * [META]
>> +	 *
>> +	 * Matches traffic at e-switch going from (sent by) the given ethdev.
>> +	 *
>> +	 * @see struct rte_flow_item_ethdev
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_ETHDEV,
>>   };
>>
>>   /**
>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>> rte_flow_item_conntrack_mask = {  };  #endif
>>
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + *
>> + * Provides an ethdev ID for use with items which are as follows:
>> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
>> + */
>> +struct rte_flow_item_ethdev {
>> +	uint16_t id; /**< Ethdev ID */
> 
> True for all above uses,
> should this be renamed to port?

I'd not rename it to "port". The very idea of this series is to 
disambiguate things. This structure is shared between primitives ETHDEV 
and ESWITCH_PORT. If we go for "port", then in conjunction with 
ESWITCH_PORT the structure name may trick readers into thinking that the 
ID in question is the own ID of the e-switch port itself. But in fact 
this ID is an ethdev ID which is associated with the e-switch port.

Should you wish to elaborate on your concerns with regard to naming, 
please do so. I'm all ears.

> 
>> +};
>> +
>> +/** Default mask for RTE_FLOW_ITEM_TYPE_ETHDEV */ #ifndef
>> __cplusplus
>> +static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
>> +	.id = 0xffff,
>> +};
>> +#endif
>> +
>>   /**
>>    * Matching pattern item definition.
>>    *
>> --
>> 2.30.2

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-03 12:40     ` Ori Kam
@ 2021-10-03 18:10       ` Ivan Malov
  2021-10-04  5:45         ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-03 18:10 UTC (permalink / raw)
  To: Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev



On 03/10/2021 15:40, Ori Kam wrote:
> Hi Andrew and Ivan,
> 
>> -----Original Message-----
>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Sent: Friday, October 1, 2021 4:47 PM
>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>
>> For use with "transfer" flows. Supposed to match traffic entering the e-switch
>> from the external world (network, guests) via the port which is logically
>> connected with the given ethdev.
>>
>> Must not be combined with attributes "ingress" / "egress".
>>
>> This item is meant to use the same structure as ethdev item.
>>
> 
> In case the app is not working with representors, meaning
> each switch port is mapped to ethdev.
> both items (ethdev and eswitch port ) have the same meaning?

No. Ethdev means ethdev, and e-switch port is the point where this 
ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a 
regular PF ethdev typically means the network port (maybe you can recall 
the idea that a PF ethdev "represents" the network port it's associated 
with).

I believe, that diagrams which these patches add to 
"doc/guides/prog_guide/rte_flow.rst" may come in handy to understand the 
meaning. Also, you can take a look at our larger diagram from the Sep 14 
gathering.

> 
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> ---
>>   app/test-pmd/cmdline_flow.c                 | 27 +++++++++++++++++++++
>>   doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
>>   doc/guides/rel_notes/release_21_11.rst      |  2 +-
>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
>>   lib/ethdev/rte_flow.c                       |  1 +
>>   lib/ethdev/rte_flow.h                       | 12 ++++++++-
>>   6 files changed, 66 insertions(+), 2 deletions(-)
>>
>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
>> index e05b0d83d2..188d0ee39d 100644
>> --- a/app/test-pmd/cmdline_flow.c
>> +++ b/app/test-pmd/cmdline_flow.c
>> @@ -308,6 +308,8 @@ enum index {
>>   	ITEM_POL_POLICY,
>>   	ITEM_ETHDEV,
>>   	ITEM_ETHDEV_ID,
>> +	ITEM_ESWITCH_PORT,
>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> 
> Like my comment from previous patch, I'm not sure the correct
> term for ETHDEV is ID is should be port.

Please see my reply in the previous thread. "ethdev" here is an 
"anchor", a "beacon" of sorts which allows either to refer namely to 
this ethdev or to the e-switch port associated with it.

> 
>>
>>   	/* Validate/create actions. */
>>   	ACTIONS,
>> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
>>   	ITEM_INTEGRITY,
>>   	ITEM_CONNTRACK,
>>   	ITEM_ETHDEV,
>> +	ITEM_ESWITCH_PORT,
>>   	END_SET,
>>   	ZERO,
>>   };
>> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
>>   	ZERO,
>>   };
>>
>> +static const enum index item_eswitch_port[] = {
>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
>> +	ITEM_NEXT,
>> +	ZERO,
>> +};
>> +
>>   static const enum index next_action[] = {
>>   	ACTION_END,
>>   	ACTION_VOID,
>> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
>>   			     item_param),
>>   		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
>>   	},
>> +	[ITEM_ESWITCH_PORT] = {
>> +		.name = "eswitch_port",
>> +		.help = "match traffic at e-switch going from the external port
>> associated with the given ethdev",
> 
> Missing the word logically since if we are talking about representor the connected port
> is the PF while we want to match traffic on one of the FVs.

Doesn't the word "external" say it all?

Representor Ethdev <--> Admin ethdev's PF <--> E-Switch <--> VF 
(external / the most remote endpoint).

> 
>> +		.priv = PRIV_ITEM(ESWITCH_PORT,
>> +				  sizeof(struct rte_flow_item_ethdev)),
>> +		.next = NEXT(item_eswitch_port),
>> +		.call = parse_vc,
>> +	},
>> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
>> +		.name = "ethdev_id",
>> +		.help = "ethdev ID",
>> +		.next = NEXT(item_eswitch_port,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>> +			     item_param),
>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, id)),
>> +	},
>>   	/* Validate/create actions. */
>>   	[ACTIONS] = {
>>   		.name = "actions",
>> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
>> rte_flow_item *item)
>>   	case RTE_FLOW_ITEM_TYPE_ETHDEV:
>>   		mask = &rte_flow_item_ethdev_mask;
>>   		break;
>> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
>> +		mask = &rte_flow_item_ethdev_mask;
>> +		break;
> 
> Not sure maybe merged the two cases?

A noble idea.

> 
>>   	default:
>>   		break;
>>   	}
>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>> b/doc/guides/prog_guide/rte_flow.rst
>> index ab628d9139..292bb42410 100644
>> --- a/doc/guides/prog_guide/rte_flow.rst
>> +++ b/doc/guides/prog_guide/rte_flow.rst
>> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**. Attributes
>> **ingress** and
>>      | ``mask`` | ``id``   | zeroed for wildcard match |
>>      +----------+----------+---------------------------+
>>
>> +Item: ``ESWITCH_PORT``
>> +^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +Matches traffic at e-switch going from the external port associated
>> +with the given ethdev, for example, traffic from net. port or guest.
> 
> Maybe replace external with e-switch?

The word "e-switch" is already here. Basically, all "external" ports are 
"e-switch external ports" = ports which connect the e-switch with 
non-DPDK world: network ports, VFs passed to guests, etc.

> 
>> +
>> +::
>> +
>> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External Port)
>> +   *    :  SW                 :   Logical                    Net / Guest :
>> +   *    :                     :                                          :
>> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
>> +   *
>> +   *    [] shows the effective ("transfer") standpoint, the match engine;
>> +   *    << shows the traffic flow in question hitting the match engine;
>> +   *    ~~ shows logical interconnects between the endpoints.
>> +
> 
> I'm not sure I understand this diagram.

Thanks for the feedback. I have no way with drawing fancy diagrams, so 
this one may not be ideal, yes. But could you please elaborate on your 
concerns. Maybe you understand it the right way but just unsure. If you 
describe what you see when looking at the diagram, I'll be able to 
either confirm your vision or debunk any misunderstanding and possibly 
improve the drawing.

> 
>> +Use this with attribute **transfer**. Attributes **ingress** and
>> +**egress** (`Attribute: Traffic direction`_) must not be used.
>> +
>> +This item is meant to use the same structure as `Item: ETHDEV`_.
>> +
>>   Actions
>>   ~~~~~~~
>>
>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>> b/doc/guides/rel_notes/release_21_11.rst
>> index 91631adb4e..b2b27de3f0 100644
>> --- a/doc/guides/rel_notes/release_21_11.rst
>> +++ b/doc/guides/rel_notes/release_21_11.rst
>> @@ -167,7 +167,7 @@ API Changes
>>      Also, make sure to start the actual text at the margin.
>>      =======================================================
>>
>> -* ethdev: Added item ``ETHDEV`` to flow API.
>> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
>>
>>   * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
>>     rte_cryptodev_is_valid_dev as it can be used by the application as diff --git
>> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> index 6d5de5457c..9a5c2a2d82 100644
>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> @@ -3824,6 +3824,10 @@ This section lists supported pattern items and
>> their attributes, if any.
>>
>>     - ``id {unsigned}``: ethdev ID
>>
>> +- ``eswitch_port``: match traffic at e-switch going from the external
>> +port associated with the given ethdev
>> +
>> +  - ``ethdev_id {unsigned}``: ethdev ID
>> +
>>   Actions list
>>   ^^^^^^^^^^^^
>>
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>> 84eb61cb6c..c4aea5625f 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
>> rte_flow_desc_item[] = {
>>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>>   	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
>> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
>> rte_flow_item_ethdev)),
>>   };
>>
>>   /** Generate flow_action[] entry. */
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> 880502098e..1a7e4c2e3d 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
>>   	 * @see struct rte_flow_item_ethdev
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_ETHDEV,
>> +
>> +	/**
>> +	 * [META]
>> +	 *
>> +	 * Matches traffic at e-switch going from the external port associated
>> +	 * with the given ethdev, for example, traffic from net. port or guest.
>> +	 *
>> +	 * @see struct rte_flow_item_ethdev
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
>>   };
>>
>>   /**
>> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
>> rte_flow_item_conntrack_mask = {
>>    * @b EXPERIMENTAL: this structure may change without prior notice
>>    *
>>    * Provides an ethdev ID for use with items which are as follows:
>> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
>> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
>> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
>>    */
>>   struct rte_flow_item_ethdev {
>>   	uint16_t id; /**< Ethdev ID */
>> --
>> 2.30.2
> 
> Best,
> Ori
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-03 17:40       ` Ivan Malov
@ 2021-10-03 21:09         ` Ori Kam
  2021-10-04  0:00           ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-03 21:09 UTC (permalink / raw)
  To: Ivan Malov, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Subject: Re: [PATCH v1 01/12] ethdev: add ethdev item to flow API
> 
> Hi Ori,
> 
> On 03/10/2021 14:52, Ori Kam wrote:
> > Hi Andrew and Ivan,
> >
> >> -----Original Message-----
> >> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >> Sent: Friday, October 1, 2021 4:47 PM
> >> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
> >>
> >> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >>
> >> For use with "transfer" flows. Supposed to match traffic transmitted
> >> by the DPDK application via the specified ethdev, at e-switch level.
> >>
> >> Must not be combined with attributes "ingress" / "egress".
> >>
> >> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >> ---
> >
> > [Snip]
> >
> >>   /** Generate flow_action[] entry. */ diff --git
> >> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >> 7b1ed7f110..880502098e 100644
> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
> >>   	 * @see struct rte_flow_item_conntrack.
> >>   	 */
> >>   	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> >> +
> >> +	/**
> >> +	 * [META]
> >> +	 *
> >> +	 * Matches traffic at e-switch going from (sent by) the given ethdev.
> >> +	 *
> >> +	 * @see struct rte_flow_item_ethdev
> >> +	 */
> >> +	RTE_FLOW_ITEM_TYPE_ETHDEV,
> >>   };
> >>
> >>   /**
> >> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
> >> rte_flow_item_conntrack_mask = {  };  #endif
> >>
> >> +/**
> >> + * @warning
> >> + * @b EXPERIMENTAL: this structure may change without prior notice
> >> + *
> >> + * Provides an ethdev ID for use with items which are as follows:
> >> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
> >> + */
> >> +struct rte_flow_item_ethdev {
> >> +	uint16_t id; /**< Ethdev ID */
> >
> > True for all above uses,
> > should this be renamed to port?
> 
> I'd not rename it to "port". The very idea of this series is to disambiguate
> things. This structure is shared between primitives ETHDEV and
> ESWITCH_PORT. If we go for "port", then in conjunction with ESWITCH_PORT
> the structure name may trick readers into thinking that the ID in question is
> the own ID of the e-switch port itself. But in fact this ID is an ethdev ID which
> is associated with the e-switch port.
> 
> Should you wish to elaborate on your concerns with regard to naming, please
> do so. I'm all ears.
> 
Fully understand and agree that the idea is to clear the ambiguaty.
My concern is that we don't use ethdev id, from application ethdev has only
ports, so what is the id? (if we keep this, we should document that the id is the
port) 
What about ETHDEV_PORT and ESWITCH_PORT?

Best,
Ori
> >
> >> +};
> >> +
> >> +/** Default mask for RTE_FLOW_ITEM_TYPE_ETHDEV */ #ifndef
> >> __cplusplus
> >> +static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask
> = {
> >> +	.id = 0xffff,
> >> +};
> >> +#endif
> >> +
> >>   /**
> >>    * Matching pattern item definition.
> >>    *
> >> --
> >> 2.30.2
> 
> --
> Ivan M

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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-03 21:09         ` Ori Kam
@ 2021-10-04  0:00           ` Ivan Malov
  2021-10-04 10:47             ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-04  0:00 UTC (permalink / raw)
  To: Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ori,

On 04/10/2021 00:09, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>> Subject: Re: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>
>> Hi Ori,
>>
>> On 03/10/2021 14:52, Ori Kam wrote:
>>> Hi Andrew and Ivan,
>>>
>>>> -----Original Message-----
>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>>>
>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>
>>>> For use with "transfer" flows. Supposed to match traffic transmitted
>>>> by the DPDK application via the specified ethdev, at e-switch level.
>>>>
>>>> Must not be combined with attributes "ingress" / "egress".
>>>>
>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>> ---
>>>
>>> [Snip]
>>>
>>>>    /** Generate flow_action[] entry. */ diff --git
>>>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>> 7b1ed7f110..880502098e 100644
>>>> --- a/lib/ethdev/rte_flow.h
>>>> +++ b/lib/ethdev/rte_flow.h
>>>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>>>    	 * @see struct rte_flow_item_conntrack.
>>>>    	 */
>>>>    	RTE_FLOW_ITEM_TYPE_CONNTRACK,
>>>> +
>>>> +	/**
>>>> +	 * [META]
>>>> +	 *
>>>> +	 * Matches traffic at e-switch going from (sent by) the given ethdev.
>>>> +	 *
>>>> +	 * @see struct rte_flow_item_ethdev
>>>> +	 */
>>>> +	RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>>    };
>>>>
>>>>    /**
>>>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>>>> rte_flow_item_conntrack_mask = {  };  #endif
>>>>
>>>> +/**
>>>> + * @warning
>>>> + * @b EXPERIMENTAL: this structure may change without prior notice
>>>> + *
>>>> + * Provides an ethdev ID for use with items which are as follows:
>>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
>>>> + */
>>>> +struct rte_flow_item_ethdev {
>>>> +	uint16_t id; /**< Ethdev ID */
>>>
>>> True for all above uses,
>>> should this be renamed to port?
>>
>> I'd not rename it to "port". The very idea of this series is to disambiguate
>> things. This structure is shared between primitives ETHDEV and
>> ESWITCH_PORT. If we go for "port", then in conjunction with ESWITCH_PORT
>> the structure name may trick readers into thinking that the ID in question is
>> the own ID of the e-switch port itself. But in fact this ID is an ethdev ID which
>> is associated with the e-switch port.
>>
>> Should you wish to elaborate on your concerns with regard to naming, please
>> do so. I'm all ears.
>>
> Fully understand and agree that the idea is to clear the ambiguaty.
> My concern is that we don't use ethdev id, from application ethdev has only
> ports, so what is the id? (if we keep this, we should document that the id is the
> port)
> What about ETHDEV_PORT and ESWITCH_PORT?

I understand that, technically, the only ports which the application can 
really interface with are ethdevs. So, terms "ethdev" and "port" may 
appear synonymous to the application - you are right on that. But, given 
the fact that we have some primitives like PHY_PORT and the likes, which 
also have "PORT" in their names, I'd rather go for "ethdev" as more 
precise term.

But let me assure you: I'm not saying that my opinion should prevail. 
I'm giving more thoughts to this in the background. Maybe Andrew can 
join this conversation as well.

> 
> Best,
> Ori
>>>
>>>> +};
>>>> +
>>>> +/** Default mask for RTE_FLOW_ITEM_TYPE_ETHDEV */ #ifndef
>>>> __cplusplus
>>>> +static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask
>> = {
>>>> +	.id = 0xffff,
>>>> +};
>>>> +#endif
>>>> +
>>>>    /**
>>>>     * Matching pattern item definition.
>>>>     *
>>>> --
>>>> 2.30.2
>>
>> --
>> Ivan M

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-03 18:10       ` Ivan Malov
@ 2021-10-04  5:45         ` Ori Kam
  2021-10-04 11:05           ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-04  5:45 UTC (permalink / raw)
  To: Ivan Malov, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Sent: Sunday, October 3, 2021 9:11 PM
> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> 
> 
> 
> On 03/10/2021 15:40, Ori Kam wrote:
> > Hi Andrew and Ivan,
> >
> >> -----Original Message-----
> >> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >> Sent: Friday, October 1, 2021 4:47 PM
> >> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> >>
> >> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >>
> >> For use with "transfer" flows. Supposed to match traffic entering the
> >> e-switch from the external world (network, guests) via the port which
> >> is logically connected with the given ethdev.
> >>
> >> Must not be combined with attributes "ingress" / "egress".
> >>
> >> This item is meant to use the same structure as ethdev item.
> >>
> >
> > In case the app is not working with representors, meaning each switch
> > port is mapped to ethdev.
> > both items (ethdev and eswitch port ) have the same meaning?
> 
> No. Ethdev means ethdev, and e-switch port is the point where this ethdev
> is plugged to. For example, "transfer + ESWITCH_PORT" for a regular PF
> ethdev typically means the network port (maybe you can recall the idea that
> a PF ethdev "represents" the network port it's associated with).
> 
> I believe, that diagrams which these patches add to
> "doc/guides/prog_guide/rte_flow.rst" may come in handy to understand the
> meaning. Also, you can take a look at our larger diagram from the Sep 14
> gathering.
> 

Lets look at the following system:
E-Switch has 3 ports - PF, VF1, VF2
The ports are distributed as follows:
DPDK application:
ethdev(0) pf,
ethdev(1) representor to VF1
ethdev(2) representor to VF2
ethdev(3) VF1

VM:
VF2

As we know all representors are realy connected to the PF(at least in this example)

So matching on ethdev(3)  means matching on traffic sent from DPDK port 3 right?
And matching on eswitch_port(3) means matching in traffic that goes into VF1 which
is the same traffic as ethdev(3) right?

Matching on ethdev(1) means matching on the PF port in the E-Switch but with some
metadata that marks the traffic as coming from DPDK port 1 and not from VF1 E-Switch
port right?

While matching on eswitch_port(2) means matching on traffic coming from the VM right?
 
> >
> >> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >> ---
> >>   app/test-pmd/cmdline_flow.c                 | 27 +++++++++++++++++++++
> >>   doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
> >>   doc/guides/rel_notes/release_21_11.rst      |  2 +-
> >>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
> >>   lib/ethdev/rte_flow.c                       |  1 +
> >>   lib/ethdev/rte_flow.h                       | 12 ++++++++-
> >>   6 files changed, 66 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-
> pmd/cmdline_flow.c
> >> index e05b0d83d2..188d0ee39d 100644
> >> --- a/app/test-pmd/cmdline_flow.c
> >> +++ b/app/test-pmd/cmdline_flow.c
> >> @@ -308,6 +308,8 @@ enum index {
> >>   	ITEM_POL_POLICY,
> >>   	ITEM_ETHDEV,
> >>   	ITEM_ETHDEV_ID,
> >> +	ITEM_ESWITCH_PORT,
> >> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> >
> > Like my comment from previous patch, I'm not sure the correct
> > term for ETHDEV is ID is should be port.
> 
> Please see my reply in the previous thread. "ethdev" here is an
> "anchor", a "beacon" of sorts which allows either to refer namely to
> this ethdev or to the e-switch port associated with it.
> 
> >
> >>
> >>   	/* Validate/create actions. */
> >>   	ACTIONS,
> >> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
> >>   	ITEM_INTEGRITY,
> >>   	ITEM_CONNTRACK,
> >>   	ITEM_ETHDEV,
> >> +	ITEM_ESWITCH_PORT,
> >>   	END_SET,
> >>   	ZERO,
> >>   };
> >> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
> >>   	ZERO,
> >>   };
> >>
> >> +static const enum index item_eswitch_port[] = {
> >> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> >> +	ITEM_NEXT,
> >> +	ZERO,
> >> +};
> >> +
> >>   static const enum index next_action[] = {
> >>   	ACTION_END,
> >>   	ACTION_VOID,
> >> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
> >>   			     item_param),
> >>   		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> id)),
> >>   	},
> >> +	[ITEM_ESWITCH_PORT] = {
> >> +		.name = "eswitch_port",
> >> +		.help = "match traffic at e-switch going from the external port
> >> associated with the given ethdev",
> >
> > Missing the word logically since if we are talking about representor the
> connected port
> > is the PF while we want to match traffic on one of the FVs.
> 
> Doesn't the word "external" say it all?
> 
> Representor Ethdev <--> Admin ethdev's PF <--> E-Switch <--> VF
> (external / the most remote endpoint).
> 

Until the last comment External had totally different meaning to me.
I think you should add some place the meaning of external or use
the most remote endpoint.

> >
> >> +		.priv = PRIV_ITEM(ESWITCH_PORT,
> >> +				  sizeof(struct rte_flow_item_ethdev)),
> >> +		.next = NEXT(item_eswitch_port),
> >> +		.call = parse_vc,
> >> +	},
> >> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
> >> +		.name = "ethdev_id",
> >> +		.help = "ethdev ID",
> >> +		.next = NEXT(item_eswitch_port,
> >> NEXT_ENTRY(COMMON_UNSIGNED),
> >> +			     item_param),
> >> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> id)),
> >> +	},
> >>   	/* Validate/create actions. */
> >>   	[ACTIONS] = {
> >>   		.name = "actions",
> >> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
> >> rte_flow_item *item)
> >>   	case RTE_FLOW_ITEM_TYPE_ETHDEV:
> >>   		mask = &rte_flow_item_ethdev_mask;
> >>   		break;
> >> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
> >> +		mask = &rte_flow_item_ethdev_mask;
> >> +		break;
> >
> > Not sure maybe merged the two cases?
> 
> A noble idea.
> 
> >
> >>   	default:
> >>   		break;
> >>   	}
> >> diff --git a/doc/guides/prog_guide/rte_flow.rst
> >> b/doc/guides/prog_guide/rte_flow.rst
> >> index ab628d9139..292bb42410 100644
> >> --- a/doc/guides/prog_guide/rte_flow.rst
> >> +++ b/doc/guides/prog_guide/rte_flow.rst
> >> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**. Attributes
> >> **ingress** and
> >>      | ``mask`` | ``id``   | zeroed for wildcard match |
> >>      +----------+----------+---------------------------+
> >>
> >> +Item: ``ESWITCH_PORT``
> >> +^^^^^^^^^^^^^^^^^^^^^^
> >> +
> >> +Matches traffic at e-switch going from the external port associated
> >> +with the given ethdev, for example, traffic from net. port or guest.
> >
> > Maybe replace external with e-switch?
> 
> The word "e-switch" is already here. Basically, all "external" ports are
> "e-switch external ports" = ports which connect the e-switch with
> non-DPDK world: network ports, VFs passed to guests, etc.
> 

Please see comment above, the word external is not clearly defined.

> >
> >> +
> >> +::
> >> +
> >> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External
> Port)
> >> +   *    :  SW                 :   Logical                    Net / Guest :
> >> +   *    :                     :                                          :
> >> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
> >> +   *
> >> +   *    [] shows the effective ("transfer") standpoint, the match engine;
> >> +   *    << shows the traffic flow in question hitting the match engine;
> >> +   *    ~~ shows logical interconnects between the endpoints.
> >> +
> >
> > I'm not sure I understand this diagram.
> 
> Thanks for the feedback. I have no way with drawing fancy diagrams, so
> this one may not be ideal, yes. But could you please elaborate on your
> concerns. Maybe you understand it the right way but just unsure. If you
> describe what you see when looking at the diagram, I'll be able to
> either confirm your vision or debunk any misunderstanding and possibly
> improve the drawing.
> 


I will try,
Ethdev is the port that the application sees in DPDK right?
Internal port is what the PMD sees, for example in case of representor it will see the PF port.
External (also due to a drawing in one of your comments) is the E-Switch end point.
So this drawing shows that the app select the external port that is connected to the
internal port which is connected to the ethdev port?

Thanks,
Ori
> >
> >> +Use this with attribute **transfer**. Attributes **ingress** and
> >> +**egress** (`Attribute: Traffic direction`_) must not be used.
> >> +
> >> +This item is meant to use the same structure as `Item: ETHDEV`_.
> >> +
> >>   Actions
> >>   ~~~~~~~
> >>
> >> diff --git a/doc/guides/rel_notes/release_21_11.rst
> >> b/doc/guides/rel_notes/release_21_11.rst
> >> index 91631adb4e..b2b27de3f0 100644
> >> --- a/doc/guides/rel_notes/release_21_11.rst
> >> +++ b/doc/guides/rel_notes/release_21_11.rst
> >> @@ -167,7 +167,7 @@ API Changes
> >>      Also, make sure to start the actual text at the margin.
> >>
> =======================================================
> >>
> >> -* ethdev: Added item ``ETHDEV`` to flow API.
> >> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
> >>
> >>   * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
> >>     rte_cryptodev_is_valid_dev as it can be used by the application as diff --
> git
> >> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> index 6d5de5457c..9a5c2a2d82 100644
> >> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> @@ -3824,6 +3824,10 @@ This section lists supported pattern items and
> >> their attributes, if any.
> >>
> >>     - ``id {unsigned}``: ethdev ID
> >>
> >> +- ``eswitch_port``: match traffic at e-switch going from the external
> >> +port associated with the given ethdev
> >> +
> >> +  - ``ethdev_id {unsigned}``: ethdev ID
> >> +
> >>   Actions list
> >>   ^^^^^^^^^^^^
> >>
> >> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> >> 84eb61cb6c..c4aea5625f 100644
> >> --- a/lib/ethdev/rte_flow.c
> >> +++ b/lib/ethdev/rte_flow.c
> >> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
> >> rte_flow_desc_item[] = {
> >>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
> >>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> >>   	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
> >> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
> >> rte_flow_item_ethdev)),
> >>   };
> >>
> >>   /** Generate flow_action[] entry. */
> >> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >> 880502098e..1a7e4c2e3d 100644
> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
> >>   	 * @see struct rte_flow_item_ethdev
> >>   	 */
> >>   	RTE_FLOW_ITEM_TYPE_ETHDEV,
> >> +
> >> +	/**
> >> +	 * [META]
> >> +	 *
> >> +	 * Matches traffic at e-switch going from the external port associated
> >> +	 * with the given ethdev, for example, traffic from net. port or guest.
> >> +	 *
> >> +	 * @see struct rte_flow_item_ethdev
> >> +	 */
> >> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
> >>   };
> >>
> >>   /**
> >> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
> >> rte_flow_item_conntrack_mask = {
> >>    * @b EXPERIMENTAL: this structure may change without prior notice
> >>    *
> >>    * Provides an ethdev ID for use with items which are as follows:
> >> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
> >> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
> >> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
> >>    */
> >>   struct rte_flow_item_ethdev {
> >>   	uint16_t id; /**< Ethdev ID */
> >> --
> >> 2.30.2
> >
> > Best,
> > Ori
> >
> 
> --
> Ivan M

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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-04  0:00           ` Ivan Malov
@ 2021-10-04 10:47             ` Andrew Rybchenko
  2021-10-04 11:08               ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-04 10:47 UTC (permalink / raw)
  To: Ivan Malov, Ori Kam, Xiaoyun Li, NBU-Contact-Thomas Monjalon,
	Ferruh Yigit
  Cc: dev

On 10/4/21 3:00 AM, Ivan Malov wrote:
> Hi Ori,
> 
> On 04/10/2021 00:09, Ori Kam wrote:
>> Hi Ivan,
>>
>>> -----Original Message-----
>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>> Subject: Re: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>>
>>> Hi Ori,
>>>
>>> On 03/10/2021 14:52, Ori Kam wrote:
>>>> Hi Andrew and Ivan,
>>>>
>>>>> -----Original Message-----
>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>>> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>>>>
>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>
>>>>> For use with "transfer" flows. Supposed to match traffic transmitted
>>>>> by the DPDK application via the specified ethdev, at e-switch level.
>>>>>
>>>>> Must not be combined with attributes "ingress" / "egress".
>>>>>
>>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>> ---
>>>>
>>>> [Snip]
>>>>
>>>>>    /** Generate flow_action[] entry. */ diff --git
>>>>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>>> 7b1ed7f110..880502098e 100644
>>>>> --- a/lib/ethdev/rte_flow.h
>>>>> +++ b/lib/ethdev/rte_flow.h
>>>>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>>>>         * @see struct rte_flow_item_conntrack.
>>>>>         */
>>>>>        RTE_FLOW_ITEM_TYPE_CONNTRACK,
>>>>> +
>>>>> +    /**
>>>>> +     * [META]
>>>>> +     *
>>>>> +     * Matches traffic at e-switch going from (sent by) the given
>>>>> ethdev.
>>>>> +     *
>>>>> +     * @see struct rte_flow_item_ethdev
>>>>> +     */
>>>>> +    RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>>>    };
>>>>>
>>>>>    /**
>>>>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>>>>> rte_flow_item_conntrack_mask = {  };  #endif
>>>>>
>>>>> +/**
>>>>> + * @warning
>>>>> + * @b EXPERIMENTAL: this structure may change without prior notice
>>>>> + *
>>>>> + * Provides an ethdev ID for use with items which are as follows:
>>>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
>>>>> + */
>>>>> +struct rte_flow_item_ethdev {
>>>>> +    uint16_t id; /**< Ethdev ID */
>>>>
>>>> True for all above uses,
>>>> should this be renamed to port?
>>>
>>> I'd not rename it to "port". The very idea of this series is to
>>> disambiguate
>>> things. This structure is shared between primitives ETHDEV and
>>> ESWITCH_PORT. If we go for "port", then in conjunction with ESWITCH_PORT
>>> the structure name may trick readers into thinking that the ID in
>>> question is
>>> the own ID of the e-switch port itself. But in fact this ID is an
>>> ethdev ID which
>>> is associated with the e-switch port.
>>>
>>> Should you wish to elaborate on your concerns with regard to naming,
>>> please
>>> do so. I'm all ears.
>>>
>> Fully understand and agree that the idea is to clear the ambiguaty.
>> My concern is that we don't use ethdev id, from application ethdev has
>> only
>> ports, so what is the id? (if we keep this, we should document that
>> the id is the
>> port)
>> What about ETHDEV_PORT and ESWITCH_PORT?
> 
> I understand that, technically, the only ports which the application can
> really interface with are ethdevs. So, terms "ethdev" and "port" may
> appear synonymous to the application - you are right on that. But, given
> the fact that we have some primitives like PHY_PORT and the likes, which
> also have "PORT" in their names, I'd rather go for "ethdev" as more
> precise term.
> 
> But let me assure you: I'm not saying that my opinion should prevail.
> I'm giving more thoughts to this in the background. Maybe Andrew can
> join this conversation as well.

As far as I can see ethdev API uses 'port_id' everywhere to
refer to ethdev port by its number. So, I suggest

struct rte_flow_item_ethdev {
    uint16_t port_id; /**< ethdev port ID */
};

Basically I agree with Ori, that just "id" is a bit confusing
even when it is a member of the _ethdev structure, but I'd
prepend "port_"  a field name to sync with ethdev API which
uses port_id. So, we have ethdev->port_id.

Andrew.

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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-04  5:45         ` Ori Kam
@ 2021-10-04 11:05           ` Ivan Malov
  2021-10-04 11:37             ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-04 11:05 UTC (permalink / raw)
  To: Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ori,

On 04/10/2021 08:45, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>> Sent: Sunday, October 3, 2021 9:11 PM
>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>
>>
>>
>> On 03/10/2021 15:40, Ori Kam wrote:
>>> Hi Andrew and Ivan,
>>>
>>>> -----Original Message-----
>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>>>
>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>
>>>> For use with "transfer" flows. Supposed to match traffic entering the
>>>> e-switch from the external world (network, guests) via the port which
>>>> is logically connected with the given ethdev.
>>>>
>>>> Must not be combined with attributes "ingress" / "egress".
>>>>
>>>> This item is meant to use the same structure as ethdev item.
>>>>
>>>
>>> In case the app is not working with representors, meaning each switch
>>> port is mapped to ethdev.
>>> both items (ethdev and eswitch port ) have the same meaning?
>>
>> No. Ethdev means ethdev, and e-switch port is the point where this ethdev
>> is plugged to. For example, "transfer + ESWITCH_PORT" for a regular PF
>> ethdev typically means the network port (maybe you can recall the idea that
>> a PF ethdev "represents" the network port it's associated with).
>>
>> I believe, that diagrams which these patches add to
>> "doc/guides/prog_guide/rte_flow.rst" may come in handy to understand the
>> meaning. Also, you can take a look at our larger diagram from the Sep 14
>> gathering.
>>
> 
> Lets look at the following system:
> E-Switch has 3 ports - PF, VF1, VF2
> The ports are distributed as follows:
> DPDK application:
> ethdev(0) pf,
> ethdev(1) representor to VF1
> ethdev(2) representor to VF2
> ethdev(3) VF1
> 
> VM:
> VF2
> 
> As we know all representors are realy connected to the PF(at least in this example)

This example tries to say that the e-switch has 3 ports in total, and, 
given your explanation, one may indeed agree that *in this example* 
representors re-use e-switch port of ethdev=0 (with some metadata to 
distinguish packets, etc.). But one can hardly assume that *all* 
representors with any vendor's NIC are connected to the e-switch the 
same way. It's vendor specific. Well, at least, applications don't have 
this knowledge and don't need to.

> 
> So matching on ethdev(3)  means matching on traffic sent from DPDK port 3 right?

Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks 
like we're on the same page here.

> And matching on eswitch_port(3) means matching in traffic that goes into VF1 which
> is the same traffic as ethdev(3) right?

I didn't catch the thought about "the same traffic". Direction is not 
the same. Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK 
port 1.

Yes, in this case neither of the ports (1, 3) is truly "external" (they 
both interface the DPDK application), but, the thing is, they're 
"external" *to each other* in the sense that they sit at the opposite 
ends of the wire.

> 
> Matching on ethdev(1) means matching on the PF port in the E-Switch but with some
> metadata that marks the traffic as coming from DPDK port 1 and not from VF1 E-Switch
> port right?

That's vendor specific. The application doesn't have to know how exactly 
this particular ethdev is connected to the e-switch - whether it re-uses 
the PF's e-switch port or has its own. The e-switch port that connects 
the ethdev with the e-switch is just assumed to exist logically.

> 
> While matching on eswitch_port(2) means matching on traffic coming from the VM right?

Right.

>   
>>>
>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>> ---
>>>>    app/test-pmd/cmdline_flow.c                 | 27 +++++++++++++++++++++
>>>>    doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
>>>>    doc/guides/rel_notes/release_21_11.rst      |  2 +-
>>>>    doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
>>>>    lib/ethdev/rte_flow.c                       |  1 +
>>>>    lib/ethdev/rte_flow.h                       | 12 ++++++++-
>>>>    6 files changed, 66 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-
>> pmd/cmdline_flow.c
>>>> index e05b0d83d2..188d0ee39d 100644
>>>> --- a/app/test-pmd/cmdline_flow.c
>>>> +++ b/app/test-pmd/cmdline_flow.c
>>>> @@ -308,6 +308,8 @@ enum index {
>>>>    	ITEM_POL_POLICY,
>>>>    	ITEM_ETHDEV,
>>>>    	ITEM_ETHDEV_ID,
>>>> +	ITEM_ESWITCH_PORT,
>>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
>>>
>>> Like my comment from previous patch, I'm not sure the correct
>>> term for ETHDEV is ID is should be port.
>>
>> Please see my reply in the previous thread. "ethdev" here is an
>> "anchor", a "beacon" of sorts which allows either to refer namely to
>> this ethdev or to the e-switch port associated with it.
>>
>>>
>>>>
>>>>    	/* Validate/create actions. */
>>>>    	ACTIONS,
>>>> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
>>>>    	ITEM_INTEGRITY,
>>>>    	ITEM_CONNTRACK,
>>>>    	ITEM_ETHDEV,
>>>> +	ITEM_ESWITCH_PORT,
>>>>    	END_SET,
>>>>    	ZERO,
>>>>    };
>>>> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
>>>>    	ZERO,
>>>>    };
>>>>
>>>> +static const enum index item_eswitch_port[] = {
>>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
>>>> +	ITEM_NEXT,
>>>> +	ZERO,
>>>> +};
>>>> +
>>>>    static const enum index next_action[] = {
>>>>    	ACTION_END,
>>>>    	ACTION_VOID,
>>>> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
>>>>    			     item_param),
>>>>    		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>> id)),
>>>>    	},
>>>> +	[ITEM_ESWITCH_PORT] = {
>>>> +		.name = "eswitch_port",
>>>> +		.help = "match traffic at e-switch going from the external port
>>>> associated with the given ethdev",
>>>
>>> Missing the word logically since if we are talking about representor the
>> connected port
>>> is the PF while we want to match traffic on one of the FVs.
>>
>> Doesn't the word "external" say it all?
>>
>> Representor Ethdev <--> Admin ethdev's PF <--> E-Switch <--> VF
>> (external / the most remote endpoint).
>>
> 
> Until the last comment External had totally different meaning to me.
> I think you should add some place the meaning of external or use
> the most remote endpoint.

We'll keep this in mind. Given your above example (when both VF and its 
representor) are plugged to the DPDK application, "external" may sound a 
bit off, but maybe it can be retained and just clarified as the "most 
remote endpoint" in the e-switch with respect to the ethdev in question.

> 
>>>
>>>> +		.priv = PRIV_ITEM(ESWITCH_PORT,
>>>> +				  sizeof(struct rte_flow_item_ethdev)),
>>>> +		.next = NEXT(item_eswitch_port),
>>>> +		.call = parse_vc,
>>>> +	},
>>>> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
>>>> +		.name = "ethdev_id",
>>>> +		.help = "ethdev ID",
>>>> +		.next = NEXT(item_eswitch_port,
>>>> NEXT_ENTRY(COMMON_UNSIGNED),
>>>> +			     item_param),
>>>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>> id)),
>>>> +	},
>>>>    	/* Validate/create actions. */
>>>>    	[ACTIONS] = {
>>>>    		.name = "actions",
>>>> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
>>>> rte_flow_item *item)
>>>>    	case RTE_FLOW_ITEM_TYPE_ETHDEV:
>>>>    		mask = &rte_flow_item_ethdev_mask;
>>>>    		break;
>>>> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
>>>> +		mask = &rte_flow_item_ethdev_mask;
>>>> +		break;
>>>
>>> Not sure maybe merged the two cases?
>>
>> A noble idea.
>>
>>>
>>>>    	default:
>>>>    		break;
>>>>    	}
>>>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>>>> b/doc/guides/prog_guide/rte_flow.rst
>>>> index ab628d9139..292bb42410 100644
>>>> --- a/doc/guides/prog_guide/rte_flow.rst
>>>> +++ b/doc/guides/prog_guide/rte_flow.rst
>>>> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**. Attributes
>>>> **ingress** and
>>>>       | ``mask`` | ``id``   | zeroed for wildcard match |
>>>>       +----------+----------+---------------------------+
>>>>
>>>> +Item: ``ESWITCH_PORT``
>>>> +^^^^^^^^^^^^^^^^^^^^^^
>>>> +
>>>> +Matches traffic at e-switch going from the external port associated
>>>> +with the given ethdev, for example, traffic from net. port or guest.
>>>
>>> Maybe replace external with e-switch?
>>
>> The word "e-switch" is already here. Basically, all "external" ports are
>> "e-switch external ports" = ports which connect the e-switch with
>> non-DPDK world: network ports, VFs passed to guests, etc.
>>
> 
> Please see comment above, the word external is not clearly defined. >
>>>
>>>> +
>>>> +::
>>>> +
>>>> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External
>> Port)
>>>> +   *    :  SW                 :   Logical                    Net / Guest :
>>>> +   *    :                     :                                          :
>>>> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
>>>> +   *
>>>> +   *    [] shows the effective ("transfer") standpoint, the match engine;
>>>> +   *    << shows the traffic flow in question hitting the match engine;
>>>> +   *    ~~ shows logical interconnects between the endpoints.
>>>> +
>>>
>>> I'm not sure I understand this diagram.
>>
>> Thanks for the feedback. I have no way with drawing fancy diagrams, so
>> this one may not be ideal, yes. But could you please elaborate on your
>> concerns. Maybe you understand it the right way but just unsure. If you
>> describe what you see when looking at the diagram, I'll be able to
>> either confirm your vision or debunk any misunderstanding and possibly
>> improve the drawing.
>>
> 
> 
> I will try,
> Ethdev is the port that the application sees in DPDK right?

Exactly.

> Internal port is what the PMD sees, for example in case of representor it will see the PF port.

Vendor-specific, but, yes, let's assume that.

> External (also due to a drawing in one of your comments) is the E-Switch end point.
> So this drawing shows that the app select the external port that is connected to the
> internal port which is connected to the ethdev port?

So what's the problem?

Ethdev ----- E-switch port A -- ... --- E-switch port B------ VF

So, saying "transfer + ESWITCH_PORT" here implies the e-switch port B.
How do we name it? "External"? "The most remote"? Any other options?

> 
> Thanks,
> Ori
>>>
>>>> +Use this with attribute **transfer**. Attributes **ingress** and
>>>> +**egress** (`Attribute: Traffic direction`_) must not be used.
>>>> +
>>>> +This item is meant to use the same structure as `Item: ETHDEV`_.
>>>> +
>>>>    Actions
>>>>    ~~~~~~~
>>>>
>>>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>>>> b/doc/guides/rel_notes/release_21_11.rst
>>>> index 91631adb4e..b2b27de3f0 100644
>>>> --- a/doc/guides/rel_notes/release_21_11.rst
>>>> +++ b/doc/guides/rel_notes/release_21_11.rst
>>>> @@ -167,7 +167,7 @@ API Changes
>>>>       Also, make sure to start the actual text at the margin.
>>>>
>> =======================================================
>>>>
>>>> -* ethdev: Added item ``ETHDEV`` to flow API.
>>>> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
>>>>
>>>>    * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
>>>>      rte_cryptodev_is_valid_dev as it can be used by the application as diff --
>> git
>>>> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> index 6d5de5457c..9a5c2a2d82 100644
>>>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> @@ -3824,6 +3824,10 @@ This section lists supported pattern items and
>>>> their attributes, if any.
>>>>
>>>>      - ``id {unsigned}``: ethdev ID
>>>>
>>>> +- ``eswitch_port``: match traffic at e-switch going from the external
>>>> +port associated with the given ethdev
>>>> +
>>>> +  - ``ethdev_id {unsigned}``: ethdev ID
>>>> +
>>>>    Actions list
>>>>    ^^^^^^^^^^^^
>>>>
>>>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>>>> 84eb61cb6c..c4aea5625f 100644
>>>> --- a/lib/ethdev/rte_flow.c
>>>> +++ b/lib/ethdev/rte_flow.c
>>>> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
>>>> rte_flow_desc_item[] = {
>>>>    	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>>>    	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>>>>    	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
>>>> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
>>>> rte_flow_item_ethdev)),
>>>>    };
>>>>
>>>>    /** Generate flow_action[] entry. */
>>>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>> 880502098e..1a7e4c2e3d 100644
>>>> --- a/lib/ethdev/rte_flow.h
>>>> +++ b/lib/ethdev/rte_flow.h
>>>> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
>>>>    	 * @see struct rte_flow_item_ethdev
>>>>    	 */
>>>>    	RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>> +
>>>> +	/**
>>>> +	 * [META]
>>>> +	 *
>>>> +	 * Matches traffic at e-switch going from the external port associated
>>>> +	 * with the given ethdev, for example, traffic from net. port or guest.
>>>> +	 *
>>>> +	 * @see struct rte_flow_item_ethdev
>>>> +	 */
>>>> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
>>>>    };
>>>>
>>>>    /**
>>>> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
>>>> rte_flow_item_conntrack_mask = {
>>>>     * @b EXPERIMENTAL: this structure may change without prior notice
>>>>     *
>>>>     * Provides an ethdev ID for use with items which are as follows:
>>>> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
>>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
>>>>     */
>>>>    struct rte_flow_item_ethdev {
>>>>    	uint16_t id; /**< Ethdev ID */
>>>> --
>>>> 2.30.2
>>>
>>> Best,
>>> Ori
>>>
>>
>> --
>> Ivan M

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v1 01/12] ethdev: add ethdev item to flow API
  2021-10-04 10:47             ` Andrew Rybchenko
@ 2021-10-04 11:08               ` Ivan Malov
  0 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-04 11:08 UTC (permalink / raw)
  To: Andrew Rybchenko, Ori Kam, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Andrew, Ori,

On 04/10/2021 13:47, Andrew Rybchenko wrote:
> On 10/4/21 3:00 AM, Ivan Malov wrote:
>> Hi Ori,
>>
>> On 04/10/2021 00:09, Ori Kam wrote:
>>> Hi Ivan,
>>>
>>>> -----Original Message-----
>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>> Subject: Re: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>>>
>>>> Hi Ori,
>>>>
>>>> On 03/10/2021 14:52, Ori Kam wrote:
>>>>> Hi Andrew and Ivan,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>>>> Subject: [PATCH v1 01/12] ethdev: add ethdev item to flow API
>>>>>>
>>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>>
>>>>>> For use with "transfer" flows. Supposed to match traffic transmitted
>>>>>> by the DPDK application via the specified ethdev, at e-switch level.
>>>>>>
>>>>>> Must not be combined with attributes "ingress" / "egress".
>>>>>>
>>>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>> ---
>>>>>
>>>>> [Snip]
>>>>>
>>>>>>     /** Generate flow_action[] entry. */ diff --git
>>>>>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>>>> 7b1ed7f110..880502098e 100644
>>>>>> --- a/lib/ethdev/rte_flow.h
>>>>>> +++ b/lib/ethdev/rte_flow.h
>>>>>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>>>>>          * @see struct rte_flow_item_conntrack.
>>>>>>          */
>>>>>>         RTE_FLOW_ITEM_TYPE_CONNTRACK,
>>>>>> +
>>>>>> +    /**
>>>>>> +     * [META]
>>>>>> +     *
>>>>>> +     * Matches traffic at e-switch going from (sent by) the given
>>>>>> ethdev.
>>>>>> +     *
>>>>>> +     * @see struct rte_flow_item_ethdev
>>>>>> +     */
>>>>>> +    RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>>>>     };
>>>>>>
>>>>>>     /**
>>>>>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>>>>>> rte_flow_item_conntrack_mask = {  };  #endif
>>>>>>
>>>>>> +/**
>>>>>> + * @warning
>>>>>> + * @b EXPERIMENTAL: this structure may change without prior notice
>>>>>> + *
>>>>>> + * Provides an ethdev ID for use with items which are as follows:
>>>>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV.
>>>>>> + */
>>>>>> +struct rte_flow_item_ethdev {
>>>>>> +    uint16_t id; /**< Ethdev ID */
>>>>>
>>>>> True for all above uses,
>>>>> should this be renamed to port?
>>>>
>>>> I'd not rename it to "port". The very idea of this series is to
>>>> disambiguate
>>>> things. This structure is shared between primitives ETHDEV and
>>>> ESWITCH_PORT. If we go for "port", then in conjunction with ESWITCH_PORT
>>>> the structure name may trick readers into thinking that the ID in
>>>> question is
>>>> the own ID of the e-switch port itself. But in fact this ID is an
>>>> ethdev ID which
>>>> is associated with the e-switch port.
>>>>
>>>> Should you wish to elaborate on your concerns with regard to naming,
>>>> please
>>>> do so. I'm all ears.
>>>>
>>> Fully understand and agree that the idea is to clear the ambiguaty.
>>> My concern is that we don't use ethdev id, from application ethdev has
>>> only
>>> ports, so what is the id? (if we keep this, we should document that
>>> the id is the
>>> port)
>>> What about ETHDEV_PORT and ESWITCH_PORT?
>>
>> I understand that, technically, the only ports which the application can
>> really interface with are ethdevs. So, terms "ethdev" and "port" may
>> appear synonymous to the application - you are right on that. But, given
>> the fact that we have some primitives like PHY_PORT and the likes, which
>> also have "PORT" in their names, I'd rather go for "ethdev" as more
>> precise term.
>>
>> But let me assure you: I'm not saying that my opinion should prevail.
>> I'm giving more thoughts to this in the background. Maybe Andrew can
>> join this conversation as well.
> 
> As far as I can see ethdev API uses 'port_id' everywhere to
> refer to ethdev port by its number. So, I suggest
> 
> struct rte_flow_item_ethdev {
>      uint16_t port_id; /**< ethdev port ID */
> };
> 
> Basically I agree with Ori, that just "id" is a bit confusing
> even when it is a member of the _ethdev structure, but I'd
> prepend "port_"  a field name to sync with ethdev API which
> uses port_id. So, we have ethdev->port_id.

Ack

> 
> Andrew.
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [EXT] [PATCH v1 11/12] net/octeontx2: support ethdev flow action
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 11/12] net/octeontx2: support ethdev " Andrew Rybchenko
@ 2021-10-04 11:13     ` Kiran Kumar Kokkilagadda
  2021-10-04 12:45       ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Kiran Kumar Kokkilagadda @ 2021-10-04 11:13 UTC (permalink / raw)
  To: Andrew Rybchenko, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov



> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, October 1, 2021 7:17 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram
> <ndabilpuram@marvell.com>; Kiran Kumar Kokkilagadda
> <kirankumark@marvell.com>
> Cc: dev@dpdk.org; Ori Kam <orika@nvidia.com>; Thomas Monjalon
> <thomas@monjalon.net>; Ferruh Yigit <ferruh.yigit@intel.com>; Ivan Malov
> <ivan.malov@oktetlabs.ru>
> Subject: [EXT] [PATCH v1 11/12] net/octeontx2: support ethdev flow action
> 
> External Email
> 
> ----------------------------------------------------------------------
> PORT_ID action implementation works for ingress only and has the same
> semantics as ETHDEV action.

Please update the documentation also.


> 
> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
>  drivers/net/octeontx2/otx2_flow_parse.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/octeontx2/otx2_flow_parse.c
> b/drivers/net/octeontx2/otx2_flow_parse.c
> index 63a33142a5..5dd8464ec9 100644
> --- a/drivers/net/octeontx2/otx2_flow_parse.c
> +++ b/drivers/net/octeontx2/otx2_flow_parse.c
> @@ -900,7 +900,6 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,  {
>  	struct otx2_eth_dev *hw = dev->data->dev_private;
>  	struct otx2_npc_flow_info *npc = &hw->npc_flow;
> -	const struct rte_flow_action_port_id *port_act;
>  	const struct rte_flow_action_count *act_count;
>  	const struct rte_flow_action_mark *act_mark;
>  	const struct rte_flow_action_queue *act_q; @@ -987,9 +986,18 @@
> otx2_flow_parse_actions(struct rte_eth_dev *dev,
>  			break;
> 
>  		case RTE_FLOW_ACTION_TYPE_PORT_ID:
> -			port_act = (const struct rte_flow_action_port_id *)
> -				actions->conf;
> -			port_id = port_act->id;
> +		case RTE_FLOW_ACTION_TYPE_ETHDEV:
> +			if (actions->type ==
> RTE_FLOW_ACTION_TYPE_PORT_ID) {
> +				const struct rte_flow_action_port_id
> *port_act;
> +
> +				port_act = actions->conf;
> +				port_id = port_act->id;
> +			} else {
> +				const struct rte_flow_action_ethdev
> *ethdev_act;
> +
> +				ethdev_act = actions->conf;
> +				port_id = ethdev_act->id;
> +			}
>  			if (rte_eth_dev_get_name_by_port(port_id, if_name)) {
>  				errmsg = "Name not found for output port id";
>  				errcode = EINVAL;
> --
> 2.30.2


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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-04 11:05           ` Ivan Malov
@ 2021-10-04 11:37             ` Ori Kam
  2021-10-04 11:58               ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-04 11:37 UTC (permalink / raw)
  To: Ivan Malov, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Sent: Monday, October 4, 2021 2:06 PM
> Cc: dev@dpdk.org
> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> 
> Hi Ori,
> 
> On 04/10/2021 08:45, Ori Kam wrote:
> > Hi Ivan,
> >
> >> -----Original Message-----
> >> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> >> Sent: Sunday, October 3, 2021 9:11 PM
> >> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
> >> API
> >>
> >>
> >>
> >> On 03/10/2021 15:40, Ori Kam wrote:
> >>> Hi Andrew and Ivan,
> >>>
> >>>> -----Original Message-----
> >>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >>>> Sent: Friday, October 1, 2021 4:47 PM
> >>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> >>>>
> >>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >>>>
> >>>> For use with "transfer" flows. Supposed to match traffic entering
> >>>> the e-switch from the external world (network, guests) via the port
> >>>> which is logically connected with the given ethdev.
> >>>>
> >>>> Must not be combined with attributes "ingress" / "egress".
> >>>>
> >>>> This item is meant to use the same structure as ethdev item.
> >>>>
> >>>
> >>> In case the app is not working with representors, meaning each
> >>> switch port is mapped to ethdev.
> >>> both items (ethdev and eswitch port ) have the same meaning?
> >>
> >> No. Ethdev means ethdev, and e-switch port is the point where this
> >> ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a
> >> regular PF ethdev typically means the network port (maybe you can
> >> recall the idea that a PF ethdev "represents" the network port it's
> associated with).
> >>
> >> I believe, that diagrams which these patches add to
> >> "doc/guides/prog_guide/rte_flow.rst" may come in handy to understand
> >> the meaning. Also, you can take a look at our larger diagram from the
> >> Sep 14 gathering.
> >>
> >
> > Lets look at the following system:
> > E-Switch has 3 ports - PF, VF1, VF2
> > The ports are distributed as follows:
> > DPDK application:
> > ethdev(0) pf,
> > ethdev(1) representor to VF1
> > ethdev(2) representor to VF2
> > ethdev(3) VF1
> >
> > VM:
> > VF2
> >
> > As we know all representors are realy connected to the PF(at least in
> > this example)
> 
> This example tries to say that the e-switch has 3 ports in total, and, given
> your explanation, one may indeed agree that *in this example* representors
> re-use e-switch port of ethdev=0 (with some metadata to distinguish
> packets, etc.). But one can hardly assume that *all* representors with any
> vendor's NIC are connected to the e-switch the same way. It's vendor
> specific. Well, at least, applications don't have this knowledge and don't need
> to.
> 
> >
> > So matching on ethdev(3)  means matching on traffic sent from DPDK port
> 3 right?
> 
> Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks like
> we're on the same page here.
> 

Good.

> > And matching on eswitch_port(3) means matching in traffic that goes
> > into VF1 which is the same traffic as ethdev(3) right?
> 
> I didn't catch the thought about "the same traffic". Direction is not the same.
> Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK port 1.
> 
This is the critical part for my understanding.
Matching on ethdev_id(3) means matching on traffic that is coming from DPDK port3.
So from E-Switch view point it is traffic that goes into VF1?
While matching on E-Switch_port(3) means matching on traffic coming from VF1?

And by the same logic matching on ethdev_id(1) means matching on taffic that was sent
from DPDK port 1 and matching on E-Switch_port(1) means matching on traffic coming from
VF1 

So in this case eswitch_port(3) is equal ot eswitch_port(1) right?
While ethdev(1) is not equal to ethdev(3)

And just to complete the picture, matching on ethdev(2) will result in traffic
coming from the dpdk port and matching on eswitch_port(2) will match
on traffic coming from VF2

> Yes, in this case neither of the ports (1, 3) is truly "external" (they both
> interface the DPDK application), but, the thing is, they're "external" *to each
> other* in the sense that they sit at the opposite ends of the wire.
> 
> >
> > Matching on ethdev(1) means matching on the PF port in the E-Switch but
> with some
> > metadata that marks the traffic as coming from DPDK port 1 and not from
> VF1 E-Switch
> > port right?
> 
> That's vendor specific. The application doesn't have to know how exactly
> this particular ethdev is connected to the e-switch - whether it re-uses
> the PF's e-switch port or has its own. The e-switch port that connects
> the ethdev with the e-switch is just assumed to exist logically.
> 
> >
> > While matching on eswitch_port(2) means matching on traffic coming from
> the VM right?
> 
> Right.
> 

I think the my above question will clear everything for me.

> >
> >>>
> >>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> >>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >>>> ---
> >>>>    app/test-pmd/cmdline_flow.c                 | 27
> +++++++++++++++++++++
> >>>>    doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
> >>>>    doc/guides/rel_notes/release_21_11.rst      |  2 +-
> >>>>    doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
> >>>>    lib/ethdev/rte_flow.c                       |  1 +
> >>>>    lib/ethdev/rte_flow.h                       | 12 ++++++++-
> >>>>    6 files changed, 66 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-
> >> pmd/cmdline_flow.c
> >>>> index e05b0d83d2..188d0ee39d 100644
> >>>> --- a/app/test-pmd/cmdline_flow.c
> >>>> +++ b/app/test-pmd/cmdline_flow.c
> >>>> @@ -308,6 +308,8 @@ enum index {
> >>>>    	ITEM_POL_POLICY,
> >>>>    	ITEM_ETHDEV,
> >>>>    	ITEM_ETHDEV_ID,
> >>>> +	ITEM_ESWITCH_PORT,
> >>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> >>>
> >>> Like my comment from previous patch, I'm not sure the correct
> >>> term for ETHDEV is ID is should be port.
> >>
> >> Please see my reply in the previous thread. "ethdev" here is an
> >> "anchor", a "beacon" of sorts which allows either to refer namely to
> >> this ethdev or to the e-switch port associated with it.
> >>
> >>>
> >>>>
> >>>>    	/* Validate/create actions. */
> >>>>    	ACTIONS,
> >>>> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
> >>>>    	ITEM_INTEGRITY,
> >>>>    	ITEM_CONNTRACK,
> >>>>    	ITEM_ETHDEV,
> >>>> +	ITEM_ESWITCH_PORT,
> >>>>    	END_SET,
> >>>>    	ZERO,
> >>>>    };
> >>>> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
> >>>>    	ZERO,
> >>>>    };
> >>>>
> >>>> +static const enum index item_eswitch_port[] = {
> >>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
> >>>> +	ITEM_NEXT,
> >>>> +	ZERO,
> >>>> +};
> >>>> +
> >>>>    static const enum index next_action[] = {
> >>>>    	ACTION_END,
> >>>>    	ACTION_VOID,
> >>>> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
> >>>>    			     item_param),
> >>>>    		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> >> id)),
> >>>>    	},
> >>>> +	[ITEM_ESWITCH_PORT] = {
> >>>> +		.name = "eswitch_port",
> >>>> +		.help = "match traffic at e-switch going from the external port
> >>>> associated with the given ethdev",
> >>>
> >>> Missing the word logically since if we are talking about representor the
> >> connected port
> >>> is the PF while we want to match traffic on one of the FVs.
> >>
> >> Doesn't the word "external" say it all?
> >>
> >> Representor Ethdev <--> Admin ethdev's PF <--> E-Switch <--> VF
> >> (external / the most remote endpoint).
> >>
> >
> > Until the last comment External had totally different meaning to me.
> > I think you should add some place the meaning of external or use
> > the most remote endpoint.
> 
> We'll keep this in mind. Given your above example (when both VF and its
> representor) are plugged to the DPDK application, "external" may sound a
> bit off, but maybe it can be retained and just clarified as the "most
> remote endpoint" in the e-switch with respect to the ethdev in question.
> 

+1 to the most remote or finding different wording.

> >
> >>>
> >>>> +		.priv = PRIV_ITEM(ESWITCH_PORT,
> >>>> +				  sizeof(struct rte_flow_item_ethdev)),
> >>>> +		.next = NEXT(item_eswitch_port),
> >>>> +		.call = parse_vc,
> >>>> +	},
> >>>> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
> >>>> +		.name = "ethdev_id",
> >>>> +		.help = "ethdev ID",
> >>>> +		.next = NEXT(item_eswitch_port,
> >>>> NEXT_ENTRY(COMMON_UNSIGNED),
> >>>> +			     item_param),
> >>>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> >> id)),
> >>>> +	},
> >>>>    	/* Validate/create actions. */
> >>>>    	[ACTIONS] = {
> >>>>    		.name = "actions",
> >>>> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
> >>>> rte_flow_item *item)
> >>>>    	case RTE_FLOW_ITEM_TYPE_ETHDEV:
> >>>>    		mask = &rte_flow_item_ethdev_mask;
> >>>>    		break;
> >>>> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
> >>>> +		mask = &rte_flow_item_ethdev_mask;
> >>>> +		break;
> >>>
> >>> Not sure maybe merged the two cases?
> >>
> >> A noble idea.
> >>
> >>>
> >>>>    	default:
> >>>>    		break;
> >>>>    	}
> >>>> diff --git a/doc/guides/prog_guide/rte_flow.rst
> >>>> b/doc/guides/prog_guide/rte_flow.rst
> >>>> index ab628d9139..292bb42410 100644
> >>>> --- a/doc/guides/prog_guide/rte_flow.rst
> >>>> +++ b/doc/guides/prog_guide/rte_flow.rst
> >>>> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**.
> Attributes
> >>>> **ingress** and
> >>>>       | ``mask`` | ``id``   | zeroed for wildcard match |
> >>>>       +----------+----------+---------------------------+
> >>>>
> >>>> +Item: ``ESWITCH_PORT``
> >>>> +^^^^^^^^^^^^^^^^^^^^^^
> >>>> +
> >>>> +Matches traffic at e-switch going from the external port associated
> >>>> +with the given ethdev, for example, traffic from net. port or guest.
> >>>
> >>> Maybe replace external with e-switch?
> >>
> >> The word "e-switch" is already here. Basically, all "external" ports are
> >> "e-switch external ports" = ports which connect the e-switch with
> >> non-DPDK world: network ports, VFs passed to guests, etc.
> >>
> >
> > Please see comment above, the word external is not clearly defined. >
> >>>
> >>>> +
> >>>> +::
> >>>> +
> >>>> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External
> >> Port)
> >>>> +   *    :  SW                 :   Logical                    Net / Guest :
> >>>> +   *    :                     :                                          :
> >>>> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
> >>>> +   *
> >>>> +   *    [] shows the effective ("transfer") standpoint, the match engine;
> >>>> +   *    << shows the traffic flow in question hitting the match engine;
> >>>> +   *    ~~ shows logical interconnects between the endpoints.
> >>>> +
> >>>
> >>> I'm not sure I understand this diagram.
> >>
> >> Thanks for the feedback. I have no way with drawing fancy diagrams, so
> >> this one may not be ideal, yes. But could you please elaborate on your
> >> concerns. Maybe you understand it the right way but just unsure. If you
> >> describe what you see when looking at the diagram, I'll be able to
> >> either confirm your vision or debunk any misunderstanding and possibly
> >> improve the drawing.
> >>
> >
> >
> > I will try,
> > Ethdev is the port that the application sees in DPDK right?
> 
> Exactly.
> 
> > Internal port is what the PMD sees, for example in case of representor it
> will see the PF port.
> 
> Vendor-specific, but, yes, let's assume that.
> 
> > External (also due to a drawing in one of your comments) is the E-Switch
> end point.
> > So this drawing shows that the app select the external port that is
> connected to the
> > internal port which is connected to the ethdev port?
> 
> So what's the problem?
> 
> Ethdev ----- E-switch port A -- ... --- E-switch port B------ VF
> 
> So, saying "transfer + ESWITCH_PORT" here implies the e-switch port B.
> How do we name it? "External"? "The most remote"? Any other options?
> 
> >
> > Thanks,
> > Ori
> >>>
> >>>> +Use this with attribute **transfer**. Attributes **ingress** and
> >>>> +**egress** (`Attribute: Traffic direction`_) must not be used.
> >>>> +
> >>>> +This item is meant to use the same structure as `Item: ETHDEV`_.
> >>>> +
> >>>>    Actions
> >>>>    ~~~~~~~
> >>>>
> >>>> diff --git a/doc/guides/rel_notes/release_21_11.rst
> >>>> b/doc/guides/rel_notes/release_21_11.rst
> >>>> index 91631adb4e..b2b27de3f0 100644
> >>>> --- a/doc/guides/rel_notes/release_21_11.rst
> >>>> +++ b/doc/guides/rel_notes/release_21_11.rst
> >>>> @@ -167,7 +167,7 @@ API Changes
> >>>>       Also, make sure to start the actual text at the margin.
> >>>>
> >> =======================================================
> >>>>
> >>>> -* ethdev: Added item ``ETHDEV`` to flow API.
> >>>> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
> >>>>
> >>>>    * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
> >>>>      rte_cryptodev_is_valid_dev as it can be used by the application as
> diff --
> >> git
> >>>> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >>>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >>>> index 6d5de5457c..9a5c2a2d82 100644
> >>>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >>>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >>>> @@ -3824,6 +3824,10 @@ This section lists supported pattern items
> and
> >>>> their attributes, if any.
> >>>>
> >>>>      - ``id {unsigned}``: ethdev ID
> >>>>
> >>>> +- ``eswitch_port``: match traffic at e-switch going from the external
> >>>> +port associated with the given ethdev
> >>>> +
> >>>> +  - ``ethdev_id {unsigned}``: ethdev ID
> >>>> +
> >>>>    Actions list
> >>>>    ^^^^^^^^^^^^
> >>>>
> >>>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> >>>> 84eb61cb6c..c4aea5625f 100644
> >>>> --- a/lib/ethdev/rte_flow.c
> >>>> +++ b/lib/ethdev/rte_flow.c
> >>>> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
> >>>> rte_flow_desc_item[] = {
> >>>>    	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
> >>>>    	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> >>>>    	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
> >>>> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
> >>>> rte_flow_item_ethdev)),
> >>>>    };
> >>>>
> >>>>    /** Generate flow_action[] entry. */
> >>>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >>>> 880502098e..1a7e4c2e3d 100644
> >>>> --- a/lib/ethdev/rte_flow.h
> >>>> +++ b/lib/ethdev/rte_flow.h
> >>>> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
> >>>>    	 * @see struct rte_flow_item_ethdev
> >>>>    	 */
> >>>>    	RTE_FLOW_ITEM_TYPE_ETHDEV,
> >>>> +
> >>>> +	/**
> >>>> +	 * [META]
> >>>> +	 *
> >>>> +	 * Matches traffic at e-switch going from the external port associated
> >>>> +	 * with the given ethdev, for example, traffic from net. port or guest.
> >>>> +	 *
> >>>> +	 * @see struct rte_flow_item_ethdev
> >>>> +	 */
> >>>> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
> >>>>    };
> >>>>
> >>>>    /**
> >>>> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
> >>>> rte_flow_item_conntrack_mask = {
> >>>>     * @b EXPERIMENTAL: this structure may change without prior notice
> >>>>     *
> >>>>     * Provides an ethdev ID for use with items which are as follows:
> >>>> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
> >>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
> >>>> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
> >>>>     */
> >>>>    struct rte_flow_item_ethdev {
> >>>>    	uint16_t id; /**< Ethdev ID */
> >>>> --
> >>>> 2.30.2
> >>>
> >>> Best,
> >>> Ori
> >>>
> >>
> >> --
> >> Ivan M
> 
> --
> Ivan M

Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-04 11:37             ` Ori Kam
@ 2021-10-04 11:58               ` Ivan Malov
  2021-10-05  6:20                 ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-04 11:58 UTC (permalink / raw)
  To: Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ori,

On 04/10/2021 14:37, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>> Sent: Monday, October 4, 2021 2:06 PM
>> Cc: dev@dpdk.org
>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>
>> Hi Ori,
>>
>> On 04/10/2021 08:45, Ori Kam wrote:
>>> Hi Ivan,
>>>
>>>> -----Original Message-----
>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>> Sent: Sunday, October 3, 2021 9:11 PM
>>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>> API
>>>>
>>>>
>>>>
>>>> On 03/10/2021 15:40, Ori Kam wrote:
>>>>> Hi Andrew and Ivan,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>>>>>
>>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>>
>>>>>> For use with "transfer" flows. Supposed to match traffic entering
>>>>>> the e-switch from the external world (network, guests) via the port
>>>>>> which is logically connected with the given ethdev.
>>>>>>
>>>>>> Must not be combined with attributes "ingress" / "egress".
>>>>>>
>>>>>> This item is meant to use the same structure as ethdev item.
>>>>>>
>>>>>
>>>>> In case the app is not working with representors, meaning each
>>>>> switch port is mapped to ethdev.
>>>>> both items (ethdev and eswitch port ) have the same meaning?
>>>>
>>>> No. Ethdev means ethdev, and e-switch port is the point where this
>>>> ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a
>>>> regular PF ethdev typically means the network port (maybe you can
>>>> recall the idea that a PF ethdev "represents" the network port it's
>> associated with).
>>>>
>>>> I believe, that diagrams which these patches add to
>>>> "doc/guides/prog_guide/rte_flow.rst" may come in handy to understand
>>>> the meaning. Also, you can take a look at our larger diagram from the
>>>> Sep 14 gathering.
>>>>
>>>
>>> Lets look at the following system:
>>> E-Switch has 3 ports - PF, VF1, VF2
>>> The ports are distributed as follows:
>>> DPDK application:
>>> ethdev(0) pf,
>>> ethdev(1) representor to VF1
>>> ethdev(2) representor to VF2
>>> ethdev(3) VF1
>>>
>>> VM:
>>> VF2
>>>
>>> As we know all representors are realy connected to the PF(at least in
>>> this example)
>>
>> This example tries to say that the e-switch has 3 ports in total, and, given
>> your explanation, one may indeed agree that *in this example* representors
>> re-use e-switch port of ethdev=0 (with some metadata to distinguish
>> packets, etc.). But one can hardly assume that *all* representors with any
>> vendor's NIC are connected to the e-switch the same way. It's vendor
>> specific. Well, at least, applications don't have this knowledge and don't need
>> to.
>>
>>>
>>> So matching on ethdev(3)  means matching on traffic sent from DPDK port
>> 3 right?
>>
>> Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks like
>> we're on the same page here.
>>
> 
> Good.
> 
>>> And matching on eswitch_port(3) means matching in traffic that goes
>>> into VF1 which is the same traffic as ethdev(3) right?
>>
>> I didn't catch the thought about "the same traffic". Direction is not the same.
>> Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK port 1.
>>
> This is the critical part for my understanding.
> Matching on ethdev_id(3) means matching on traffic that is coming from DPDK port3.

Right.

> So from E-Switch view point it is traffic that goes into VF1?

No. Above you clearly say "coming from DPDK port3". That is, from the 
VF1. *Not* going into it. Port 3 (ethdev_id=3) *is* VF1.

> While matching on E-Switch_port(3) means matching on traffic coming from VF1?

No. It means matching on traffic coming from ethdev 1. From the VF1's 
representor.

> 
> And by the same logic matching on ethdev_id(1) means matching on taffic that was sent
> from DPDK port 1 and matching on E-Switch_port(1) means matching on traffic coming from
> VF1

In this case, you've got this right. But please see my above notes. By 
the looks of it, you might have run into confusion over there.

> 
> So in this case eswitch_port(3) is equal ot eswitch_port(1) right?
> While ethdev(1) is not equal to ethdev(3)

No.

Item ETHDEV (ethdev_id=1) equals item ESWITCH_PORT (ethdev_id=3).
Item ETHDEV (ethdev_id=3) equals item ESWITCH_PORT (ethdev_id=1).

> 
> And just to complete the picture, matching on ethdev(2) will result in traffic
> coming from the dpdk port and matching on eswitch_port(2) will match
> on traffic coming from VF2

Exactly.


But, Ori, let me draw your attention to the following issue. In order to 
simplify understanding, I suggest that we refrain from saying "traffic 
that GOES TO". Where it goes depends on default rules that are supposed 
to be maintained by the PMD when ports get plugged / unplugged.

The flow items ETHDEV and ESWITH_PORT define the SOURCE of traffic. 
That's it. They define where the traffic "goes FROM".

Say, the DPDK application sends a packet from ethdev 0. This packet 
enters the e-switch. Match engine sits in the e-switch and intercepts 
the packet. It doesn't care where the packet *would go* if it wasn't 
intercepted. It cares about where the packet comes from. And it comes 
from ethdev 0. So, in the focus, we have the SOURCE of the packet.


> 
>> Yes, in this case neither of the ports (1, 3) is truly "external" (they both
>> interface the DPDK application), but, the thing is, they're "external" *to each
>> other* in the sense that they sit at the opposite ends of the wire.
>>
>>>
>>> Matching on ethdev(1) means matching on the PF port in the E-Switch but
>> with some
>>> metadata that marks the traffic as coming from DPDK port 1 and not from
>> VF1 E-Switch
>>> port right?
>>
>> That's vendor specific. The application doesn't have to know how exactly
>> this particular ethdev is connected to the e-switch - whether it re-uses
>> the PF's e-switch port or has its own. The e-switch port that connects
>> the ethdev with the e-switch is just assumed to exist logically.
>>
>>>
>>> While matching on eswitch_port(2) means matching on traffic coming from
>> the VM right?
>>
>> Right.
>>
> 
> I think the my above question will clear everything for me.
> 
>>>
>>>>>
>>>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>> ---
>>>>>>     app/test-pmd/cmdline_flow.c                 | 27
>> +++++++++++++++++++++
>>>>>>     doc/guides/prog_guide/rte_flow.rst          | 22 +++++++++++++++++
>>>>>>     doc/guides/rel_notes/release_21_11.rst      |  2 +-
>>>>>>     doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 +++
>>>>>>     lib/ethdev/rte_flow.c                       |  1 +
>>>>>>     lib/ethdev/rte_flow.h                       | 12 ++++++++-
>>>>>>     6 files changed, 66 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-
>>>> pmd/cmdline_flow.c
>>>>>> index e05b0d83d2..188d0ee39d 100644
>>>>>> --- a/app/test-pmd/cmdline_flow.c
>>>>>> +++ b/app/test-pmd/cmdline_flow.c
>>>>>> @@ -308,6 +308,8 @@ enum index {
>>>>>>     	ITEM_POL_POLICY,
>>>>>>     	ITEM_ETHDEV,
>>>>>>     	ITEM_ETHDEV_ID,
>>>>>> +	ITEM_ESWITCH_PORT,
>>>>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
>>>>>
>>>>> Like my comment from previous patch, I'm not sure the correct
>>>>> term for ETHDEV is ID is should be port.
>>>>
>>>> Please see my reply in the previous thread. "ethdev" here is an
>>>> "anchor", a "beacon" of sorts which allows either to refer namely to
>>>> this ethdev or to the e-switch port associated with it.
>>>>
>>>>>
>>>>>>
>>>>>>     	/* Validate/create actions. */
>>>>>>     	ACTIONS,
>>>>>> @@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
>>>>>>     	ITEM_INTEGRITY,
>>>>>>     	ITEM_CONNTRACK,
>>>>>>     	ITEM_ETHDEV,
>>>>>> +	ITEM_ESWITCH_PORT,
>>>>>>     	END_SET,
>>>>>>     	ZERO,
>>>>>>     };
>>>>>> @@ -1377,6 +1380,12 @@ static const enum index item_ethdev[] = {
>>>>>>     	ZERO,
>>>>>>     };
>>>>>>
>>>>>> +static const enum index item_eswitch_port[] = {
>>>>>> +	ITEM_ESWITCH_PORT_ETHDEV_ID,
>>>>>> +	ITEM_NEXT,
>>>>>> +	ZERO,
>>>>>> +};
>>>>>> +
>>>>>>     static const enum index next_action[] = {
>>>>>>     	ACTION_END,
>>>>>>     	ACTION_VOID,
>>>>>> @@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
>>>>>>     			     item_param),
>>>>>>     		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>>>> id)),
>>>>>>     	},
>>>>>> +	[ITEM_ESWITCH_PORT] = {
>>>>>> +		.name = "eswitch_port",
>>>>>> +		.help = "match traffic at e-switch going from the external port
>>>>>> associated with the given ethdev",
>>>>>
>>>>> Missing the word logically since if we are talking about representor the
>>>> connected port
>>>>> is the PF while we want to match traffic on one of the FVs.
>>>>
>>>> Doesn't the word "external" say it all?
>>>>
>>>> Representor Ethdev <--> Admin ethdev's PF <--> E-Switch <--> VF
>>>> (external / the most remote endpoint).
>>>>
>>>
>>> Until the last comment External had totally different meaning to me.
>>> I think you should add some place the meaning of external or use
>>> the most remote endpoint.
>>
>> We'll keep this in mind. Given your above example (when both VF and its
>> representor) are plugged to the DPDK application, "external" may sound a
>> bit off, but maybe it can be retained and just clarified as the "most
>> remote endpoint" in the e-switch with respect to the ethdev in question.
>>
> 
> +1 to the most remote or finding different wording.
> 
>>>
>>>>>
>>>>>> +		.priv = PRIV_ITEM(ESWITCH_PORT,
>>>>>> +				  sizeof(struct rte_flow_item_ethdev)),
>>>>>> +		.next = NEXT(item_eswitch_port),
>>>>>> +		.call = parse_vc,
>>>>>> +	},
>>>>>> +	[ITEM_ESWITCH_PORT_ETHDEV_ID] = {
>>>>>> +		.name = "ethdev_id",
>>>>>> +		.help = "ethdev ID",
>>>>>> +		.next = NEXT(item_eswitch_port,
>>>>>> NEXT_ENTRY(COMMON_UNSIGNED),
>>>>>> +			     item_param),
>>>>>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>>>> id)),
>>>>>> +	},
>>>>>>     	/* Validate/create actions. */
>>>>>>     	[ACTIONS] = {
>>>>>>     		.name = "actions",
>>>>>> @@ -8370,6 +8394,9 @@ flow_item_default_mask(const struct
>>>>>> rte_flow_item *item)
>>>>>>     	case RTE_FLOW_ITEM_TYPE_ETHDEV:
>>>>>>     		mask = &rte_flow_item_ethdev_mask;
>>>>>>     		break;
>>>>>> +	case RTE_FLOW_ITEM_TYPE_ESWITCH_PORT:
>>>>>> +		mask = &rte_flow_item_ethdev_mask;
>>>>>> +		break;
>>>>>
>>>>> Not sure maybe merged the two cases?
>>>>
>>>> A noble idea.
>>>>
>>>>>
>>>>>>     	default:
>>>>>>     		break;
>>>>>>     	}
>>>>>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>>>>>> b/doc/guides/prog_guide/rte_flow.rst
>>>>>> index ab628d9139..292bb42410 100644
>>>>>> --- a/doc/guides/prog_guide/rte_flow.rst
>>>>>> +++ b/doc/guides/prog_guide/rte_flow.rst
>>>>>> @@ -1460,6 +1460,28 @@ Use this with attribute **transfer**.
>> Attributes
>>>>>> **ingress** and
>>>>>>        | ``mask`` | ``id``   | zeroed for wildcard match |
>>>>>>        +----------+----------+---------------------------+
>>>>>>
>>>>>> +Item: ``ESWITCH_PORT``
>>>>>> +^^^^^^^^^^^^^^^^^^^^^^
>>>>>> +
>>>>>> +Matches traffic at e-switch going from the external port associated
>>>>>> +with the given ethdev, for example, traffic from net. port or guest.
>>>>>
>>>>> Maybe replace external with e-switch?
>>>>
>>>> The word "e-switch" is already here. Basically, all "external" ports are
>>>> "e-switch external ports" = ports which connect the e-switch with
>>>> non-DPDK world: network ports, VFs passed to guests, etc.
>>>>
>>>
>>> Please see comment above, the word external is not clearly defined. >
>>>>>
>>>>>> +
>>>>>> +::
>>>>>> +
>>>>>> +   *    (Ethdev) ~~~~~~~~~~~~ (Internal Port) ~~~~ [] <<<< (External
>>>> Port)
>>>>>> +   *    :  SW                 :   Logical                    Net / Guest :
>>>>>> +   *    :                     :                                          :
>>>>>> +   *    | ---- PMD Layer ---- | ------------ E-Switch Layer ------------ |
>>>>>> +   *
>>>>>> +   *    [] shows the effective ("transfer") standpoint, the match engine;
>>>>>> +   *    << shows the traffic flow in question hitting the match engine;
>>>>>> +   *    ~~ shows logical interconnects between the endpoints.
>>>>>> +
>>>>>
>>>>> I'm not sure I understand this diagram.
>>>>
>>>> Thanks for the feedback. I have no way with drawing fancy diagrams, so
>>>> this one may not be ideal, yes. But could you please elaborate on your
>>>> concerns. Maybe you understand it the right way but just unsure. If you
>>>> describe what you see when looking at the diagram, I'll be able to
>>>> either confirm your vision or debunk any misunderstanding and possibly
>>>> improve the drawing.
>>>>
>>>
>>>
>>> I will try,
>>> Ethdev is the port that the application sees in DPDK right?
>>
>> Exactly.
>>
>>> Internal port is what the PMD sees, for example in case of representor it
>> will see the PF port.
>>
>> Vendor-specific, but, yes, let's assume that.
>>
>>> External (also due to a drawing in one of your comments) is the E-Switch
>> end point.
>>> So this drawing shows that the app select the external port that is
>> connected to the
>>> internal port which is connected to the ethdev port?
>>
>> So what's the problem?
>>
>> Ethdev ----- E-switch port A -- ... --- E-switch port B------ VF
>>
>> So, saying "transfer + ESWITCH_PORT" here implies the e-switch port B.
>> How do we name it? "External"? "The most remote"? Any other options?
>>
>>>
>>> Thanks,
>>> Ori
>>>>>
>>>>>> +Use this with attribute **transfer**. Attributes **ingress** and
>>>>>> +**egress** (`Attribute: Traffic direction`_) must not be used.
>>>>>> +
>>>>>> +This item is meant to use the same structure as `Item: ETHDEV`_.
>>>>>> +
>>>>>>     Actions
>>>>>>     ~~~~~~~
>>>>>>
>>>>>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>>>>>> b/doc/guides/rel_notes/release_21_11.rst
>>>>>> index 91631adb4e..b2b27de3f0 100644
>>>>>> --- a/doc/guides/rel_notes/release_21_11.rst
>>>>>> +++ b/doc/guides/rel_notes/release_21_11.rst
>>>>>> @@ -167,7 +167,7 @@ API Changes
>>>>>>        Also, make sure to start the actual text at the margin.
>>>>>>
>>>> =======================================================
>>>>>>
>>>>>> -* ethdev: Added item ``ETHDEV`` to flow API.
>>>>>> +* ethdev: Added items ``ETHDEV``, ``ESWITCH_PORT`` to flow API.
>>>>>>
>>>>>>     * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to
>>>>>>       rte_cryptodev_is_valid_dev as it can be used by the application as
>> diff --
>>>> git
>>>>>> a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>>>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>>>> index 6d5de5457c..9a5c2a2d82 100644
>>>>>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>>>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>>>> @@ -3824,6 +3824,10 @@ This section lists supported pattern items
>> and
>>>>>> their attributes, if any.
>>>>>>
>>>>>>       - ``id {unsigned}``: ethdev ID
>>>>>>
>>>>>> +- ``eswitch_port``: match traffic at e-switch going from the external
>>>>>> +port associated with the given ethdev
>>>>>> +
>>>>>> +  - ``ethdev_id {unsigned}``: ethdev ID
>>>>>> +
>>>>>>     Actions list
>>>>>>     ^^^^^^^^^^^^
>>>>>>
>>>>>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>>>>>> 84eb61cb6c..c4aea5625f 100644
>>>>>> --- a/lib/ethdev/rte_flow.c
>>>>>> +++ b/lib/ethdev/rte_flow.c
>>>>>> @@ -101,6 +101,7 @@ static const struct rte_flow_desc_data
>>>>>> rte_flow_desc_item[] = {
>>>>>>     	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>>>>>     	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>>>>>>     	MK_FLOW_ITEM(ETHDEV, sizeof(struct rte_flow_item_ethdev)),
>>>>>> +	MK_FLOW_ITEM(ESWITCH_PORT, sizeof(struct
>>>>>> rte_flow_item_ethdev)),
>>>>>>     };
>>>>>>
>>>>>>     /** Generate flow_action[] entry. */
>>>>>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>>>> 880502098e..1a7e4c2e3d 100644
>>>>>> --- a/lib/ethdev/rte_flow.h
>>>>>> +++ b/lib/ethdev/rte_flow.h
>>>>>> @@ -583,6 +583,16 @@ enum rte_flow_item_type {
>>>>>>     	 * @see struct rte_flow_item_ethdev
>>>>>>     	 */
>>>>>>     	RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>>>> +
>>>>>> +	/**
>>>>>> +	 * [META]
>>>>>> +	 *
>>>>>> +	 * Matches traffic at e-switch going from the external port associated
>>>>>> +	 * with the given ethdev, for example, traffic from net. port or guest.
>>>>>> +	 *
>>>>>> +	 * @see struct rte_flow_item_ethdev
>>>>>> +	 */
>>>>>> +	RTE_FLOW_ITEM_TYPE_ESWITCH_PORT,
>>>>>>     };
>>>>>>
>>>>>>     /**
>>>>>> @@ -1813,7 +1823,7 @@ static const struct rte_flow_item_conntrack
>>>>>> rte_flow_item_conntrack_mask = {
>>>>>>      * @b EXPERIMENTAL: this structure may change without prior notice
>>>>>>      *
>>>>>>      * Provides an ethdev ID for use with items which are as follows:
>>>>>> - * RTE_FLOW_ITEM_TYPE_ETHDEV.
>>>>>> + * RTE_FLOW_ITEM_TYPE_ETHDEV,
>>>>>> RTE_FLOW_ITEM_TYPE_ESWITCH_PORT.
>>>>>>      */
>>>>>>     struct rte_flow_item_ethdev {
>>>>>>     	uint16_t id; /**< Ethdev ID */
>>>>>> --
>>>>>> 2.30.2
>>>>>
>>>>> Best,
>>>>> Ori
>>>>>
>>>>
>>>> --
>>>> Ivan M
>>
>> --
>> Ivan M
> 
> Thanks,
> Ori
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [EXT] [PATCH v1 11/12] net/octeontx2: support ethdev flow action
  2021-10-04 11:13     ` [dpdk-dev] [EXT] " Kiran Kumar Kokkilagadda
@ 2021-10-04 12:45       ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-04 12:45 UTC (permalink / raw)
  To: Kiran Kumar Kokkilagadda, Jerin Jacob Kollanukkaran,
	Nithin Kumar Dabilpuram
  Cc: dev, Ori Kam, Thomas Monjalon, Ferruh Yigit, Ivan Malov

On 10/4/21 2:13 PM, Kiran Kumar Kokkilagadda wrote:
> 
> 
>> -----Original Message-----
>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Sent: Friday, October 1, 2021 7:17 PM
>> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram
>> <ndabilpuram@marvell.com>; Kiran Kumar Kokkilagadda
>> <kirankumark@marvell.com>
>> Cc: dev@dpdk.org; Ori Kam <orika@nvidia.com>; Thomas Monjalon
>> <thomas@monjalon.net>; Ferruh Yigit <ferruh.yigit@intel.com>; Ivan Malov
>> <ivan.malov@oktetlabs.ru>
>> Subject: [EXT] [PATCH v1 11/12] net/octeontx2: support ethdev flow action
>>
>> External Email
>>
>> ----------------------------------------------------------------------
>> PORT_ID action implementation works for ingress only and has the same
>> semantics as ETHDEV action.
> 
> Please update the documentation also.

Thanks, will do.


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

* [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-09-07 12:51 [dpdk-dev] [RFC PATCH] ethdev: clarify flow attribute and action port ID semantics Ivan Malov
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
@ 2021-10-05  0:36 ` Ivan Malov
  2021-10-05  9:22   ` Ori Kam
                     ` (4 more replies)
  1 sibling, 5 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-05  0:36 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Xiaoyun Li, Ori Kam, Thomas Monjalon,
	Ferruh Yigit, Ray Kinsella

Introduce a helper API to let applications find transfer
admin port for a given ethdev to avoid failures when
managing "transfer" flows through unprivileged ports.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
Patch series [1] has reworked support for "transfer" flows.
As a result, an application no longer needs to communicate
such flows through a particular ethdev where it receives
the corresponding packets in the first place.

Hence, this patch is a legitimate follow-up to the series [1].
At the same time, it's a follow-up to the early RFC [2].

net/sfc driver is going to support this method. The
corresponding patch is already in progress and will
be provided in the course of this release cycle.

[1] https://patches.dpdk.org/project/dpdk/list/?series=19326
[2] https://patches.dpdk.org/project/dpdk/list/?series=18737
---
 app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
 app/test-pmd/testpmd.c                 |  21 +++++
 app/test-pmd/testpmd.h                 |   4 +
 app/test-pmd/util.c                    |   5 +-
 doc/guides/rel_notes/release_21_11.rst |   3 +
 lib/ethdev/rte_flow.c                  |  22 +++++
 lib/ethdev/rte_flow.h                  |  32 ++++++++
 lib/ethdev/rte_flow_driver.h           |   5 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 197 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9c66329e96..2772c83d0a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 	struct port_indirect_action *pia;
 	int ret;
 	struct rte_flow_error error;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	ret = action_alloc(port_id, id, &pia);
 	if (ret)
 		return ret;
+
+	port = &ports[port_id];
+
+	if (conf->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
 		struct rte_flow_action_age *age =
 			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
@@ -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 		return port_flow_complain(&error);
 	}
 	pia->type = action->type;
+	pia->transfer = conf->transfer;
 	printf("Indirect action #%u created\n", pia->id);
 	return 0;
 }
@@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
 		for (i = 0; i != n; ++i) {
 			struct rte_flow_error error;
 			struct port_indirect_action *pia = *tmp;
+			portid_t port_id_eff = port_id;
 
 			if (actions[i] != pia->id)
 				continue;
+
+			if (pia->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
 			/*
 			 * Poisoning to make sure PMDs update it in case
 			 * of error.
@@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
 			memset(&error, 0x33, sizeof(error));
 
 			if (pia->handle && rte_flow_action_handle_destroy(
-					port_id, pia->handle, &error)) {
+					port_id_eff, pia->handle, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	struct rte_flow_error error;
 	struct rte_flow_action_handle *action_handle;
 	struct port_indirect_action *pia;
+	struct rte_port *port;
 	const void *update;
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
 	action_handle = port_action_handle_get_by_id(port_id, id);
 	if (!action_handle)
 		return -EINVAL;
@@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 		update = action;
 		break;
 	}
+
+	if (pia->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (rte_flow_action_handle_update(port_id, action_handle, update,
 					  &error)) {
 		return port_flow_complain(&error);
@@ -1636,6 +1676,14 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 		struct rte_flow_query_age age;
 		struct rte_flow_action_conntrack ct;
 	} query;
+	portid_t port_id_eff = port_id;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
 
 	pia = action_get_by_id(port_id, id);
 	if (!pia)
@@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 			id, pia->type, port_id);
 		return -ENOTSUP;
 	}
+
+	if (pia->transfer)
+		port_id_eff = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+	    port_id_eff == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x55, sizeof(error));
 	memset(&query, 0, sizeof(query));
-	if (rte_flow_action_handle_query(port_id, pia->handle, &query, &error))
+	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
+					 &error))
 		return port_flow_complain(&error);
 	switch (pia->type) {
 	case RTE_FLOW_ACTION_TYPE_AGE:
@@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,
 {
 	struct rte_flow_error error;
 	struct port_flow_tunnel *pft = NULL;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
@@ -1925,7 +1996,19 @@ port_flow_create(portid_t port_id,
 	struct port_flow_tunnel *pft = NULL;
 	struct rte_flow_action_age *age = age_action_get(actions);
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (port->flow_list) {
 		if (port->flow_list->id == UINT32_MAX) {
 			fprintf(stderr,
@@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 		uint32_t i;
 
 		for (i = 0; i != n; ++i) {
+			portid_t port_id_eff = port_id;
 			struct rte_flow_error error;
 			struct port_flow *pf = *tmp;
 
@@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 			 * of error.
 			 */
 			memset(&error, 0x33, sizeof(error));
-			if (rte_flow_destroy(port_id, pf->flow, &error)) {
+
+			if (pf->rule.attr->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
+			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
 		fprintf(stderr, "Flow rule #%u not found\n", rule);
 		return -ENOENT;
 	}
+
+	if (pf->rule.attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
 			    &name, sizeof(name),
 			    (void *)(uintptr_t)action->type, &error);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 97ae52e17e..a88e920bd0 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -533,6 +533,25 @@ int proc_id;
  */
 unsigned int num_procs = 1;
 
+static void
+flow_pick_transfer_proxy_mp(uint16_t port_id)
+{
+	struct rte_port *port = &ports[port_id];
+	int ret;
+
+	port->flow_transfer_proxy = port_id;
+
+	if (!is_proc_primary())
+		return;
+
+	ret = rte_flow_pick_transfer_proxy(port_id, &port->flow_transfer_proxy,
+					   NULL);
+	if (ret != 0) {
+		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s - ignore\n",
+			port_id, rte_strerror(-ret));
+	}
+}
+
 static int
 eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
@@ -1489,6 +1508,8 @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
 	int ret;
 	int i;
 
+	flow_pick_transfer_proxy_mp(pid);
+
 	port->dev_conf.txmode = tx_mode;
 	port->dev_conf.rxmode = rx_mode;
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 5863b2f43f..b3dfd350e5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -173,6 +173,8 @@ struct port_indirect_action {
 	enum rte_flow_action_type type; /**< Action type. */
 	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
 	enum age_action_context_type age_type; /**< Age action context type. */
+	/** If true, the action applies to "transfer" flows, and vice versa */
+	bool transfer;
 };
 
 struct port_flow_tunnel {
@@ -234,6 +236,8 @@ struct rte_port {
 	/**< dynamic flags. */
 	uint64_t		mbuf_dynf;
 	const struct rte_eth_rxtx_callback *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
+	/** Associated port which is supposed to handle "transfer" flows */
+	portid_t		flow_transfer_proxy;
 };
 
 /**
diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
index 14a9a251fb..d9edbbf9ee 100644
--- a/app/test-pmd/util.c
+++ b/app/test-pmd/util.c
@@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 		int ret;
 		struct rte_flow_error error;
 		struct rte_flow_restore_info info = { 0, };
+		struct rte_port *port = &ports[port_id];
 
 		mb = pkts[i];
 		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr), &_eth_hdr);
 		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
 		packet_type = mb->packet_type;
 		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
-		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
+
+		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
+						mb, &info, &error);
 		if (!ret) {
 			MKDUMPSTR(print_buf, buf_size, cur_len,
 				  "restore info:");
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 37776c135e..cc0ea4695a 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -67,6 +67,9 @@ New Features
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
   TCP/UDP/SCTP header checksum field can be used as input set for RSS.
 
+* **Added an API to pick flow transfer proxy port**
+  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
+
 * **Updated Broadcom bnxt PMD.**
 
   * Added flow offload support for Thor.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 647bbf91ce..15e978f7f7 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				  NULL, rte_strerror(ENOTSUP));
 }
+
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(ops == NULL))
+		return -rte_errno;
+
+	if (likely(ops->pick_transfer_proxy != NULL)) {
+		return flow_err(port_id,
+				ops->pick_transfer_proxy(dev, proxy_port_id,
+							 error),
+				error);
+	}
+
+	*proxy_port_id = port_id;
+
+	return 0;
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index f195aa7224..d2cb476189 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -122,6 +122,10 @@ struct rte_flow_attr {
 	 *
 	 * In order to match traffic originating from specific source(s), the
 	 * application should use pattern items ETHDEV and ESWITCH_PORT.
+	 *
+	 * Communicating "transfer" flows via unprivileged ethdevs may not
+	 * be possible. In order to pick the ethdev suitable for that, the
+	 * application should use @p rte_flow_pick_transfer_proxy().
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
@@ -4427,6 +4431,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 			     struct rte_flow_item *items,
 			     uint32_t num_of_items,
 			     struct rte_flow_error *error);
+
+/**
+ * An application receiving packets on a given ethdev may want to have their
+ * processing offloaded to the e-switch lying beneath this ethdev by means
+ * of maintaining "transfer" flows. However, it need never use this exact
+ * ethdev as an entry point for such flows to be managed through. More to
+ * that, this particular ethdev may be short of privileges to control the
+ * e-switch. Instead, the application should find an admin ethdev sitting
+ * on top of the same e-switch to be used as the entry point (a "proxy").
+ *
+ * This API is a helper to find such "transfer proxy" for a given ethdev.
+ *
+ * @note
+ *   If the PMD serving @p port_id doesn't have the corresponding method
+ *   implemented, the API will return @p port_id via @p proxy_port_id.
+ *
+ * @param port_id
+ *   ID of the ethdev in question
+ * @param[out] proxy_port_id
+ *   ID of the "transfer proxy"
+ *
+ * @return
+ *   0 on success, a negative error code otherwise
+ */
+__rte_experimental
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index 46f62c2ec2..ed52e59a0a 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -139,6 +139,11 @@ struct rte_flow_ops {
 		 struct rte_flow_item *pmd_items,
 		 uint32_t num_of_items,
 		 struct rte_flow_error *err);
+	/** See rte_flow_pick_transfer_proxy() */
+	int (*pick_transfer_proxy)
+		(struct rte_eth_dev *dev,
+		 uint16_t *proxy_port_id,
+		 struct rte_flow_error *error);
 };
 
 /**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 904bce6ea1..d4286dc8dd 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -247,6 +247,9 @@ EXPERIMENTAL {
 	rte_mtr_meter_policy_delete;
 	rte_mtr_meter_policy_update;
 	rte_mtr_meter_policy_validate;
+
+	# added in 21.11
+	rte_flow_pick_transfer_proxy;
 };
 
 INTERNAL {
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-04 11:58               ` Ivan Malov
@ 2021-10-05  6:20                 ` Ori Kam
  2021-10-05  9:19                   ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-05  6:20 UTC (permalink / raw)
  To: Ivan Malov, Andrew Rybchenko, Xiaoyun Li,
	NBU-Contact-Thomas Monjalon, Ferruh Yigit
  Cc: dev

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Cc: dev@dpdk.org
> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
> 
> Hi Ori,
> 
> On 04/10/2021 14:37, Ori Kam wrote:
> > Hi Ivan,
> >
> >> -----Original Message-----
> >> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> >> Sent: Monday, October 4, 2021 2:06 PM
> >> Cc: dev@dpdk.org
> >> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
> >> API
> >>
> >> Hi Ori,
> >>
> >> On 04/10/2021 08:45, Ori Kam wrote:
> >>> Hi Ivan,
> >>>
> >>>> -----Original Message-----
> >>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> >>>> Sent: Sunday, October 3, 2021 9:11 PM
> >>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
> >>>> API
> >>>>
> >>>>
> >>>>
> >>>> On 03/10/2021 15:40, Ori Kam wrote:
> >>>>> Hi Andrew and Ivan,
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >>>>>> Sent: Friday, October 1, 2021 4:47 PM
> >>>>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow
> >>>>>> API
> >>>>>>
> >>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >>>>>>
> >>>>>> For use with "transfer" flows. Supposed to match traffic entering
> >>>>>> the e-switch from the external world (network, guests) via the
> >>>>>> port which is logically connected with the given ethdev.
> >>>>>>
> >>>>>> Must not be combined with attributes "ingress" / "egress".
> >>>>>>
> >>>>>> This item is meant to use the same structure as ethdev item.
> >>>>>>
> >>>>>
> >>>>> In case the app is not working with representors, meaning each
> >>>>> switch port is mapped to ethdev.
> >>>>> both items (ethdev and eswitch port ) have the same meaning?
> >>>>
> >>>> No. Ethdev means ethdev, and e-switch port is the point where this
> >>>> ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a
> >>>> regular PF ethdev typically means the network port (maybe you can
> >>>> recall the idea that a PF ethdev "represents" the network port it's
> >> associated with).
> >>>>
> >>>> I believe, that diagrams which these patches add to
> >>>> "doc/guides/prog_guide/rte_flow.rst" may come in handy to
> >>>> understand the meaning. Also, you can take a look at our larger
> >>>> diagram from the Sep 14 gathering.
> >>>>
> >>>
> >>> Lets look at the following system:
> >>> E-Switch has 3 ports - PF, VF1, VF2
> >>> The ports are distributed as follows:
> >>> DPDK application:
> >>> ethdev(0) pf,
> >>> ethdev(1) representor to VF1
> >>> ethdev(2) representor to VF2
> >>> ethdev(3) VF1
> >>>
> >>> VM:
> >>> VF2
> >>>
> >>> As we know all representors are realy connected to the PF(at least
> >>> in this example)
> >>
> >> This example tries to say that the e-switch has 3 ports in total,
> >> and, given your explanation, one may indeed agree that *in this
> >> example* representors re-use e-switch port of ethdev=0 (with some
> >> metadata to distinguish packets, etc.). But one can hardly assume
> >> that *all* representors with any vendor's NIC are connected to the
> >> e-switch the same way. It's vendor specific. Well, at least,
> >> applications don't have this knowledge and don't need to.
> >>
> >>>
> >>> So matching on ethdev(3)  means matching on traffic sent from DPDK
> >>> port
> >> 3 right?
> >>
> >> Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks
> >> like we're on the same page here.
> >>
> >
> > Good.
> >
> >>> And matching on eswitch_port(3) means matching in traffic that goes
> >>> into VF1 which is the same traffic as ethdev(3) right?
> >>
> >> I didn't catch the thought about "the same traffic". Direction is not the
> same.
> >> Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK port 1.
> >>
> > This is the critical part for my understanding.
> > Matching on ethdev_id(3) means matching on traffic that is coming from
> DPDK port3.
> 
> Right.
> 
> > So from E-Switch view point it is traffic that goes into VF1?
> 
> No. Above you clearly say "coming from DPDK port3". That is, from the VF1.
> *Not* going into it. Port 3 (ethdev_id=3) *is* VF1.
> 
But taffic that goes from DPDK port 3 goes into VF1,
what am I missing?

> > While matching on E-Switch_port(3) means matching on traffic coming
> from VF1?
> 
> No. It means matching on traffic coming from ethdev 1. From the VF1's
> representor.
> 
> >
> > And by the same logic matching on ethdev_id(1) means matching on
> > taffic that was sent from DPDK port 1 and matching on E-Switch_port(1)
> > means matching on traffic coming from
> > VF1
> 
> In this case, you've got this right. But please see my above notes. By the
> looks of it, you might have run into confusion over there.
> 
That is the issue I'm not sure I understand, and I think that 
if I don't underdand this, this miss underdanding will be shared by others.

> >
> > So in this case eswitch_port(3) is equal ot eswitch_port(1) right?
> > While ethdev(1) is not equal to ethdev(3)
> 
> No.
> 
> Item ETHDEV (ethdev_id=1) equals item ESWITCH_PORT (ethdev_id=3).
> Item ETHDEV (ethdev_id=3) equals item ESWITCH_PORT (ethdev_id=1).
> 
I think this was my first undestaning, lets see if I can explain it using my words.
ETHDEV - means that the source port that we are matching on is the closest one
the dpdk application. Example like above ETHDEV(ethdev_id=1) means matching
on traffic coming from the PF with some metadata that marks this DPDK port.
ETHDEV(ethdev_id=3) means matching on traffic coming from VF1.

ESWITCH_PORT meaning matching on the port that is connected to the DPDK port
(the other side of the wire). Example ESWITCH_PORT(ethdev_id=1) means matching
on traffic coming from VF1
While matching on ESWITCH_PORT(ethdev_id=3) means matching on PF with some
metadata.

Everything assume that representors are on the PF and use some metadata.

Did I get it right?

> >
> > And just to complete the picture, matching on ethdev(2) will result in
> > traffic coming from the dpdk port and matching on eswitch_port(2) will
> > match on traffic coming from VF2
> 
> Exactly.
> 
> 
> But, Ori, let me draw your attention to the following issue. In order to
> simplify understanding, I suggest that we refrain from saying "traffic that
> GOES TO". Where it goes depends on default rules that are supposed to be
> maintained by the PMD when ports get plugged / unplugged.
> 
> The flow items ETHDEV and ESWITH_PORT define the SOURCE of traffic.
> That's it. They define where the traffic "goes FROM".
> 
> Say, the DPDK application sends a packet from ethdev 0. This packet enters
> the e-switch. Match engine sits in the e-switch and intercepts the packet. It
> doesn't care where the packet *would go* if it wasn't intercepted. It cares
> about where the packet comes from. And it comes from ethdev 0. So, in the
> focus, we have the SOURCE of the packet.
> 

Agree with you we should only look at coming from,
but something in the patch made me thing otherwise (not sure what part)

> 
> >
> >> Yes, in this case neither of the ports (1, 3) is truly "external"
> >> (they both interface the DPDK application), but, the thing is,
> >> they're "external" *to each
> >> other* in the sense that they sit at the opposite ends of the wire.
> >>
> >>>
> >>> Matching on ethdev(1) means matching on the PF port in the E-Switch
> >>> but
> >> with some
> >>> metadata that marks the traffic as coming from DPDK port 1 and not
> >>> from
> >> VF1 E-Switch
> >>> port right?
> >>
> >> That's vendor specific. The application doesn't have to know how
> >> exactly this particular ethdev is connected to the e-switch - whether
> >> it re-uses the PF's e-switch port or has its own. The e-switch port
> >> that connects the ethdev with the e-switch is just assumed to exist
> logically.
> >>
> >>>
> >>> While matching on eswitch_port(2) means matching on traffic coming
> >>> from
> >> the VM right?
> >>
> >> Right.
> >>
> >
> > I think the my above question will clear everything for me.
> >

[Snip]
> >>>>>
> >>>>> Best,
> >>>>> Ori
> >>>>>
> >>>>
> >>>> --
> >>>> Ivan M
> >>
> >> --
> >> Ivan M
> >
> > Thanks,
> > Ori
> >
> 
> --
> Ivan M

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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-05  6:20                 ` Ori Kam
@ 2021-10-05  9:19                   ` Andrew Rybchenko
  2021-10-05 12:12                     ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-05  9:19 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov
  Cc: dev, Xiaoyun Li, NBU-Contact-Thomas Monjalon, Ferruh Yigit

Hi Ori,

On 10/5/21 9:20 AM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>> Cc: dev@dpdk.org
>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>
>> Hi Ori,
>>
>> On 04/10/2021 14:37, Ori Kam wrote:
>>> Hi Ivan,
>>>
>>>> -----Original Message-----
>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>> Sent: Monday, October 4, 2021 2:06 PM
>>>> Cc: dev@dpdk.org
>>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>> API
>>>>
>>>> Hi Ori,
>>>>
>>>> On 04/10/2021 08:45, Ori Kam wrote:
>>>>> Hi Ivan,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>>>> Sent: Sunday, October 3, 2021 9:11 PM
>>>>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>>>> API
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 03/10/2021 15:40, Ori Kam wrote:
>>>>>>> Hi Andrew and Ivan,
>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>>>>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>>>>>> API
>>>>>>>>
>>>>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>>>>
>>>>>>>> For use with "transfer" flows. Supposed to match traffic entering
>>>>>>>> the e-switch from the external world (network, guests) via the
>>>>>>>> port which is logically connected with the given ethdev.
>>>>>>>>
>>>>>>>> Must not be combined with attributes "ingress" / "egress".
>>>>>>>>
>>>>>>>> This item is meant to use the same structure as ethdev item.
>>>>>>>>
>>>>>>>
>>>>>>> In case the app is not working with representors, meaning each
>>>>>>> switch port is mapped to ethdev.
>>>>>>> both items (ethdev and eswitch port ) have the same meaning?
>>>>>>
>>>>>> No. Ethdev means ethdev, and e-switch port is the point where this
>>>>>> ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a
>>>>>> regular PF ethdev typically means the network port (maybe you can
>>>>>> recall the idea that a PF ethdev "represents" the network port it's
>>>> associated with).
>>>>>>
>>>>>> I believe, that diagrams which these patches add to
>>>>>> "doc/guides/prog_guide/rte_flow.rst" may come in handy to
>>>>>> understand the meaning. Also, you can take a look at our larger
>>>>>> diagram from the Sep 14 gathering.
>>>>>>
>>>>>
>>>>> Lets look at the following system:
>>>>> E-Switch has 3 ports - PF, VF1, VF2
>>>>> The ports are distributed as follows:
>>>>> DPDK application:
>>>>> ethdev(0) pf,
>>>>> ethdev(1) representor to VF1
>>>>> ethdev(2) representor to VF2
>>>>> ethdev(3) VF1
>>>>>
>>>>> VM:
>>>>> VF2
>>>>>
>>>>> As we know all representors are realy connected to the PF(at least
>>>>> in this example)
>>>>
>>>> This example tries to say that the e-switch has 3 ports in total,
>>>> and, given your explanation, one may indeed agree that *in this
>>>> example* representors re-use e-switch port of ethdev=0 (with some
>>>> metadata to distinguish packets, etc.). But one can hardly assume
>>>> that *all* representors with any vendor's NIC are connected to the
>>>> e-switch the same way. It's vendor specific. Well, at least,
>>>> applications don't have this knowledge and don't need to.
>>>>
>>>>>
>>>>> So matching on ethdev(3)  means matching on traffic sent from DPDK
>>>>> port
>>>> 3 right?
>>>>
>>>> Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks
>>>> like we're on the same page here.
>>>>
>>>
>>> Good.
>>>
>>>>> And matching on eswitch_port(3) means matching in traffic that goes
>>>>> into VF1 which is the same traffic as ethdev(3) right?
>>>>
>>>> I didn't catch the thought about "the same traffic". Direction is not the
>> same.
>>>> Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK port 1.
>>>>
>>> This is the critical part for my understanding.
>>> Matching on ethdev_id(3) means matching on traffic that is coming from
>> DPDK port3.
>>
>> Right.
>>
>>> So from E-Switch view point it is traffic that goes into VF1?
>>
>> No. Above you clearly say "coming from DPDK port3". That is, from the VF1.
>> *Not* going into it. Port 3 (ethdev_id=3) *is* VF1.
>>
> But taffic that goes from DPDK port 3 goes into VF1,
> what am I missing?

DPDK port 3 is a VF1 itself. So, is it loopback? I think no.

Let me repeat your example:

DPDK application:
ethdev(0) pf,
ethdev(1) representor to VF1
ethdev(2) representor to VF2
ethdev(3) VF1

VM:
VF2

Traffic that goes from DPDK port 3 (which is VF1 bound to DPDK)
goes to its representor by default, i.e. ethdev(1).

> 
>>> While matching on E-Switch_port(3) means matching on traffic coming
>> from VF1?
>>
>> No. It means matching on traffic coming from ethdev 1. From the VF1's
>> representor.
>>
>>>
>>> And by the same logic matching on ethdev_id(1) means matching on
>>> taffic that was sent from DPDK port 1 and matching on E-Switch_port(1)
>>> means matching on traffic coming from
>>> VF1
>>
>> In this case, you've got this right. But please see my above notes. By the
>> looks of it, you might have run into confusion over there.
>>
> That is the issue I'm not sure I understand, and I think that 
> if I don't underdand this, this miss underdanding will be shared by others.

In order to address the confusion and misunderstanding we
should find out the source of it. We always match on source
(inbound port) and the result is a destination (outgoing port).
So, if item is ETHDEV, the source is DPDK application via
corresponding ethdev port.  If ETHDEV is an action, the
destination is the DPDK application via specified ethdev port.
Above is regardless of the ethdev port type (representor or
not). Always, no exceptions.

>>>
>>> So in this case eswitch_port(3) is equal ot eswitch_port(1) right?
>>> While ethdev(1) is not equal to ethdev(3)
>>
>> No.
>>
>> Item ETHDEV (ethdev_id=1) equals item ESWITCH_PORT (ethdev_id=3).
>> Item ETHDEV (ethdev_id=3) equals item ESWITCH_PORT (ethdev_id=1).
>>
> I think this was my first undestaning, lets see if I can explain it using my words.
> ETHDEV - means that the source port that we are matching on is the closest one
> the dpdk application.

Yes, it sounds right.

> Example like above ETHDEV(ethdev_id=1) means matching
> on traffic coming from the PF with some metadata that marks this DPDK port.

No, no, no. It is the problem of too much knowledge and
diving too deep. Neither you nor API user should not
think about it. Representor ethdev(1) is a DPDK ethdev
port that's it. An application can send traffic via the
ethdev port and receive traffic from it. How the traffic
goes inside is vendor-specific implementation detail.
Application just know that if it sends traffic to VF1
representor ethdev(1), the traffic will be received
from VF1 by default. If it sends traffic from VF1,
the traffic will be received from VF1 representor
by default. It is the definition of the representor.

> ETHDEV(ethdev_id=3) means matching on traffic coming from VF1.

Yes.

> 
> ESWITCH_PORT meaning matching on the port that is connected to the DPDK port
> (the other side of the wire). Example ESWITCH_PORT(ethdev_id=1) means matching
> on traffic coming from VF1

Yes, since ethdev(1) is VF1 representor.

> While matching on ESWITCH_PORT(ethdev_id=3) means matching on PF with some
> metadata.

Again, yes and no. No, since you should not think about it this way. It
is just traffic sent via VF1 representor (since ethdev(3) is VF1 and its
other side of the logical wire is VF1
representor). No vendor-specific implementation details.

> 
> Everything assume that representors are on the PF and use some metadata.

No, it is a vendor-specific implementation details.
Flow API definitions should not mention it.

> 
> Did I get it right?

I think you get overall idea right, but explanations
are too complicated. It is simpler in fact.

>>>
>>> And just to complete the picture, matching on ethdev(2) will result in
>>> traffic coming from the dpdk port and matching on eswitch_port(2) will
>>> match on traffic coming from VF2
>>
>> Exactly.
>>
>>
>> But, Ori, let me draw your attention to the following issue. In order to
>> simplify understanding, I suggest that we refrain from saying "traffic that
>> GOES TO". Where it goes depends on default rules that are supposed to be
>> maintained by the PMD when ports get plugged / unplugged.
>>
>> The flow items ETHDEV and ESWITH_PORT define the SOURCE of traffic.
>> That's it. They define where the traffic "goes FROM".
>>
>> Say, the DPDK application sends a packet from ethdev 0. This packet enters
>> the e-switch. Match engine sits in the e-switch and intercepts the packet. It
>> doesn't care where the packet *would go* if it wasn't intercepted. It cares
>> about where the packet comes from. And it comes from ethdev 0. So, in the
>> focus, we have the SOURCE of the packet.
>>
> 
> Agree with you we should only look at coming from,
> but something in the patch made me thing otherwise (not sure what part)

I've reread the documentation and failed to find,
but it will be hard for me to do it, since I read
it too many times already.

Thanks,
Andrew.

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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
@ 2021-10-05  9:22   ` Ori Kam
  2021-10-05 12:41     ` Ivan Malov
  2021-10-05 17:56   ` Thomas Monjalon
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-05  9:22 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: Andrew Rybchenko, Xiaoyun Li, NBU-Contact-Thomas Monjalon,
	Ferruh Yigit, Ray Kinsella

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Tuesday, October 5, 2021 3:36 AM
> Subject: [PATCH] ethdev: let apps find transfer admin port for a given ethdev
> 
> Introduce a helper API to let applications find transfer admin port for a given
> ethdev to avoid failures when managing "transfer" flows through unprivileged
> ports.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
> Patch series [1] has reworked support for "transfer" flows.
> As a result, an application no longer needs to communicate such flows through
> a particular ethdev where it receives the corresponding packets in the first
> place.
> 
> Hence, this patch is a legitimate follow-up to the series [1].
> At the same time, it's a follow-up to the early RFC [2].
> 
> net/sfc driver is going to support this method. The corresponding patch is
> already in progress and will be provided in the course of this release cycle.
> 
> [1] https://patches.dpdk.org/project/dpdk/list/?series=19326
> [2] https://patches.dpdk.org/project/dpdk/list/?series=18737
> ---
>  app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
>  app/test-pmd/testpmd.c                 |  21 +++++
>  app/test-pmd/testpmd.h                 |   4 +
>  app/test-pmd/util.c                    |   5 +-
>  doc/guides/rel_notes/release_21_11.rst |   3 +
>  lib/ethdev/rte_flow.c                  |  22 +++++
>  lib/ethdev/rte_flow.h                  |  32 ++++++++
>  lib/ethdev/rte_flow_driver.h           |   5 ++
>  lib/ethdev/version.map                 |   3 +
>  9 files changed, 197 insertions(+), 4 deletions(-)
> 
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> 9c66329e96..2772c83d0a 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id,
> uint32_t id,
>  	struct port_indirect_action *pia;
>  	int ret;
>  	struct rte_flow_error error;
> +	struct rte_port *port;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> 

Is this part of the patch or a general fix?

>  	ret = action_alloc(port_id, id, &pia);
>  	if (ret)
>  		return ret;
> +
> +	port = &ports[port_id];
> +
> +	if (conf->transfer)
> +		port_id = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
>  		struct rte_flow_action_age *age =
>  			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
> @@ -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id,
> uint32_t id,
>  		return port_flow_complain(&error);
>  	}
>  	pia->type = action->type;
> +	pia->transfer = conf->transfer;
>  	printf("Indirect action #%u created\n", pia->id);
>  	return 0;
>  }
> @@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
>  		for (i = 0; i != n; ++i) {
>  			struct rte_flow_error error;
>  			struct port_indirect_action *pia = *tmp;
> +			portid_t port_id_eff = port_id;
> 
>  			if (actions[i] != pia->id)
>  				continue;
> +
> +			if (pia->transfer)
> +				port_id_eff = port->flow_transfer_proxy;
> +
> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
> +				return -EINVAL;
> +
>  			/*
>  			 * Poisoning to make sure PMDs update it in case
>  			 * of error.
> @@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
>  			memset(&error, 0x33, sizeof(error));
> 
>  			if (pia->handle && rte_flow_action_handle_destroy(
> -					port_id, pia->handle, &error)) {
> +					port_id_eff, pia->handle, &error)) {
>  				ret = port_flow_complain(&error);
>  				continue;
>  			}
> @@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id,
> uint32_t id,
>  	struct rte_flow_error error;
>  	struct rte_flow_action_handle *action_handle;
>  	struct port_indirect_action *pia;
> +	struct rte_port *port;
>  	const void *update;
> 
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
> +	port = &ports[port_id];
> +
>  	action_handle = port_action_handle_get_by_id(port_id, id);
>  	if (!action_handle)
>  		return -EINVAL;
> @@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id,
> uint32_t id,
>  		update = action;
>  		break;
>  	}
> +
> +	if (pia->transfer)
> +		port_id = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	if (rte_flow_action_handle_update(port_id, action_handle, update,
>  					  &error)) {
>  		return port_flow_complain(&error);
> @@ -1636,6 +1676,14 @@ port_action_handle_query(portid_t port_id,
> uint32_t id)
>  		struct rte_flow_query_age age;
>  		struct rte_flow_action_conntrack ct;
>  	} query;
> +	portid_t port_id_eff = port_id;
> +	struct rte_port *port;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
> +	port = &ports[port_id];
> 
>  	pia = action_get_by_id(port_id, id);
>  	if (!pia)
> @@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id,
> uint32_t id)
>  			id, pia->type, port_id);
>  		return -ENOTSUP;
>  	}
> +
> +	if (pia->transfer)
> +		port_id_eff = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> +	    port_id_eff == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	/* Poisoning to make sure PMDs update it in case of error. */
>  	memset(&error, 0x55, sizeof(error));
>  	memset(&query, 0, sizeof(query));
> -	if (rte_flow_action_handle_query(port_id, pia->handle, &query,
> &error))
> +	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
> +					 &error))
>  		return port_flow_complain(&error);
>  	switch (pia->type) {
>  	case RTE_FLOW_ACTION_TYPE_AGE:
> @@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,  {
>  	struct rte_flow_error error;
>  	struct port_flow_tunnel *pft = NULL;
> +	struct rte_port *port;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
> +	port = &ports[port_id];
> +
> +	if (attr->transfer)
> +		port_id = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> 
>  	/* Poisoning to make sure PMDs update it in case of error. */
>  	memset(&error, 0x11, sizeof(error));
> @@ -1925,7 +1996,19 @@ port_flow_create(portid_t port_id,
>  	struct port_flow_tunnel *pft = NULL;
>  	struct rte_flow_action_age *age = age_action_get(actions);
> 
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	port = &ports[port_id];
> +
> +	if (attr->transfer)
> +		port_id = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	if (port->flow_list) {
>  		if (port->flow_list->id == UINT32_MAX) {
>  			fprintf(stderr,
> @@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const
> uint32_t *rule)
>  		uint32_t i;
> 
>  		for (i = 0; i != n; ++i) {
> +			portid_t port_id_eff = port_id;
>  			struct rte_flow_error error;
>  			struct port_flow *pf = *tmp;
> 
> @@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t n,
> const uint32_t *rule)
>  			 * of error.
>  			 */
>  			memset(&error, 0x33, sizeof(error));
> -			if (rte_flow_destroy(port_id, pf->flow, &error)) {
> +
> +			if (pf->rule.attr->transfer)
> +				port_id_eff = port->flow_transfer_proxy;
> +
> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
> +				return -EINVAL;
> +
> +			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
>  				ret = port_flow_complain(&error);
>  				continue;
>  			}
> @@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
>  		fprintf(stderr, "Flow rule #%u not found\n", rule);
>  		return -ENOENT;
>  	}
> +
> +	if (pf->rule.attr->transfer)
> +		port_id = port->flow_transfer_proxy;
> +
> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> +	    port_id == (portid_t)RTE_PORT_ALL)
> +		return -EINVAL;
> +
>  	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
>  			    &name, sizeof(name),
>  			    (void *)(uintptr_t)action->type, &error); diff --git
> a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> 97ae52e17e..a88e920bd0 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -533,6 +533,25 @@ int proc_id;
>   */
>  unsigned int num_procs = 1;
> 
> +static void
> +flow_pick_transfer_proxy_mp(uint16_t port_id) {
> +	struct rte_port *port = &ports[port_id];
> +	int ret;
> +
> +	port->flow_transfer_proxy = port_id;
> +
> +	if (!is_proc_primary())
> +		return;
> +
> +	ret = rte_flow_pick_transfer_proxy(port_id, &port-
> >flow_transfer_proxy,
> +					   NULL);
> +	if (ret != 0) {
> +		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s
> - ignore\n",
> +			port_id, rte_strerror(-ret));
> +	}
> +}
> +
>  static int
>  eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  		      const struct rte_eth_conf *dev_conf) @@ -1489,6 +1508,8
> @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
>  	int ret;
>  	int i;
> 
> +	flow_pick_transfer_proxy_mp(pid);
> +
>  	port->dev_conf.txmode = tx_mode;
>  	port->dev_conf.rxmode = rx_mode;
> 
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
> 5863b2f43f..b3dfd350e5 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -173,6 +173,8 @@ struct port_indirect_action {
>  	enum rte_flow_action_type type; /**< Action type. */
>  	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
>  	enum age_action_context_type age_type; /**< Age action context
> type. */
> +	/** If true, the action applies to "transfer" flows, and vice versa */
> +	bool transfer;
>  };
> 
>  struct port_flow_tunnel {
> @@ -234,6 +236,8 @@ struct rte_port {
>  	/**< dynamic flags. */
>  	uint64_t		mbuf_dynf;
>  	const struct rte_eth_rxtx_callback
> *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
> +	/** Associated port which is supposed to handle "transfer" flows */
> +	portid_t		flow_transfer_proxy;
>  };
> 
>  /**
> diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c index
> 14a9a251fb..d9edbbf9ee 100644
> --- a/app/test-pmd/util.c
> +++ b/app/test-pmd/util.c
> @@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
> struct rte_mbuf *pkts[],
>  		int ret;
>  		struct rte_flow_error error;
>  		struct rte_flow_restore_info info = { 0, };
> +		struct rte_port *port = &ports[port_id];
> 
>  		mb = pkts[i];
>  		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr),
> &_eth_hdr);
>  		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
>  		packet_type = mb->packet_type;
>  		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
> -		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
> +
> +		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
> +						mb, &info, &error);

I'm not sure this is correct,
Since to restore the data you need to know the port that this traffic was sent to.
Even if the action was offloaded on the proxy port, it is important to know what was the
destination port.
even setting the tunnel must be done on the target port and not the proxy port.

>  		if (!ret) {
>  			MKDUMPSTR(print_buf, buf_size, cur_len,
>  				  "restore info:");
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 37776c135e..cc0ea4695a 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -67,6 +67,9 @@ New Features
>    Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4
> and
>    TCP/UDP/SCTP header checksum field can be used as input set for RSS.
> 
> +* **Added an API to pick flow transfer proxy port**
> +  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
> +
>  * **Updated Broadcom bnxt PMD.**
> 
>    * Added flow offload support for Thor.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> 647bbf91ce..15e978f7f7 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>  				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>  				  NULL, rte_strerror(ENOTSUP));
>  }
> +
> +int
> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> +			     struct rte_flow_error *error)

What about replaceing pick with get?

> +{
> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> +	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
> +
> +	if (unlikely(ops == NULL))
> +		return -rte_errno;
> +
> +	if (likely(ops->pick_transfer_proxy != NULL)) {
> +		return flow_err(port_id,
> +				ops->pick_transfer_proxy(dev, proxy_port_id,
> +							 error),
> +				error);
> +	}
> +
> +	*proxy_port_id = port_id;
> +
> +	return 0;
> +}
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> f195aa7224..d2cb476189 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -122,6 +122,10 @@ struct rte_flow_attr {
>  	 *
>  	 * In order to match traffic originating from specific source(s), the
>  	 * application should use pattern items ETHDEV and ESWITCH_PORT.
> +	 *
> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
> +	 * be possible. In order to pick the ethdev suitable for that, the
> +	 * application should use @p rte_flow_pick_transfer_proxy().
>  	 */
>  	uint32_t transfer:1;
>  	uint32_t reserved:29; /**< Reserved, must be zero. */ @@ -4427,6
> +4431,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>  			     struct rte_flow_item *items,
>  			     uint32_t num_of_items,
>  			     struct rte_flow_error *error);
> +
> +/**
> + * An application receiving packets on a given ethdev may want to have
> +their
> + * processing offloaded to the e-switch lying beneath this ethdev by
> +means
> + * of maintaining "transfer" flows. However, it need never use this
> +exact
> + * ethdev as an entry point for such flows to be managed through. More
> +to
> + * that, this particular ethdev may be short of privileges to control
> +the
> + * e-switch. Instead, the application should find an admin ethdev
> +sitting
> + * on top of the same e-switch to be used as the entry point (a "proxy").
> + *

This explanation is not clear, can you rephrase it?

> + * This API is a helper to find such "transfer proxy" for a given ethdev.
> + *
> + * @note
> + *   If the PMD serving @p port_id doesn't have the corresponding method
> + *   implemented, the API will return @p port_id via @p proxy_port_id.

+1 

> + *
> + * @param port_id
> + *   ID of the ethdev in question
> + * @param[out] proxy_port_id
> + *   ID of the "transfer proxy"
> + *
> + * @return
> + *   0 on success, a negative error code otherwise
> + */
> +__rte_experimental
> +int
> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> +			     struct rte_flow_error *error);
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h index
> 46f62c2ec2..ed52e59a0a 100644
> --- a/lib/ethdev/rte_flow_driver.h
> +++ b/lib/ethdev/rte_flow_driver.h
> @@ -139,6 +139,11 @@ struct rte_flow_ops {
>  		 struct rte_flow_item *pmd_items,
>  		 uint32_t num_of_items,
>  		 struct rte_flow_error *err);
> +	/** See rte_flow_pick_transfer_proxy() */
> +	int (*pick_transfer_proxy)
> +		(struct rte_eth_dev *dev,
> +		 uint16_t *proxy_port_id,
> +		 struct rte_flow_error *error);
>  };
> 
>  /**
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index
> 904bce6ea1..d4286dc8dd 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -247,6 +247,9 @@ EXPERIMENTAL {
>  	rte_mtr_meter_policy_delete;
>  	rte_mtr_meter_policy_update;
>  	rte_mtr_meter_policy_validate;
> +
> +	# added in 21.11
> +	rte_flow_pick_transfer_proxy;
>  };
> 
>  INTERNAL {
> --
> 2.20.1

Best,
Ori


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

* Re: [dpdk-dev] [PATCH v1 02/12] ethdev: add eswitch port item to flow API
  2021-10-05  9:19                   ` Andrew Rybchenko
@ 2021-10-05 12:12                     ` Ivan Malov
  0 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-05 12:12 UTC (permalink / raw)
  To: Andrew Rybchenko, Ori Kam
  Cc: dev, Xiaoyun Li, NBU-Contact-Thomas Monjalon, Ferruh Yigit

Hi Ori, Andrew,

On 05/10/2021 12:19, Andrew Rybchenko wrote:
> Hi Ori,
> 
> On 10/5/21 9:20 AM, Ori Kam wrote:
>> Hi Ivan,
>>
>>> -----Original Message-----
>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>> Cc: dev@dpdk.org
>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow API
>>>
>>> Hi Ori,
>>>
>>> On 04/10/2021 14:37, Ori Kam wrote:
>>>> Hi Ivan,
>>>>
>>>>> -----Original Message-----
>>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>>> Sent: Monday, October 4, 2021 2:06 PM
>>>>> Cc: dev@dpdk.org
>>>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>>> API
>>>>>
>>>>> Hi Ori,
>>>>>
>>>>> On 04/10/2021 08:45, Ori Kam wrote:
>>>>>> Hi Ivan,
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>>>>>>> Sent: Sunday, October 3, 2021 9:11 PM
>>>>>>> Subject: Re: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>>>>> API
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 03/10/2021 15:40, Ori Kam wrote:
>>>>>>>> Hi Andrew and Ivan,
>>>>>>>>
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>>>>>>> Sent: Friday, October 1, 2021 4:47 PM
>>>>>>>>> Subject: [PATCH v1 02/12] ethdev: add eswitch port item to flow
>>>>>>>>> API
>>>>>>>>>
>>>>>>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>>>>>>>
>>>>>>>>> For use with "transfer" flows. Supposed to match traffic entering
>>>>>>>>> the e-switch from the external world (network, guests) via the
>>>>>>>>> port which is logically connected with the given ethdev.
>>>>>>>>>
>>>>>>>>> Must not be combined with attributes "ingress" / "egress".
>>>>>>>>>
>>>>>>>>> This item is meant to use the same structure as ethdev item.
>>>>>>>>>
>>>>>>>>
>>>>>>>> In case the app is not working with representors, meaning each
>>>>>>>> switch port is mapped to ethdev.
>>>>>>>> both items (ethdev and eswitch port ) have the same meaning?
>>>>>>>
>>>>>>> No. Ethdev means ethdev, and e-switch port is the point where this
>>>>>>> ethdev is plugged to. For example, "transfer + ESWITCH_PORT" for a
>>>>>>> regular PF ethdev typically means the network port (maybe you can
>>>>>>> recall the idea that a PF ethdev "represents" the network port it's
>>>>> associated with).
>>>>>>>
>>>>>>> I believe, that diagrams which these patches add to
>>>>>>> "doc/guides/prog_guide/rte_flow.rst" may come in handy to
>>>>>>> understand the meaning. Also, you can take a look at our larger
>>>>>>> diagram from the Sep 14 gathering.
>>>>>>>
>>>>>>
>>>>>> Lets look at the following system:
>>>>>> E-Switch has 3 ports - PF, VF1, VF2
>>>>>> The ports are distributed as follows:
>>>>>> DPDK application:
>>>>>> ethdev(0) pf,
>>>>>> ethdev(1) representor to VF1
>>>>>> ethdev(2) representor to VF2
>>>>>> ethdev(3) VF1
>>>>>>
>>>>>> VM:
>>>>>> VF2
>>>>>>
>>>>>> As we know all representors are realy connected to the PF(at least
>>>>>> in this example)
>>>>>
>>>>> This example tries to say that the e-switch has 3 ports in total,
>>>>> and, given your explanation, one may indeed agree that *in this
>>>>> example* representors re-use e-switch port of ethdev=0 (with some
>>>>> metadata to distinguish packets, etc.). But one can hardly assume
>>>>> that *all* representors with any vendor's NIC are connected to the
>>>>> e-switch the same way. It's vendor specific. Well, at least,
>>>>> applications don't have this knowledge and don't need to.
>>>>>
>>>>>>
>>>>>> So matching on ethdev(3)  means matching on traffic sent from DPDK
>>>>>> port
>>>>> 3 right?
>>>>>
>>>>> Item ETHDEV (ethdev_id=3) matches traffic sent by DPDK port 3. Looks
>>>>> like we're on the same page here.
>>>>>
>>>>
>>>> Good.
>>>>
>>>>>> And matching on eswitch_port(3) means matching in traffic that goes
>>>>>> into VF1 which is the same traffic as ethdev(3) right?
>>>>>
>>>>> I didn't catch the thought about "the same traffic". Direction is not the
>>> same.
>>>>> Item ESWITCH_PORT (ethdev_id=3) matches traffic sent by DPDK port 1.
>>>>>
>>>> This is the critical part for my understanding.
>>>> Matching on ethdev_id(3) means matching on traffic that is coming from
>>> DPDK port3.
>>>
>>> Right.
>>>
>>>> So from E-Switch view point it is traffic that goes into VF1?
>>>
>>> No. Above you clearly say "coming from DPDK port3". That is, from the VF1.
>>> *Not* going into it. Port 3 (ethdev_id=3) *is* VF1.
>>>
>> But taffic that goes from DPDK port 3 goes into VF1,
>> what am I missing?

Terms like "PF", "VF", "PHY_PORT" describe the nature of the e-switch 
ports. In your example, DPDK port 3 is just based on VF1. The 
application doesn't have such knowledge. To it, this is a regular ethdev.

In order to gain correct understanding, you should imagine an observer 
standing inside the e-switch. When that observer sees packets entering 
the e-switch FROM the VF1, we effectively talk about packets sent by the 
ethdev sitting on top of that VF1, that is, packets coming FROM DPDK 
port 3. And vice versa: if you say "traffic that goes into VF1", you 
mean traffic that LEAVES the e-switch via VF1, that is, traffic, going 
TO DPDK port 3.

"VF1" is just a name of a logical "window" between the e-switch and its 
surroundings. If this VF is passed to a guest machine, then this VF is a 
"window" between the e-switch and the guest machine. If you plug this VF 
to the DPDK application (create an ethdev on top of this VF), then this 
VF is a "window" between the e-switch and the PMD. That's it.

> 
> DPDK port 3 is a VF1 itself. So, is it loopback? I think no.
> 
> Let me repeat your example:
> 
> DPDK application:
> ethdev(0) pf,
> ethdev(1) representor to VF1
> ethdev(2) representor to VF2
> ethdev(3) VF1
> 
> VM:
> VF2
> 
> Traffic that goes from DPDK port 3 (which is VF1 bound to DPDK)
> goes to its representor by default, i.e. ethdev(1).

+1

> 
>>
>>>> While matching on E-Switch_port(3) means matching on traffic coming
>>> from VF1?
>>>
>>> No. It means matching on traffic coming from ethdev 1. From the VF1's
>>> representor.
>>>
>>>>
>>>> And by the same logic matching on ethdev_id(1) means matching on
>>>> taffic that was sent from DPDK port 1 and matching on E-Switch_port(1)
>>>> means matching on traffic coming from
>>>> VF1
>>>
>>> In this case, you've got this right. But please see my above notes. By the
>>> looks of it, you might have run into confusion over there.
>>>
>> That is the issue I'm not sure I understand, and I think that
>> if I don't underdand this, this miss underdanding will be shared by others.

Please see my diagram below.

> 
> In order to address the confusion and misunderstanding we
> should find out the source of it. We always match on source
> (inbound port) and the result is a destination (outgoing port).
> So, if item is ETHDEV, the source is DPDK application via
> corresponding ethdev port.  If ETHDEV is an action, the
> destination is the DPDK application via specified ethdev port.
> Above is regardless of the ethdev port type (representor or
> not). Always, no exceptions.
> 
>>>>
>>>> So in this case eswitch_port(3) is equal ot eswitch_port(1) right?
>>>> While ethdev(1) is not equal to ethdev(3)
>>>
>>> No.
>>>
>>> Item ETHDEV (ethdev_id=1) equals item ESWITCH_PORT (ethdev_id=3).
>>> Item ETHDEV (ethdev_id=3) equals item ESWITCH_PORT (ethdev_id=1).
>>>
>> I think this was my first undestaning, lets see if I can explain it using my words.
>> ETHDEV - means that the source port that we are matching on is the closest one
>> the dpdk application.
> 
> Yes, it sounds right.
> 
>> Example like above ETHDEV(ethdev_id=1) means matching
>> on traffic coming from the PF with some metadata that marks this DPDK port.

Some vendors support allocation of separate logical e-switch ports for 
representors. Other vendors can't support that, and, in this case, they 
indeed have to devise "PF + metadata" solution. But DPDK framework (I 
mean, vendor-agnostic code) can't assume any of these options as a 
"standard". Neither can applications do that. It's truly vendor-specific.

> 
> No, no, no. It is the problem of too much knowledge and
> diving too deep. Neither you nor API user should not
> think about it. Representor ethdev(1) is a DPDK ethdev
> port that's it. An application can send traffic via the
> ethdev port and receive traffic from it. How the traffic
> goes inside is vendor-specific implementation detail.
> Application just know that if it sends traffic to VF1
> representor ethdev(1), the traffic will be received
> from VF1 by default. If it sends traffic from VF1,
> the traffic will be received from VF1 representor
> by default. It is the definition of the representor.

+1

> 
>> ETHDEV(ethdev_id=3) means matching on traffic coming from VF1.
> 
> Yes.
> 
>>
>> ESWITCH_PORT meaning matching on the port that is connected to the DPDK port
>> (the other side of the wire). Example ESWITCH_PORT(ethdev_id=1) means matching
>> on traffic coming from VF1
> 
> Yes, since ethdev(1) is VF1 representor.
> 
>> While matching on ESWITCH_PORT(ethdev_id=3) means matching on PF with some
>> metadata.
> 
> Again, yes and no. No, since you should not think about it this way. It
> is just traffic sent via VF1 representor (since ethdev(3) is VF1 and its
> other side of the logical wire is VF1
> representor). No vendor-specific implementation details.
> 
>>
>> Everything assume that representors are on the PF and use some metadata.
> 
> No, it is a vendor-specific implementation details.
> Flow API definitions should not mention it.

+1

> 
>>
>> Did I get it right?

Let's try to look at the overall idea one more time. Just to get us on 
the same page.

In general, for any given ethdev you have:


ETHDEV (A)
|
|    (PMD area)
|
CLOSEST ESWITCH_PORT (B)
|
|    (e-switch area)
|
REMOTE ESWITCH_PORT (C)
|
X


The point "B" is located closest to the ethdev (A). Not to the 
application in general, but to the given ethdev.

The point "C" is the most remote point from the ethdev's perspective. 
Again, it's not the most remote from the application. It's the most 
remote from this specific ethdev.

 From the application perspective, the nature of (B) and (C) is unknown. 
But the application knows for sure that these points just exist. To it, 
these points are some *logical* e-switch ports.

Now.

When you say "item ETHDEV", you tell the PMD that you want to match 
packets entering the *PMD area* FROM point (A). But you also add 
"transfer" attribute. This attribute makes the PMD translate your 
request to the e-switch viewpoint by "transferring" point "A" one level 
below. What was "A" becomes "B". This way, an imaginary observer 
standing inside the *e-switch area* intercepts packets which enter this 
area FROM (B).
Summary: this way, you match packets going *DOWN* from (A).

When you say "item ESWITCH_PORT", you tell the PMD that you want to 
match packets entering the *PMD area* FROM point (B). Once again, 
"transfer" translates this to the e-switch viewpoint, that is, (B) 
becomes (C). So, the e-switch knows that it should intercept packets 
entering its area FROM point (C).
Summary: this way, you match packets going *UP* from (X).


Some use case examples:

- The ethdev (A) is a DPDK port based on a PF associated with a network 
port. In this case, (B) == PF and (C) == (X) == network port.

- The ethdev (A) is a representor of VF1 which is passed to a VM. In 
this case, (B) is just an e-switch logical port. It's nature is vendor 
specific. It can be a PF, it can be not. It depends. (C) == VF, (X) == VM.

- The ethdev (A) is a representor of VF1 which is plugged to the same 
DPDK application. In this case, (B) is, once again, some logical 
e-switch port. (C) == VF. But (X) here is another ethdev. So, this way, 
ethdev (A) is a representor's ethdev and ethdev (X) is a VF's ethdev.

In all cases the application doesn't care about the nature of the 
e-switch ports (B) and (C). It just knows that they exist.

> 
> I think you get overall idea right, but explanations
> are too complicated. It is simpler in fact.
> 
>>>>
>>>> And just to complete the picture, matching on ethdev(2) will result in
>>>> traffic coming from the dpdk port and matching on eswitch_port(2) will
>>>> match on traffic coming from VF2
>>>
>>> Exactly.
>>>
>>>
>>> But, Ori, let me draw your attention to the following issue. In order to
>>> simplify understanding, I suggest that we refrain from saying "traffic that
>>> GOES TO". Where it goes depends on default rules that are supposed to be
>>> maintained by the PMD when ports get plugged / unplugged.
>>>
>>> The flow items ETHDEV and ESWITH_PORT define the SOURCE of traffic.
>>> That's it. They define where the traffic "goes FROM".
>>>
>>> Say, the DPDK application sends a packet from ethdev 0. This packet enters
>>> the e-switch. Match engine sits in the e-switch and intercepts the packet. It
>>> doesn't care where the packet *would go* if it wasn't intercepted. It cares
>>> about where the packet comes from. And it comes from ethdev 0. So, in the
>>> focus, we have the SOURCE of the packet.
>>>
>>
>> Agree with you we should only look at coming from,
>> but something in the patch made me thing otherwise (not sure what part)
> 
> I've reread the documentation and failed to find,
> but it will be hard for me to do it, since I read
> it too many times already.
> 
> Thanks,
> Andrew.
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05  9:22   ` Ori Kam
@ 2021-10-05 12:41     ` Ivan Malov
  2021-10-05 16:04       ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-05 12:41 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: Andrew Rybchenko, Xiaoyun Li, NBU-Contact-Thomas Monjalon,
	Ferruh Yigit, Ray Kinsella

Hi Ori,

Thanks a lot for eagerly reviewing this and related patches. That's very 
helpful of yours.

On 05/10/2021 12:22, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Tuesday, October 5, 2021 3:36 AM
>> Subject: [PATCH] ethdev: let apps find transfer admin port for a given ethdev
>>
>> Introduce a helper API to let applications find transfer admin port for a given
>> ethdev to avoid failures when managing "transfer" flows through unprivileged
>> ports.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> ---
>> Patch series [1] has reworked support for "transfer" flows.
>> As a result, an application no longer needs to communicate such flows through
>> a particular ethdev where it receives the corresponding packets in the first
>> place.
>>
>> Hence, this patch is a legitimate follow-up to the series [1].
>> At the same time, it's a follow-up to the early RFC [2].
>>
>> net/sfc driver is going to support this method. The corresponding patch is
>> already in progress and will be provided in the course of this release cycle.
>>
>> [1] https://patches.dpdk.org/project/dpdk/list/?series=19326
>> [2] https://patches.dpdk.org/project/dpdk/list/?series=18737
>> ---
>>   app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
>>   app/test-pmd/testpmd.c                 |  21 +++++
>>   app/test-pmd/testpmd.h                 |   4 +
>>   app/test-pmd/util.c                    |   5 +-
>>   doc/guides/rel_notes/release_21_11.rst |   3 +
>>   lib/ethdev/rte_flow.c                  |  22 +++++
>>   lib/ethdev/rte_flow.h                  |  32 ++++++++
>>   lib/ethdev/rte_flow_driver.h           |   5 ++
>>   lib/ethdev/version.map                 |   3 +
>>   9 files changed, 197 insertions(+), 4 deletions(-)
>>
>> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
>> 9c66329e96..2772c83d0a 100644
>> --- a/app/test-pmd/config.c
>> +++ b/app/test-pmd/config.c
>> @@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id,
>> uint32_t id,
>>   	struct port_indirect_action *pia;
>>   	int ret;
>>   	struct rte_flow_error error;
>> +	struct rte_port *port;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>>
> 
> Is this part of the patch or a general fix?

I know it might seem unrelated at first glance. But it has to be added 
here for consistency with the rest of the code being added. It should be OK.

> 
>>   	ret = action_alloc(port_id, id, &pia);
>>   	if (ret)
>>   		return ret;
>> +
>> +	port = &ports[port_id];
>> +
>> +	if (conf->transfer)
>> +		port_id = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
>>   		struct rte_flow_action_age *age =
>>   			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
>> @@ -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id,
>> uint32_t id,
>>   		return port_flow_complain(&error);
>>   	}
>>   	pia->type = action->type;
>> +	pia->transfer = conf->transfer;
>>   	printf("Indirect action #%u created\n", pia->id);
>>   	return 0;
>>   }
>> @@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
>>   		for (i = 0; i != n; ++i) {
>>   			struct rte_flow_error error;
>>   			struct port_indirect_action *pia = *tmp;
>> +			portid_t port_id_eff = port_id;
>>
>>   			if (actions[i] != pia->id)
>>   				continue;
>> +
>> +			if (pia->transfer)
>> +				port_id_eff = port->flow_transfer_proxy;
>> +
>> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
>> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
>> +				return -EINVAL;
>> +
>>   			/*
>>   			 * Poisoning to make sure PMDs update it in case
>>   			 * of error.
>> @@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
>>   			memset(&error, 0x33, sizeof(error));
>>
>>   			if (pia->handle && rte_flow_action_handle_destroy(
>> -					port_id, pia->handle, &error)) {
>> +					port_id_eff, pia->handle, &error)) {
>>   				ret = port_flow_complain(&error);
>>   				continue;
>>   			}
>> @@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id,
>> uint32_t id,
>>   	struct rte_flow_error error;
>>   	struct rte_flow_action_handle *action_handle;
>>   	struct port_indirect_action *pia;
>> +	struct rte_port *port;
>>   	const void *update;
>>
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>> +	port = &ports[port_id];
>> +
>>   	action_handle = port_action_handle_get_by_id(port_id, id);
>>   	if (!action_handle)
>>   		return -EINVAL;
>> @@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id,
>> uint32_t id,
>>   		update = action;
>>   		break;
>>   	}
>> +
>> +	if (pia->transfer)
>> +		port_id = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	if (rte_flow_action_handle_update(port_id, action_handle, update,
>>   					  &error)) {
>>   		return port_flow_complain(&error);
>> @@ -1636,6 +1676,14 @@ port_action_handle_query(portid_t port_id,
>> uint32_t id)
>>   		struct rte_flow_query_age age;
>>   		struct rte_flow_action_conntrack ct;
>>   	} query;
>> +	portid_t port_id_eff = port_id;
>> +	struct rte_port *port;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>> +	port = &ports[port_id];
>>
>>   	pia = action_get_by_id(port_id, id);
>>   	if (!pia)
>> @@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id,
>> uint32_t id)
>>   			id, pia->type, port_id);
>>   		return -ENOTSUP;
>>   	}
>> +
>> +	if (pia->transfer)
>> +		port_id_eff = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
>> +	    port_id_eff == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	/* Poisoning to make sure PMDs update it in case of error. */
>>   	memset(&error, 0x55, sizeof(error));
>>   	memset(&query, 0, sizeof(query));
>> -	if (rte_flow_action_handle_query(port_id, pia->handle, &query,
>> &error))
>> +	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
>> +					 &error))
>>   		return port_flow_complain(&error);
>>   	switch (pia->type) {
>>   	case RTE_FLOW_ACTION_TYPE_AGE:
>> @@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,  {
>>   	struct rte_flow_error error;
>>   	struct port_flow_tunnel *pft = NULL;
>> +	struct rte_port *port;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>> +	port = &ports[port_id];
>> +
>> +	if (attr->transfer)
>> +		port_id = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>>
>>   	/* Poisoning to make sure PMDs update it in case of error. */
>>   	memset(&error, 0x11, sizeof(error));
>> @@ -1925,7 +1996,19 @@ port_flow_create(portid_t port_id,
>>   	struct port_flow_tunnel *pft = NULL;
>>   	struct rte_flow_action_age *age = age_action_get(actions);
>>
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	port = &ports[port_id];
>> +
>> +	if (attr->transfer)
>> +		port_id = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	if (port->flow_list) {
>>   		if (port->flow_list->id == UINT32_MAX) {
>>   			fprintf(stderr,
>> @@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const
>> uint32_t *rule)
>>   		uint32_t i;
>>
>>   		for (i = 0; i != n; ++i) {
>> +			portid_t port_id_eff = port_id;
>>   			struct rte_flow_error error;
>>   			struct port_flow *pf = *tmp;
>>
>> @@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t n,
>> const uint32_t *rule)
>>   			 * of error.
>>   			 */
>>   			memset(&error, 0x33, sizeof(error));
>> -			if (rte_flow_destroy(port_id, pf->flow, &error)) {
>> +
>> +			if (pf->rule.attr->transfer)
>> +				port_id_eff = port->flow_transfer_proxy;
>> +
>> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
>> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
>> +				return -EINVAL;
>> +
>> +			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
>>   				ret = port_flow_complain(&error);
>>   				continue;
>>   			}
>> @@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
>>   		fprintf(stderr, "Flow rule #%u not found\n", rule);
>>   		return -ENOENT;
>>   	}
>> +
>> +	if (pf->rule.attr->transfer)
>> +		port_id = port->flow_transfer_proxy;
>> +
>> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
>> +	    port_id == (portid_t)RTE_PORT_ALL)
>> +		return -EINVAL;
>> +
>>   	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
>>   			    &name, sizeof(name),
>>   			    (void *)(uintptr_t)action->type, &error); diff --git
>> a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
>> 97ae52e17e..a88e920bd0 100644
>> --- a/app/test-pmd/testpmd.c
>> +++ b/app/test-pmd/testpmd.c
>> @@ -533,6 +533,25 @@ int proc_id;
>>    */
>>   unsigned int num_procs = 1;
>>
>> +static void
>> +flow_pick_transfer_proxy_mp(uint16_t port_id) {
>> +	struct rte_port *port = &ports[port_id];
>> +	int ret;
>> +
>> +	port->flow_transfer_proxy = port_id;
>> +
>> +	if (!is_proc_primary())
>> +		return;
>> +
>> +	ret = rte_flow_pick_transfer_proxy(port_id, &port-
>>> flow_transfer_proxy,
>> +					   NULL);
>> +	if (ret != 0) {
>> +		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s
>> - ignore\n",
>> +			port_id, rte_strerror(-ret));
>> +	}
>> +}
>> +
>>   static int
>>   eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   		      const struct rte_eth_conf *dev_conf) @@ -1489,6 +1508,8
>> @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
>>   	int ret;
>>   	int i;
>>
>> +	flow_pick_transfer_proxy_mp(pid);
>> +
>>   	port->dev_conf.txmode = tx_mode;
>>   	port->dev_conf.rxmode = rx_mode;
>>
>> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
>> 5863b2f43f..b3dfd350e5 100644
>> --- a/app/test-pmd/testpmd.h
>> +++ b/app/test-pmd/testpmd.h
>> @@ -173,6 +173,8 @@ struct port_indirect_action {
>>   	enum rte_flow_action_type type; /**< Action type. */
>>   	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
>>   	enum age_action_context_type age_type; /**< Age action context
>> type. */
>> +	/** If true, the action applies to "transfer" flows, and vice versa */
>> +	bool transfer;
>>   };
>>
>>   struct port_flow_tunnel {
>> @@ -234,6 +236,8 @@ struct rte_port {
>>   	/**< dynamic flags. */
>>   	uint64_t		mbuf_dynf;
>>   	const struct rte_eth_rxtx_callback
>> *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
>> +	/** Associated port which is supposed to handle "transfer" flows */
>> +	portid_t		flow_transfer_proxy;
>>   };
>>
>>   /**
>> diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c index
>> 14a9a251fb..d9edbbf9ee 100644
>> --- a/app/test-pmd/util.c
>> +++ b/app/test-pmd/util.c
>> @@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
>> struct rte_mbuf *pkts[],
>>   		int ret;
>>   		struct rte_flow_error error;
>>   		struct rte_flow_restore_info info = { 0, };
>> +		struct rte_port *port = &ports[port_id];
>>
>>   		mb = pkts[i];
>>   		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr),
>> &_eth_hdr);
>>   		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
>>   		packet_type = mb->packet_type;
>>   		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
>> -		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
>> +
>> +		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
>> +						mb, &info, &error);
> 
> I'm not sure this is correct,
> Since to restore the data you need to know the port that this traffic was sent to.
> Even if the action was offloaded on the proxy port, it is important to know what was the
> destination port.
> even setting the tunnel must be done on the target port and not the proxy port.

Is tunnel offload a "transfer"-based feature? My answer is "yes". And, 
if we all agree that it's easier to communicate all "transfer"-related 
requests through a single ("transfer" admin) ethdev, then the first 
argument in the highlighted invocation also should be this "proxy" 
ethdev. A unified entry point.

But please don't think me forward: I fully understand your concern about 
the real DPDK port through which the packet was delivered to the 
application. But that should not be a big problem. The mbuf which is 
passed to this API still has its metadata set (tunnel mark, for 
instance) which the PMD can use to recall the port which this packet was 
sent to. More to that, the mbuf even has a dedicated field to express 
exactly what you may want to have - the "port" field. So, when your PMD 
receives the "missed" packet and hands it over to the application 
through some ethdev / port, it can set this mbuf fields to that port ID. 
This way, such information is not lost because of migration to "transfer 
proxy" solution, is it?

> 
>>   		if (!ret) {
>>   			MKDUMPSTR(print_buf, buf_size, cur_len,
>>   				  "restore info:");
>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>> b/doc/guides/rel_notes/release_21_11.rst
>> index 37776c135e..cc0ea4695a 100644
>> --- a/doc/guides/rel_notes/release_21_11.rst
>> +++ b/doc/guides/rel_notes/release_21_11.rst
>> @@ -67,6 +67,9 @@ New Features
>>     Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4
>> and
>>     TCP/UDP/SCTP header checksum field can be used as input set for RSS.
>>
>> +* **Added an API to pick flow transfer proxy port**
>> +  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
>> +
>>   * **Updated Broadcom bnxt PMD.**
>>
>>     * Added flow offload support for Thor.
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>> 647bbf91ce..15e978f7f7 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>>   				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>>   				  NULL, rte_strerror(ENOTSUP));
>>   }
>> +
>> +int
>> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
>> +			     struct rte_flow_error *error)
> 
> What about replaceing pick with get?

There's a school of thought that terms like "get" imply the existence of 
paired actions. For example, "get - set", "probe - unprobe", "allocate - 
free", "init - fini".

So, in order to avoid any wrong assumptions, I believe it's better to 
stick with term "pick" here as it doesn't seem to have a paired term.

> 
>> +{
>> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
>> +	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
>> +
>> +	if (unlikely(ops == NULL))
>> +		return -rte_errno;
>> +
>> +	if (likely(ops->pick_transfer_proxy != NULL)) {
>> +		return flow_err(port_id,
>> +				ops->pick_transfer_proxy(dev, proxy_port_id,
>> +							 error),
>> +				error);
>> +	}
>> +
>> +	*proxy_port_id = port_id;
>> +
>> +	return 0;
>> +}
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> f195aa7224..d2cb476189 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -122,6 +122,10 @@ struct rte_flow_attr {
>>   	 *
>>   	 * In order to match traffic originating from specific source(s), the
>>   	 * application should use pattern items ETHDEV and ESWITCH_PORT.
>> +	 *
>> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
>> +	 * be possible. In order to pick the ethdev suitable for that, the
>> +	 * application should use @p rte_flow_pick_transfer_proxy().
>>   	 */
>>   	uint32_t transfer:1;
>>   	uint32_t reserved:29; /**< Reserved, must be zero. */ @@ -4427,6
>> +4431,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>>   			     struct rte_flow_item *items,
>>   			     uint32_t num_of_items,
>>   			     struct rte_flow_error *error);
>> +
>> +/**
>> + * An application receiving packets on a given ethdev may want to have
>> +their
>> + * processing offloaded to the e-switch lying beneath this ethdev by
>> +means
>> + * of maintaining "transfer" flows. However, it need never use this
>> +exact
>> + * ethdev as an entry point for such flows to be managed through. More
>> +to
>> + * that, this particular ethdev may be short of privileges to control
>> +the
>> + * e-switch. Instead, the application should find an admin ethdev
>> +sitting
>> + * on top of the same e-switch to be used as the entry point (a "proxy").
>> + *
> 
> This explanation is not clear, can you rephrase it?

Could you please be so kind to outline the parts which are not clear to 
you. Maybe your understanding is right in fact but you are just unsure. 
If you expressed your interpretation of this text, I could review it and 
either confirm its correctness or debunk any misunderstanding. In the 
latter case, it would be easier to me to rephrase the comment in the patch.

> 
>> + * This API is a helper to find such "transfer proxy" for a given ethdev.
>> + *
>> + * @note
>> + *   If the PMD serving @p port_id doesn't have the corresponding method
>> + *   implemented, the API will return @p port_id via @p proxy_port_id.
> 
> +1
> 
>> + *
>> + * @param port_id
>> + *   ID of the ethdev in question
>> + * @param[out] proxy_port_id
>> + *   ID of the "transfer proxy"
>> + *
>> + * @return
>> + *   0 on success, a negative error code otherwise
>> + */
>> +__rte_experimental
>> +int
>> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
>> +			     struct rte_flow_error *error);
>>   #ifdef __cplusplus
>>   }
>>   #endif
>> diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h index
>> 46f62c2ec2..ed52e59a0a 100644
>> --- a/lib/ethdev/rte_flow_driver.h
>> +++ b/lib/ethdev/rte_flow_driver.h
>> @@ -139,6 +139,11 @@ struct rte_flow_ops {
>>   		 struct rte_flow_item *pmd_items,
>>   		 uint32_t num_of_items,
>>   		 struct rte_flow_error *err);
>> +	/** See rte_flow_pick_transfer_proxy() */
>> +	int (*pick_transfer_proxy)
>> +		(struct rte_eth_dev *dev,
>> +		 uint16_t *proxy_port_id,
>> +		 struct rte_flow_error *error);
>>   };
>>
>>   /**
>> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index
>> 904bce6ea1..d4286dc8dd 100644
>> --- a/lib/ethdev/version.map
>> +++ b/lib/ethdev/version.map
>> @@ -247,6 +247,9 @@ EXPERIMENTAL {
>>   	rte_mtr_meter_policy_delete;
>>   	rte_mtr_meter_policy_update;
>>   	rte_mtr_meter_policy_validate;
>> +
>> +	# added in 21.11
>> +	rte_flow_pick_transfer_proxy;
>>   };
>>
>>   INTERNAL {
>> --
>> 2.20.1
> 
> Best,
> Ori
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05 12:41     ` Ivan Malov
@ 2021-10-05 16:04       ` Ori Kam
  0 siblings, 0 replies; 161+ messages in thread
From: Ori Kam @ 2021-10-05 16:04 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: Andrew Rybchenko, Xiaoyun Li, NBU-Contact-Thomas Monjalon,
	Ferruh Yigit, Ray Kinsella

Hi Ivan,

I agree with your reply.

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Subject: Re: [PATCH] ethdev: let apps find transfer admin port for a given
> ethdev
> 
> Hi Ori,
> 
> Thanks a lot for eagerly reviewing this and related patches. That's very helpful
> of yours.
> 
> On 05/10/2021 12:22, Ori Kam wrote:
> > Hi Ivan,
> >
> >> -----Original Message-----
> >> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> Sent: Tuesday, October 5, 2021 3:36 AM
> >> Subject: [PATCH] ethdev: let apps find transfer admin port for a
> >> given ethdev
> >>
> >> Introduce a helper API to let applications find transfer admin port
> >> for a given ethdev to avoid failures when managing "transfer" flows
> >> through unprivileged ports.
> >>
> >> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> >> ---
> >> Patch series [1] has reworked support for "transfer" flows.
> >> As a result, an application no longer needs to communicate such flows
> >> through a particular ethdev where it receives the corresponding
> >> packets in the first place.
> >>
> >> Hence, this patch is a legitimate follow-up to the series [1].
> >> At the same time, it's a follow-up to the early RFC [2].
> >>
> >> net/sfc driver is going to support this method. The corresponding
> >> patch is already in progress and will be provided in the course of this release
> cycle.
> >>
> >> [1] https://patches.dpdk.org/project/dpdk/list/?series=19326
> >> [2] https://patches.dpdk.org/project/dpdk/list/?series=18737
> >> ---
> >>   app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
> >>   app/test-pmd/testpmd.c                 |  21 +++++
> >>   app/test-pmd/testpmd.h                 |   4 +
> >>   app/test-pmd/util.c                    |   5 +-
> >>   doc/guides/rel_notes/release_21_11.rst |   3 +
> >>   lib/ethdev/rte_flow.c                  |  22 +++++
> >>   lib/ethdev/rte_flow.h                  |  32 ++++++++
> >>   lib/ethdev/rte_flow_driver.h           |   5 ++
> >>   lib/ethdev/version.map                 |   3 +
> >>   9 files changed, 197 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> >> 9c66329e96..2772c83d0a 100644
> >> --- a/app/test-pmd/config.c
> >> +++ b/app/test-pmd/config.c
> >> @@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id,
> >> uint32_t id,
> >>   	struct port_indirect_action *pia;
> >>   	int ret;
> >>   	struct rte_flow_error error;
> >> +	struct rte_port *port;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >>
> >
> > Is this part of the patch or a general fix?
> 
> I know it might seem unrelated at first glance. But it has to be added here for
> consistency with the rest of the code being added. It should be OK.
> 
Just checking I'm O.K. with it.

> >
> >>   	ret = action_alloc(port_id, id, &pia);
> >>   	if (ret)
> >>   		return ret;
> >> +
> >> +	port = &ports[port_id];
> >> +
> >> +	if (conf->transfer)
> >> +		port_id = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
> >>   		struct rte_flow_action_age *age =
> >>   			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
> @@
> >> -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id,
> >> uint32_t id,
> >>   		return port_flow_complain(&error);
> >>   	}
> >>   	pia->type = action->type;
> >> +	pia->transfer = conf->transfer;
> >>   	printf("Indirect action #%u created\n", pia->id);
> >>   	return 0;
> >>   }
> >> @@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
> >>   		for (i = 0; i != n; ++i) {
> >>   			struct rte_flow_error error;
> >>   			struct port_indirect_action *pia = *tmp;
> >> +			portid_t port_id_eff = port_id;
> >>
> >>   			if (actions[i] != pia->id)
> >>   				continue;
> >> +
> >> +			if (pia->transfer)
> >> +				port_id_eff = port->flow_transfer_proxy;
> >> +
> >> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> >> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
> >> +				return -EINVAL;
> >> +
> >>   			/*
> >>   			 * Poisoning to make sure PMDs update it in case
> >>   			 * of error.
> >> @@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
> >>   			memset(&error, 0x33, sizeof(error));
> >>
> >>   			if (pia->handle && rte_flow_action_handle_destroy(
> >> -					port_id, pia->handle, &error)) {
> >> +					port_id_eff, pia->handle, &error)) {
> >>   				ret = port_flow_complain(&error);
> >>   				continue;
> >>   			}
> >> @@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id,
> >> uint32_t id,
> >>   	struct rte_flow_error error;
> >>   	struct rte_flow_action_handle *action_handle;
> >>   	struct port_indirect_action *pia;
> >> +	struct rte_port *port;
> >>   	const void *update;
> >>
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >> +	port = &ports[port_id];
> >> +
> >>   	action_handle = port_action_handle_get_by_id(port_id, id);
> >>   	if (!action_handle)
> >>   		return -EINVAL;
> >> @@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id,
> >> uint32_t id,
> >>   		update = action;
> >>   		break;
> >>   	}
> >> +
> >> +	if (pia->transfer)
> >> +		port_id = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	if (rte_flow_action_handle_update(port_id, action_handle, update,
> >>   					  &error)) {
> >>   		return port_flow_complain(&error); @@ -1636,6 +1676,14
> @@
> >> port_action_handle_query(portid_t port_id, uint32_t id)
> >>   		struct rte_flow_query_age age;
> >>   		struct rte_flow_action_conntrack ct;
> >>   	} query;
> >> +	portid_t port_id_eff = port_id;
> >> +	struct rte_port *port;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >> +	port = &ports[port_id];
> >>
> >>   	pia = action_get_by_id(port_id, id);
> >>   	if (!pia)
> >> @@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id,
> >> uint32_t id)
> >>   			id, pia->type, port_id);
> >>   		return -ENOTSUP;
> >>   	}
> >> +
> >> +	if (pia->transfer)
> >> +		port_id_eff = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> >> +	    port_id_eff == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	/* Poisoning to make sure PMDs update it in case of error. */
> >>   	memset(&error, 0x55, sizeof(error));
> >>   	memset(&query, 0, sizeof(query));
> >> -	if (rte_flow_action_handle_query(port_id, pia->handle, &query,
> >> &error))
> >> +	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
> >> +					 &error))
> >>   		return port_flow_complain(&error);
> >>   	switch (pia->type) {
> >>   	case RTE_FLOW_ACTION_TYPE_AGE:
> >> @@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,  {
> >>   	struct rte_flow_error error;
> >>   	struct port_flow_tunnel *pft = NULL;
> >> +	struct rte_port *port;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >> +	port = &ports[port_id];
> >> +
> >> +	if (attr->transfer)
> >> +		port_id = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >>
> >>   	/* Poisoning to make sure PMDs update it in case of error. */
> >>   	memset(&error, 0x11, sizeof(error)); @@ -1925,7 +1996,19 @@
> >> port_flow_create(portid_t port_id,
> >>   	struct port_flow_tunnel *pft = NULL;
> >>   	struct rte_flow_action_age *age = age_action_get(actions);
> >>
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	port = &ports[port_id];
> >> +
> >> +	if (attr->transfer)
> >> +		port_id = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	if (port->flow_list) {
> >>   		if (port->flow_list->id == UINT32_MAX) {
> >>   			fprintf(stderr,
> >> @@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n,
> >> const uint32_t *rule)
> >>   		uint32_t i;
> >>
> >>   		for (i = 0; i != n; ++i) {
> >> +			portid_t port_id_eff = port_id;
> >>   			struct rte_flow_error error;
> >>   			struct port_flow *pf = *tmp;
> >>
> >> @@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t
> >> n, const uint32_t *rule)
> >>   			 * of error.
> >>   			 */
> >>   			memset(&error, 0x33, sizeof(error));
> >> -			if (rte_flow_destroy(port_id, pf->flow, &error)) {
> >> +
> >> +			if (pf->rule.attr->transfer)
> >> +				port_id_eff = port->flow_transfer_proxy;
> >> +
> >> +			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
> >> +			    port_id_eff == (portid_t)RTE_PORT_ALL)
> >> +				return -EINVAL;
> >> +
> >> +			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
> >>   				ret = port_flow_complain(&error);
> >>   				continue;
> >>   			}
> >> @@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
> >>   		fprintf(stderr, "Flow rule #%u not found\n", rule);
> >>   		return -ENOENT;
> >>   	}
> >> +
> >> +	if (pf->rule.attr->transfer)
> >> +		port_id = port->flow_transfer_proxy;
> >> +
> >> +	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
> >> +	    port_id == (portid_t)RTE_PORT_ALL)
> >> +		return -EINVAL;
> >> +
> >>   	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
> >>   			    &name, sizeof(name),
> >>   			    (void *)(uintptr_t)action->type, &error); diff --git
> >> a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index
> >> 97ae52e17e..a88e920bd0 100644
> >> --- a/app/test-pmd/testpmd.c
> >> +++ b/app/test-pmd/testpmd.c
> >> @@ -533,6 +533,25 @@ int proc_id;
> >>    */
> >>   unsigned int num_procs = 1;
> >>
> >> +static void
> >> +flow_pick_transfer_proxy_mp(uint16_t port_id) {
> >> +	struct rte_port *port = &ports[port_id];
> >> +	int ret;
> >> +
> >> +	port->flow_transfer_proxy = port_id;
> >> +
> >> +	if (!is_proc_primary())
> >> +		return;
> >> +
> >> +	ret = rte_flow_pick_transfer_proxy(port_id, &port-
> >>> flow_transfer_proxy,
> >> +					   NULL);
> >> +	if (ret != 0) {
> >> +		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s
> >> - ignore\n",
> >> +			port_id, rte_strerror(-ret));
> >> +	}
> >> +}
> >> +
> >>   static int
> >>   eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t
> nb_tx_q,
> >>   		      const struct rte_eth_conf *dev_conf) @@ -1489,6 +1508,8
> @@
> >> init_config_port_offloads(portid_t pid, uint32_t socket_id)
> >>   	int ret;
> >>   	int i;
> >>
> >> +	flow_pick_transfer_proxy_mp(pid);
> >> +
> >>   	port->dev_conf.txmode = tx_mode;
> >>   	port->dev_conf.rxmode = rx_mode;
> >>
> >> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index
> >> 5863b2f43f..b3dfd350e5 100644
> >> --- a/app/test-pmd/testpmd.h
> >> +++ b/app/test-pmd/testpmd.h
> >> @@ -173,6 +173,8 @@ struct port_indirect_action {
> >>   	enum rte_flow_action_type type; /**< Action type. */
> >>   	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
> >>   	enum age_action_context_type age_type; /**< Age action context
> >> type. */
> >> +	/** If true, the action applies to "transfer" flows, and vice versa */
> >> +	bool transfer;
> >>   };
> >>
> >>   struct port_flow_tunnel {
> >> @@ -234,6 +236,8 @@ struct rte_port {
> >>   	/**< dynamic flags. */
> >>   	uint64_t		mbuf_dynf;
> >>   	const struct rte_eth_rxtx_callback
> >> *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
> >> +	/** Associated port which is supposed to handle "transfer" flows */
> >> +	portid_t		flow_transfer_proxy;
> >>   };
> >>
> >>   /**
> >> diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c index
> >> 14a9a251fb..d9edbbf9ee 100644
> >> --- a/app/test-pmd/util.c
> >> +++ b/app/test-pmd/util.c
> >> @@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
> >> struct rte_mbuf *pkts[],
> >>   		int ret;
> >>   		struct rte_flow_error error;
> >>   		struct rte_flow_restore_info info = { 0, };
> >> +		struct rte_port *port = &ports[port_id];
> >>
> >>   		mb = pkts[i];
> >>   		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr),
> &_eth_hdr);
> >>   		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
> >>   		packet_type = mb->packet_type;
> >>   		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
> >> -		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
> >> +
> >> +		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
> >> +						mb, &info, &error);
> >
> > I'm not sure this is correct,
> > Since to restore the data you need to know the port that this traffic was sent
> to.
> > Even if the action was offloaded on the proxy port, it is important to
> > know what was the destination port.
> > even setting the tunnel must be done on the target port and not the proxy
> port.
> 
> Is tunnel offload a "transfer"-based feature? My answer is "yes". And, if we all
> agree that it's easier to communicate all "transfer"-related requests through a
> single ("transfer" admin) ethdev, then the first argument in the highlighted
> invocation also should be this "proxy"
> ethdev. A unified entry point.
> 
> But please don't think me forward: I fully understand your concern about the
> real DPDK port through which the packet was delivered to the application. But
> that should not be a big problem. The mbuf which is passed to this API still has
> its metadata set (tunnel mark, for
> instance) which the PMD can use to recall the port which this packet was sent
> to. More to that, the mbuf even has a dedicated field to express exactly what
> you may want to have - the "port" field. So, when your PMD receives the
> "missed" packet and hands it over to the application through some ethdev /
> port, it can set this mbuf fields to that port ID.
> This way, such information is not lost because of migration to "transfer proxy"
> solution, is it?
> 

Yes this answer my concerns (maybe there will some time penaltiy to set this value)
but it looks legit.

> >
> >>   		if (!ret) {
> >>   			MKDUMPSTR(print_buf, buf_size, cur_len,
> >>   				  "restore info:");
> >> diff --git a/doc/guides/rel_notes/release_21_11.rst
> >> b/doc/guides/rel_notes/release_21_11.rst
> >> index 37776c135e..cc0ea4695a 100644
> >> --- a/doc/guides/rel_notes/release_21_11.rst
> >> +++ b/doc/guides/rel_notes/release_21_11.rst
> >> @@ -67,6 +67,9 @@ New Features
> >>     Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now
> IPv4
> >> and
> >>     TCP/UDP/SCTP header checksum field can be used as input set for RSS.
> >>
> >> +* **Added an API to pick flow transfer proxy port**
> >> +  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
> >> +
> >>   * **Updated Broadcom bnxt PMD.**
> >>
> >>     * Added flow offload support for Thor.
> >> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> >> 647bbf91ce..15e978f7f7 100644
> >> --- a/lib/ethdev/rte_flow.c
> >> +++ b/lib/ethdev/rte_flow.c
> >> @@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
> >>   				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> >>   				  NULL, rte_strerror(ENOTSUP));
> >>   }
> >> +
> >> +int
> >> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> >> +			     struct rte_flow_error *error)
> >
> > What about replaceing pick with get?
> 
> There's a school of thought that terms like "get" imply the existence of paired
> actions. For example, "get - set", "probe - unprobe", "allocate - free", "init -
> fini".
>
> So, in order to avoid any wrong assumptions, I believe it's better to stick with
> term "pick" here as it doesn't seem to have a paired term.
>
I still think get is better, but lets leave it like this.
 
> >
> >> +{
> >> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> >> +	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
> >> +
> >> +	if (unlikely(ops == NULL))
> >> +		return -rte_errno;
> >> +
> >> +	if (likely(ops->pick_transfer_proxy != NULL)) {
> >> +		return flow_err(port_id,
> >> +				ops->pick_transfer_proxy(dev, proxy_port_id,
> >> +							 error),
> >> +				error);
> >> +	}
> >> +
> >> +	*proxy_port_id = port_id;
> >> +
> >> +	return 0;
> >> +}
> >> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >> f195aa7224..d2cb476189 100644
> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> @@ -122,6 +122,10 @@ struct rte_flow_attr {
> >>   	 *
> >>   	 * In order to match traffic originating from specific source(s), the
> >>   	 * application should use pattern items ETHDEV and ESWITCH_PORT.
> >> +	 *
> >> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
> >> +	 * be possible. In order to pick the ethdev suitable for that, the
> >> +	 * application should use @p rte_flow_pick_transfer_proxy().
> >>   	 */
> >>   	uint32_t transfer:1;
> >>   	uint32_t reserved:29; /**< Reserved, must be zero. */ @@ -4427,6
> >> +4431,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
> >>   			     struct rte_flow_item *items,
> >>   			     uint32_t num_of_items,
> >>   			     struct rte_flow_error *error);
> >> +
> >> +/**
> >> + * An application receiving packets on a given ethdev may want to
> >> +have their
> >> + * processing offloaded to the e-switch lying beneath this ethdev by
> >> +means
> >> + * of maintaining "transfer" flows. However, it need never use this
> >> +exact
> >> + * ethdev as an entry point for such flows to be managed through.
> >> +More to
> >> + * that, this particular ethdev may be short of privileges to
> >> +control the
> >> + * e-switch. Instead, the application should find an admin ethdev
> >> +sitting
> >> + * on top of the same e-switch to be used as the entry point (a "proxy").
> >> + *
> >
> > This explanation is not clear, can you rephrase it?
> 
> Could you please be so kind to outline the parts which are not clear to you.
> Maybe your understanding is right in fact but you are just unsure.
> If you expressed your interpretation of this text, I could review it and either
> confirm its correctness or debunk any misunderstanding. In the latter case, it
> would be easier to me to rephrase the comment in the patch.
> 

After a few more reads I can't point my finger to it.
Lets leave it.

> >
> >> + * This API is a helper to find such "transfer proxy" for a given ethdev.
> >> + *
> >> + * @note
> >> + *   If the PMD serving @p port_id doesn't have the corresponding method
> >> + *   implemented, the API will return @p port_id via @p proxy_port_id.
> >
> > +1
> >
> >> + *
> >> + * @param port_id
> >> + *   ID of the ethdev in question
> >> + * @param[out] proxy_port_id
> >> + *   ID of the "transfer proxy"
> >> + *
> >> + * @return
> >> + *   0 on success, a negative error code otherwise
> >> + */
> >> +__rte_experimental
> >> +int
> >> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> >> +			     struct rte_flow_error *error);
> >>   #ifdef __cplusplus
> >>   }
> >>   #endif
> >> diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
> index
> >> 46f62c2ec2..ed52e59a0a 100644
> >> --- a/lib/ethdev/rte_flow_driver.h
> >> +++ b/lib/ethdev/rte_flow_driver.h
> >> @@ -139,6 +139,11 @@ struct rte_flow_ops {
> >>   		 struct rte_flow_item *pmd_items,
> >>   		 uint32_t num_of_items,
> >>   		 struct rte_flow_error *err);
> >> +	/** See rte_flow_pick_transfer_proxy() */
> >> +	int (*pick_transfer_proxy)
> >> +		(struct rte_eth_dev *dev,
> >> +		 uint16_t *proxy_port_id,
> >> +		 struct rte_flow_error *error);
> >>   };
> >>
> >>   /**
> >> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map index
> >> 904bce6ea1..d4286dc8dd 100644
> >> --- a/lib/ethdev/version.map
> >> +++ b/lib/ethdev/version.map
> >> @@ -247,6 +247,9 @@ EXPERIMENTAL {
> >>   	rte_mtr_meter_policy_delete;
> >>   	rte_mtr_meter_policy_update;
> >>   	rte_mtr_meter_policy_validate;
> >> +
> >> +	# added in 21.11
> >> +	rte_flow_pick_transfer_proxy;
> >>   };
> >>
> >>   INTERNAL {
> >> --
> >> 2.20.1
> >
> > Best,
> > Ori
> >
> 
> --
> Ivan M


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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
  2021-10-05  9:22   ` Ori Kam
@ 2021-10-05 17:56   ` Thomas Monjalon
  2021-10-05 18:22     ` Ivan Malov
  2021-10-05 21:10   ` [dpdk-dev] [PATCH v2] ethdev: add API to query proxy port to manage transfer flows Ivan Malov
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 161+ messages in thread
From: Thomas Monjalon @ 2021-10-05 17:56 UTC (permalink / raw)
  To: Ivan Malov
  Cc: dev, Andrew Rybchenko, Xiaoyun Li, Ori Kam, Ferruh Yigit, Ray Kinsella

05/10/2021 02:36, Ivan Malov:
> Introduce a helper API to let applications find transfer
> admin port for a given ethdev to avoid failures when
> managing "transfer" flows through unprivileged ports.

Please explain what is transfer admin port.
We may find a simpler wording.

> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> +	 *
> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
> +	 * be possible. In order to pick the ethdev suitable for that, the

ethdev -> port

> +	 * application should use @p rte_flow_pick_transfer_proxy().
>  	 */
>  	uint32_t transfer:1;
[...]
> +/**

Please insert an one-line description here.

> + * An application receiving packets on a given ethdev may want to have their
> + * processing offloaded to the e-switch lying beneath this ethdev by means

Is "e-switch" a common word? Or should we say "embedded switch"?

> + * of maintaining "transfer" flows. However, it need never use this exact
> + * ethdev as an entry point for such flows to be managed through. More to
> + * that, this particular ethdev may be short of privileges to control the
> + * e-switch. Instead, the application should find an admin ethdev sitting
> + * on top of the same e-switch to be used as the entry point (a "proxy").

I recognize the nice right-alignment, but I think this text can be shorter.

> + *
> + * This API is a helper to find such "transfer proxy" for a given ethdev.
> + *
> + * @note
> + *   If the PMD serving @p port_id doesn't have the corresponding method
> + *   implemented, the API will return @p port_id via @p proxy_port_id.
> + *
> + * @param port_id
> + *   ID of the ethdev in question

The rest of the API says "port", not "ethdev".
Here I would suggest "ID of the port to look from."

> + * @param[out] proxy_port_id
> + *   ID of the "transfer proxy"
> + *
> + * @return
> + *   0 on success, a negative error code otherwise
> + */
> +__rte_experimental
> +int
> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> +			     struct rte_flow_error *error);




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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05 17:56   ` Thomas Monjalon
@ 2021-10-05 18:22     ` Ivan Malov
  2021-10-05 19:04       ` Thomas Monjalon
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-05 18:22 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Andrew Rybchenko, Xiaoyun Li, Ori Kam, Ferruh Yigit, Ray Kinsella

Hi Thomas,

Thanks for joining the review.

On 05/10/2021 20:56, Thomas Monjalon wrote:
> 05/10/2021 02:36, Ivan Malov:
>> Introduce a helper API to let applications find transfer
>> admin port for a given ethdev to avoid failures when
>> managing "transfer" flows through unprivileged ports.
> 
> Please explain what is transfer admin port.
> We may find a simpler wording.

It's an ethdev which has the privilege to control the embedded switch. 
Typically, it's a PF ethdev.

Flows with "transfer" attribute apply to the e-switch level. So 
"transfer admin port" reads the same as "e-switch admin port".

> 
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> +	 *
>> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
>> +	 * be possible. In order to pick the ethdev suitable for that, the
> 
> ethdev -> port

Why? "Ethdev" is a clearer term for "port".

> 
>> +	 * application should use @p rte_flow_pick_transfer_proxy().
>>   	 */
>>   	uint32_t transfer:1;
> [...]
>> +/**
> 
> Please insert an one-line description here.

Do you want me to make the first line of the description stand out? Like 
a brief summary / title?

> 
>> + * An application receiving packets on a given ethdev may want to have their
>> + * processing offloaded to the e-switch lying beneath this ethdev by means
> 
> Is "e-switch" a common word? Or should we say "embedded switch"?

Term "e-switch" is a contraction for "embedded switch". I'd go for the 
short version.

> 
>> + * of maintaining "transfer" flows. However, it need never use this exact
>> + * ethdev as an entry point for such flows to be managed through. More to
>> + * that, this particular ethdev may be short of privileges to control the
>> + * e-switch. Instead, the application should find an admin ethdev sitting
>> + * on top of the same e-switch to be used as the entry point (a "proxy").
> 
> I recognize the nice right-alignment, but I think this text can be shorter.

No right-alignment here: the last line in the block is not aligned. I 
wasn't looking to make this paragraph shorter or longer. I was looking 
to introduce the problem clearly. If you believe that I failed to do so, 
could you please highlight the parts which sound misleading to you.

> 
>> + *
>> + * This API is a helper to find such "transfer proxy" for a given ethdev.
>> + *
>> + * @note
>> + *   If the PMD serving @p port_id doesn't have the corresponding method
>> + *   implemented, the API will return @p port_id via @p proxy_port_id.
>> + *
>> + * @param port_id
>> + *   ID of the ethdev in question
> 
> The rest of the API says "port", not "ethdev".
> Here I would suggest "ID of the port to look from."

The argument name is "port_id". This is for consistency with other API 
signatures across DPDK. But, in comments, I'd stick with "ethdev". It's 
clearer than "port".

How about "ID of the ethdev to find the proxy for"?

> 
>> + * @param[out] proxy_port_id
>> + *   ID of the "transfer proxy"
>> + *
>> + * @return
>> + *   0 on success, a negative error code otherwise
>> + */
>> +__rte_experimental
>> +int
>> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
>> +			     struct rte_flow_error *error);
> 
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev
  2021-10-05 18:22     ` Ivan Malov
@ 2021-10-05 19:04       ` Thomas Monjalon
  0 siblings, 0 replies; 161+ messages in thread
From: Thomas Monjalon @ 2021-10-05 19:04 UTC (permalink / raw)
  To: Ivan Malov
  Cc: dev, Andrew Rybchenko, Xiaoyun Li, Ori Kam, Ferruh Yigit, Ray Kinsella

05/10/2021 20:22, Ivan Malov:
> Hi Thomas,
> 
> Thanks for joining the review.
> 
> On 05/10/2021 20:56, Thomas Monjalon wrote:
> > 05/10/2021 02:36, Ivan Malov:
> >> Introduce a helper API to let applications find transfer
> >> admin port for a given ethdev to avoid failures when
> >> managing "transfer" flows through unprivileged ports.
> > 
> > Please explain what is transfer admin port.
> > We may find a simpler wording.
> 
> It's an ethdev which has the privilege to control the embedded switch. 
> Typically, it's a PF ethdev.
> 
> Flows with "transfer" attribute apply to the e-switch level. So 
> "transfer admin port" reads the same as "e-switch admin port".

Please explain this in the v2.

> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> +	 *
> >> +	 * Communicating "transfer" flows via unprivileged ethdevs may not
> >> +	 * be possible. In order to pick the ethdev suitable for that, the
> > 
> > ethdev -> port
> 
> Why? "Ethdev" is a clearer term for "port".

Because the API mention ports, not ethdevs. Example: port_id, not ethdev_id.

> >> +	 * application should use @p rte_flow_pick_transfer_proxy().
> >>   	 */
> >>   	uint32_t transfer:1;
> > [...]
> >> +/**
> > 
> > Please insert an one-line description here.
> 
> Do you want me to make the first line of the description stand out? Like 
> a brief summary / title?

Yes like a title.
A proposal: "Get the proxy port able to manage transfer rules in e-switch."

> >> + * An application receiving packets on a given ethdev may want to have their
> >> + * processing offloaded to the e-switch lying beneath this ethdev by means
> > 
> > Is "e-switch" a common word? Or should we say "embedded switch"?
> 
> Term "e-switch" is a contraction for "embedded switch". I'd go for the 
> short version.
> 
> >> + * of maintaining "transfer" flows. However, it need never use this exact
> >> + * ethdev as an entry point for such flows to be managed through. More to
> >> + * that, this particular ethdev may be short of privileges to control the
> >> + * e-switch. Instead, the application should find an admin ethdev sitting
> >> + * on top of the same e-switch to be used as the entry point (a "proxy").
> > 
> > I recognize the nice right-alignment, but I think this text can be shorter.
> 
> No right-alignment here: the last line in the block is not aligned. I 
> wasn't looking to make this paragraph shorter or longer. I was looking 
> to introduce the problem clearly. If you believe that I failed to do so, 
> could you please highlight the parts which sound misleading to you.

The words misleading me are: "application", "lying beneath", "never",
"sitting on top", "entry point".
I prefer not talking about application, and avoid story telling style.

> >> + *
> >> + * This API is a helper to find such "transfer proxy" for a given ethdev.

I suggest something like this:
"
The transfer flow must be managed by privileged ports.
For some devices, all ports are privileged,
while some allow only one port to control the e-switch.
This function returns a port (proxy) in the same e-switch domain,
usable for managing transfer rules.
"

> >> + *
> >> + * @note
> >> + *   If the PMD serving @p port_id doesn't have the corresponding method
> >> + *   implemented, the API will return @p port_id via @p proxy_port_id.
> >> + *
> >> + * @param port_id
> >> + *   ID of the ethdev in question
> > 
> > The rest of the API says "port", not "ethdev".
> > Here I would suggest "ID of the port to look from."
> 
> The argument name is "port_id". This is for consistency with other API 
> signatures across DPDK. But, in comments, I'd stick with "ethdev". It's 
> clearer than "port".
> 
> How about "ID of the ethdev to find the proxy for"?

I like it except "ethdev" :)




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

* [dpdk-dev] [PATCH v2] ethdev: add API to query proxy port to manage transfer flows
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
  2021-10-05  9:22   ` Ori Kam
  2021-10-05 17:56   ` Thomas Monjalon
@ 2021-10-05 21:10   ` Ivan Malov
  2021-10-06  7:47     ` Andrew Rybchenko
  2021-10-06 12:33   ` [dpdk-dev] [PATCH v3] " Ivan Malov
  2021-10-14  3:21   ` [dpdk-dev] [PATCH v4] " Ivan Malov
  4 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-05 21:10 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	Ferruh Yigit, Ray Kinsella

Not all DPDK ports in a given e-switch domain may have the
privilege to manage "transfer" flows. Add an API to find a
port with sufficient privileges by any port in the domain.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
---
Patch series [1] has reworked support for "transfer" flows.
This allows to elaborate on the idea which first appeared
in RFC [2]. Hence the patch in question.

net/sfc driver is going to support the new API. The
corresponding patch is already in progress and will
be provided in the course of this release cycle.

[1] https://patches.dpdk.org/project/dpdk/list/?series=19326
[2] https://patches.dpdk.org/project/dpdk/list/?series=18737
---
 app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
 app/test-pmd/testpmd.c                 |  21 +++++
 app/test-pmd/testpmd.h                 |   4 +
 app/test-pmd/util.c                    |   5 +-
 doc/guides/rel_notes/release_21_11.rst |   3 +
 lib/ethdev/rte_flow.c                  |  22 +++++
 lib/ethdev/rte_flow.h                  |  31 ++++++++
 lib/ethdev/rte_flow_driver.h           |   5 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 196 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9c66329e96..2772c83d0a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 	struct port_indirect_action *pia;
 	int ret;
 	struct rte_flow_error error;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	ret = action_alloc(port_id, id, &pia);
 	if (ret)
 		return ret;
+
+	port = &ports[port_id];
+
+	if (conf->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
 		struct rte_flow_action_age *age =
 			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
@@ -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 		return port_flow_complain(&error);
 	}
 	pia->type = action->type;
+	pia->transfer = conf->transfer;
 	printf("Indirect action #%u created\n", pia->id);
 	return 0;
 }
@@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
 		for (i = 0; i != n; ++i) {
 			struct rte_flow_error error;
 			struct port_indirect_action *pia = *tmp;
+			portid_t port_id_eff = port_id;
 
 			if (actions[i] != pia->id)
 				continue;
+
+			if (pia->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
 			/*
 			 * Poisoning to make sure PMDs update it in case
 			 * of error.
@@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
 			memset(&error, 0x33, sizeof(error));
 
 			if (pia->handle && rte_flow_action_handle_destroy(
-					port_id, pia->handle, &error)) {
+					port_id_eff, pia->handle, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	struct rte_flow_error error;
 	struct rte_flow_action_handle *action_handle;
 	struct port_indirect_action *pia;
+	struct rte_port *port;
 	const void *update;
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
 	action_handle = port_action_handle_get_by_id(port_id, id);
 	if (!action_handle)
 		return -EINVAL;
@@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 		update = action;
 		break;
 	}
+
+	if (pia->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (rte_flow_action_handle_update(port_id, action_handle, update,
 					  &error)) {
 		return port_flow_complain(&error);
@@ -1636,6 +1676,14 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 		struct rte_flow_query_age age;
 		struct rte_flow_action_conntrack ct;
 	} query;
+	portid_t port_id_eff = port_id;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
 
 	pia = action_get_by_id(port_id, id);
 	if (!pia)
@@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 			id, pia->type, port_id);
 		return -ENOTSUP;
 	}
+
+	if (pia->transfer)
+		port_id_eff = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+	    port_id_eff == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x55, sizeof(error));
 	memset(&query, 0, sizeof(query));
-	if (rte_flow_action_handle_query(port_id, pia->handle, &query, &error))
+	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
+					 &error))
 		return port_flow_complain(&error);
 	switch (pia->type) {
 	case RTE_FLOW_ACTION_TYPE_AGE:
@@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,
 {
 	struct rte_flow_error error;
 	struct port_flow_tunnel *pft = NULL;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
@@ -1925,7 +1996,19 @@ port_flow_create(portid_t port_id,
 	struct port_flow_tunnel *pft = NULL;
 	struct rte_flow_action_age *age = age_action_get(actions);
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (port->flow_list) {
 		if (port->flow_list->id == UINT32_MAX) {
 			fprintf(stderr,
@@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 		uint32_t i;
 
 		for (i = 0; i != n; ++i) {
+			portid_t port_id_eff = port_id;
 			struct rte_flow_error error;
 			struct port_flow *pf = *tmp;
 
@@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 			 * of error.
 			 */
 			memset(&error, 0x33, sizeof(error));
-			if (rte_flow_destroy(port_id, pf->flow, &error)) {
+
+			if (pf->rule.attr->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
+			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
 		fprintf(stderr, "Flow rule #%u not found\n", rule);
 		return -ENOENT;
 	}
+
+	if (pf->rule.attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
 			    &name, sizeof(name),
 			    (void *)(uintptr_t)action->type, &error);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 97ae52e17e..a88e920bd0 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -533,6 +533,25 @@ int proc_id;
  */
 unsigned int num_procs = 1;
 
+static void
+flow_pick_transfer_proxy_mp(uint16_t port_id)
+{
+	struct rte_port *port = &ports[port_id];
+	int ret;
+
+	port->flow_transfer_proxy = port_id;
+
+	if (!is_proc_primary())
+		return;
+
+	ret = rte_flow_pick_transfer_proxy(port_id, &port->flow_transfer_proxy,
+					   NULL);
+	if (ret != 0) {
+		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s - ignore\n",
+			port_id, rte_strerror(-ret));
+	}
+}
+
 static int
 eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
@@ -1489,6 +1508,8 @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
 	int ret;
 	int i;
 
+	flow_pick_transfer_proxy_mp(pid);
+
 	port->dev_conf.txmode = tx_mode;
 	port->dev_conf.rxmode = rx_mode;
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 5863b2f43f..b3dfd350e5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -173,6 +173,8 @@ struct port_indirect_action {
 	enum rte_flow_action_type type; /**< Action type. */
 	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
 	enum age_action_context_type age_type; /**< Age action context type. */
+	/** If true, the action applies to "transfer" flows, and vice versa */
+	bool transfer;
 };
 
 struct port_flow_tunnel {
@@ -234,6 +236,8 @@ struct rte_port {
 	/**< dynamic flags. */
 	uint64_t		mbuf_dynf;
 	const struct rte_eth_rxtx_callback *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
+	/** Associated port which is supposed to handle "transfer" flows */
+	portid_t		flow_transfer_proxy;
 };
 
 /**
diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
index 14a9a251fb..d9edbbf9ee 100644
--- a/app/test-pmd/util.c
+++ b/app/test-pmd/util.c
@@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 		int ret;
 		struct rte_flow_error error;
 		struct rte_flow_restore_info info = { 0, };
+		struct rte_port *port = &ports[port_id];
 
 		mb = pkts[i];
 		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr), &_eth_hdr);
 		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
 		packet_type = mb->packet_type;
 		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
-		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
+
+		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
+						mb, &info, &error);
 		if (!ret) {
 			MKDUMPSTR(print_buf, buf_size, cur_len,
 				  "restore info:");
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 0787baed8c..5de30fad9c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -67,6 +67,9 @@ New Features
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
   TCP/UDP/SCTP header checksum field can be used as input set for RSS.
 
+* **Added an API to get a proxy port to manage "transfer" (e-switch) flows**
+  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
+
 * **Updated Broadcom bnxt PMD.**
 
   * Added flow offload support for Thor.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 647bbf91ce..15e978f7f7 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				  NULL, rte_strerror(ENOTSUP));
 }
+
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(ops == NULL))
+		return -rte_errno;
+
+	if (likely(ops->pick_transfer_proxy != NULL)) {
+		return flow_err(port_id,
+				ops->pick_transfer_proxy(dev, proxy_port_id,
+							 error),
+				error);
+	}
+
+	*proxy_port_id = port_id;
+
+	return 0;
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index f195aa7224..5405e2565a 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -122,6 +122,9 @@ struct rte_flow_attr {
 	 *
 	 * In order to match traffic originating from specific source(s), the
 	 * application should use pattern items ETHDEV and ESWITCH_PORT.
+	 *
+	 * Managing "transfer" flows requires that the user communicate them
+	 * through a suitable port. @see rte_flow_pick_transfer_proxy().
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
@@ -4427,6 +4430,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 			     struct rte_flow_item *items,
 			     uint32_t num_of_items,
 			     struct rte_flow_error *error);
+
+/**
+ * Get a proxy port to manage "transfer" (e-switch) flows.
+ *
+ * Managing "transfer" flows requires that the user communicate them
+ * through a port which has the privilege to control the e-switch.
+ * For some vendors, all ports in a given e-switch domain have
+ * this privilege. For other vendors, it's only one port.
+ *
+ * This API indicates such a privileged port (a "proxy")
+ * for a given port in the same e-switch domain.
+ *
+ * @note
+ *   If the PMD serving @p port_id doesn't have the corresponding method
+ *   implemented, the API will return @p port_id via @p proxy_port_id.
+ *
+ * @param port_id
+ *   Indicates the port to get a "proxy" for
+ * @param[out] proxy_port_id
+ *   Indicates the "proxy" port
+ *
+ * @return
+ *   0 on success, a negative error code otherwise
+ */
+__rte_experimental
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index 46f62c2ec2..ed52e59a0a 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -139,6 +139,11 @@ struct rte_flow_ops {
 		 struct rte_flow_item *pmd_items,
 		 uint32_t num_of_items,
 		 struct rte_flow_error *err);
+	/** See rte_flow_pick_transfer_proxy() */
+	int (*pick_transfer_proxy)
+		(struct rte_eth_dev *dev,
+		 uint16_t *proxy_port_id,
+		 struct rte_flow_error *error);
 };
 
 /**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 904bce6ea1..d4286dc8dd 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -247,6 +247,9 @@ EXPERIMENTAL {
 	rte_mtr_meter_policy_delete;
 	rte_mtr_meter_policy_update;
 	rte_mtr_meter_policy_validate;
+
+	# added in 21.11
+	rte_flow_pick_transfer_proxy;
 };
 
 INTERNAL {
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2] ethdev: add API to query proxy port to manage transfer flows
  2021-10-05 21:10   ` [dpdk-dev] [PATCH v2] ethdev: add API to query proxy port to manage transfer flows Ivan Malov
@ 2021-10-06  7:47     ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-06  7:47 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Ray Kinsella

On 10/6/21 12:10 AM, Ivan Malov wrote:
> Not all DPDK ports in a given e-switch domain may have the

Search in the Internet does not provide e-switch as a shorter
form of "embedded switch". So, I agree with Thomas, it is
better to avoid it in the documentation. Especially taking
into account that there is a company with a similar name.

I.e. e-switch -> embedded switch

> privilege to manage "transfer" flows. Add an API to find a
> port with sufficient privileges by any port in the domain.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

I have to review it better before, but it is better to do it
later than never.

> Acked-by: Ori Kam <orika@nvidia.com>
> ---
> Patch series [1] has reworked support for "transfer" flows.
> This allows to elaborate on the idea which first appeared
> in RFC [2]. Hence the patch in question.
> 
> net/sfc driver is going to support the new API. The
> corresponding patch is already in progress and will
> be provided in the course of this release cycle.
> 
> [1] https://patches.dpdk.org/project/dpdk/list/?series=19326
> [2] https://patches.dpdk.org/project/dpdk/list/?series=18737

[snip]

> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index 0787baed8c..5de30fad9c 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -67,6 +67,9 @@ New Features
>    Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
>    TCP/UDP/SCTP header checksum field can be used as input set for RSS.
>  
> +* **Added an API to get a proxy port to manage "transfer" (e-switch) flows**

Let's avoid (e-switch) here. I guess initial definition of the
transfer intentionally avoid the term.

> +  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
> +
>  * **Updated Broadcom bnxt PMD.**
>  
>    * Added flow offload support for Thor.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 647bbf91ce..15e978f7f7 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>  				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>  				  NULL, rte_strerror(ENOTSUP));
>  }
> +
> +int
> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> +			     struct rte_flow_error *error)
> +{
> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];

Let's avoid initialization here since 'port_id' is not checked
yet to be correct. Let's assign dev below just before usage.

> +	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
> +
> +	if (unlikely(ops == NULL))
> +		return -rte_errno;
> +
> +	if (likely(ops->pick_transfer_proxy != NULL)) {

Yes, I see that it is the stile in the file to expect
non-NULL callback, it is a bit unfair to say so when
just driver implements it. So, I suggest to remove it.
Also it is not an error or exception. It is documented
behaviour.

> +		return flow_err(port_id,
> +				ops->pick_transfer_proxy(dev, proxy_port_id,
> +							 error),
> +				error);
> +	}
> +
> +	*proxy_port_id = port_id;

I think code will have less lines and easier to read if
we revert above if condition, do the assignment and
return 0 from its body.

> +
> +	return 0;
> +}
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index f195aa7224..5405e2565a 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h

[snip]

> @@ -4427,6 +4430,34 @@ rte_flow_tunnel_item_release(uint16_t port_id,
>  			     struct rte_flow_item *items,
>  			     uint32_t num_of_items,
>  			     struct rte_flow_error *error);
> +
> +/**

Don't we need experimental header here?

> + * Get a proxy port to manage "transfer" (e-switch) flows.

I suggest to have no (e-switch) here as well. "transfer" is
sufficient.

> + *
> + * Managing "transfer" flows requires that the user communicate them
> + * through a port which has the privilege to control the e-switch.

e-switch -> embedded switch

> + * For some vendors, all ports in a given e-switch domain have

e-switch -> embedded switch, or "switching domain"

> + * this privilege. For other vendors, it's only one port.
> + *
> + * This API indicates such a privileged port (a "proxy")
> + * for a given port in the same e-switch domain.

e-switch -> embedded switch, or "switching domain"

> + *
> + * @note
> + *   If the PMD serving @p port_id doesn't have the corresponding method
> + *   implemented, the API will return @p port_id via @p proxy_port_id.
> + *
> + * @param port_id
> + *   Indicates the port to get a "proxy" for
> + * @param[out] proxy_port_id
> + *   Indicates the "proxy" port

I should notice it earlier, but 'error' parameter description
is missing here.

> + *
> + * @return
> + *   0 on success, a negative error code otherwise
> + */
> +__rte_experimental
> +int
> +rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
> +			     struct rte_flow_error *error);
>  #ifdef __cplusplus
>  }
>  #endif


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

* [dpdk-dev] [PATCH v3] ethdev: add API to query proxy port to manage transfer flows
  2021-10-05  0:36 ` [dpdk-dev] [PATCH] ethdev: let apps find transfer admin port for a given ethdev Ivan Malov
                     ` (2 preceding siblings ...)
  2021-10-05 21:10   ` [dpdk-dev] [PATCH v2] ethdev: add API to query proxy port to manage transfer flows Ivan Malov
@ 2021-10-06 12:33   ` Ivan Malov
  2021-10-14  3:21   ` [dpdk-dev] [PATCH v4] " Ivan Malov
  4 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-06 12:33 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li,
	Ferruh Yigit, Ray Kinsella

Not all DPDK ports in a given switching domain may have the
privilege to manage "transfer" flows. Add an API to find a
port with sufficient privileges by any port in the domain.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
---
Patch series [1] has reworked support for "transfer" flows.
This allows to elaborate on the idea which first appeared
in RFC [2]. Hence the patch in question.

net/sfc driver is going to support the new API. The
corresponding patch is already in progress and will
be provided in the course of this release cycle.

[1] https://patches.dpdk.org/project/dpdk/list/?series=19326
[2] https://patches.dpdk.org/project/dpdk/list/?series=18737

Changes in v2:
* The patch has review notes from Thomas Monjalon applied
* The patch has the ack from Ori Kam added

Changes in v3:
* The patch has review notes from Andrew Rybchenko applied
---
 app/test-pmd/config.c                  | 106 ++++++++++++++++++++++++-
 app/test-pmd/testpmd.c                 |  21 +++++
 app/test-pmd/testpmd.h                 |   4 +
 app/test-pmd/util.c                    |   5 +-
 doc/guides/rel_notes/release_21_11.rst |   3 +
 lib/ethdev/rte_flow.c                  |  22 +++++
 lib/ethdev/rte_flow.h                  |  36 +++++++++
 lib/ethdev/rte_flow_driver.h           |   5 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 201 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9c66329e96..2772c83d0a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1505,10 +1505,25 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 	struct port_indirect_action *pia;
 	int ret;
 	struct rte_flow_error error;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	ret = action_alloc(port_id, id, &pia);
 	if (ret)
 		return ret;
+
+	port = &ports[port_id];
+
+	if (conf->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
 		struct rte_flow_action_age *age =
 			(struct rte_flow_action_age *)(uintptr_t)(action->conf);
@@ -1531,6 +1546,7 @@ port_action_handle_create(portid_t port_id, uint32_t id,
 		return port_flow_complain(&error);
 	}
 	pia->type = action->type;
+	pia->transfer = conf->transfer;
 	printf("Indirect action #%u created\n", pia->id);
 	return 0;
 }
@@ -1557,9 +1573,18 @@ port_action_handle_destroy(portid_t port_id,
 		for (i = 0; i != n; ++i) {
 			struct rte_flow_error error;
 			struct port_indirect_action *pia = *tmp;
+			portid_t port_id_eff = port_id;
 
 			if (actions[i] != pia->id)
 				continue;
+
+			if (pia->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
 			/*
 			 * Poisoning to make sure PMDs update it in case
 			 * of error.
@@ -1567,7 +1592,7 @@ port_action_handle_destroy(portid_t port_id,
 			memset(&error, 0x33, sizeof(error));
 
 			if (pia->handle && rte_flow_action_handle_destroy(
-					port_id, pia->handle, &error)) {
+					port_id_eff, pia->handle, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -1602,8 +1627,15 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	struct rte_flow_error error;
 	struct rte_flow_action_handle *action_handle;
 	struct port_indirect_action *pia;
+	struct rte_port *port;
 	const void *update;
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
 	action_handle = port_action_handle_get_by_id(port_id, id);
 	if (!action_handle)
 		return -EINVAL;
@@ -1618,6 +1650,14 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 		update = action;
 		break;
 	}
+
+	if (pia->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (rte_flow_action_handle_update(port_id, action_handle, update,
 					  &error)) {
 		return port_flow_complain(&error);
@@ -1636,6 +1676,14 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 		struct rte_flow_query_age age;
 		struct rte_flow_action_conntrack ct;
 	} query;
+	portid_t port_id_eff = port_id;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
 
 	pia = action_get_by_id(port_id, id);
 	if (!pia)
@@ -1650,10 +1698,19 @@ port_action_handle_query(portid_t port_id, uint32_t id)
 			id, pia->type, port_id);
 		return -ENOTSUP;
 	}
+
+	if (pia->transfer)
+		port_id_eff = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+	    port_id_eff == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x55, sizeof(error));
 	memset(&query, 0, sizeof(query));
-	if (rte_flow_action_handle_query(port_id, pia->handle, &query, &error))
+	if (rte_flow_action_handle_query(port_id_eff, pia->handle, &query,
+					 &error))
 		return port_flow_complain(&error);
 	switch (pia->type) {
 	case RTE_FLOW_ACTION_TYPE_AGE:
@@ -1872,6 +1929,20 @@ port_flow_validate(portid_t port_id,
 {
 	struct rte_flow_error error;
 	struct port_flow_tunnel *pft = NULL;
+	struct rte_port *port;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
+	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
 
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
@@ -1925,7 +1996,19 @@ port_flow_create(portid_t port_id,
 	struct port_flow_tunnel *pft = NULL;
 	struct rte_flow_action_age *age = age_action_get(actions);
 
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	port = &ports[port_id];
+
+	if (attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	if (port->flow_list) {
 		if (port->flow_list->id == UINT32_MAX) {
 			fprintf(stderr,
@@ -1989,6 +2072,7 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 		uint32_t i;
 
 		for (i = 0; i != n; ++i) {
+			portid_t port_id_eff = port_id;
 			struct rte_flow_error error;
 			struct port_flow *pf = *tmp;
 
@@ -1999,7 +2083,15 @@ port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule)
 			 * of error.
 			 */
 			memset(&error, 0x33, sizeof(error));
-			if (rte_flow_destroy(port_id, pf->flow, &error)) {
+
+			if (pf->rule.attr->transfer)
+				port_id_eff = port->flow_transfer_proxy;
+
+			if (port_id_is_invalid(port_id_eff, ENABLED_WARN) ||
+			    port_id_eff == (portid_t)RTE_PORT_ALL)
+				return -EINVAL;
+
+			if (rte_flow_destroy(port_id_eff, pf->flow, &error)) {
 				ret = port_flow_complain(&error);
 				continue;
 			}
@@ -2133,6 +2225,14 @@ port_flow_query(portid_t port_id, uint32_t rule,
 		fprintf(stderr, "Flow rule #%u not found\n", rule);
 		return -ENOENT;
 	}
+
+	if (pf->rule.attr->transfer)
+		port_id = port->flow_transfer_proxy;
+
+	if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+	    port_id == (portid_t)RTE_PORT_ALL)
+		return -EINVAL;
+
 	ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTION_NAME_PTR,
 			    &name, sizeof(name),
 			    (void *)(uintptr_t)action->type, &error);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 97ae52e17e..a88e920bd0 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -533,6 +533,25 @@ int proc_id;
  */
 unsigned int num_procs = 1;
 
+static void
+flow_pick_transfer_proxy_mp(uint16_t port_id)
+{
+	struct rte_port *port = &ports[port_id];
+	int ret;
+
+	port->flow_transfer_proxy = port_id;
+
+	if (!is_proc_primary())
+		return;
+
+	ret = rte_flow_pick_transfer_proxy(port_id, &port->flow_transfer_proxy,
+					   NULL);
+	if (ret != 0) {
+		fprintf(stderr, "Error picking flow transfer proxy for port %u: %s - ignore\n",
+			port_id, rte_strerror(-ret));
+	}
+}
+
 static int
 eth_dev_configure_mp(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
@@ -1489,6 +1508,8 @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
 	int ret;
 	int i;
 
+	flow_pick_transfer_proxy_mp(pid);
+
 	port->dev_conf.txmode = tx_mode;
 	port->dev_conf.rxmode = rx_mode;
 
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 5863b2f43f..b3dfd350e5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -173,6 +173,8 @@ struct port_indirect_action {
 	enum rte_flow_action_type type; /**< Action type. */
 	struct rte_flow_action_handle *handle;	/**< Indirect action handle. */
 	enum age_action_context_type age_type; /**< Age action context type. */
+	/** If true, the action applies to "transfer" flows, and vice versa */
+	bool transfer;
 };
 
 struct port_flow_tunnel {
@@ -234,6 +236,8 @@ struct rte_port {
 	/**< dynamic flags. */
 	uint64_t		mbuf_dynf;
 	const struct rte_eth_rxtx_callback *tx_set_dynf_cb[RTE_MAX_QUEUES_PER_PORT+1];
+	/** Associated port which is supposed to handle "transfer" flows */
+	portid_t		flow_transfer_proxy;
 };
 
 /**
diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
index 14a9a251fb..d9edbbf9ee 100644
--- a/app/test-pmd/util.c
+++ b/app/test-pmd/util.c
@@ -98,13 +98,16 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 		int ret;
 		struct rte_flow_error error;
 		struct rte_flow_restore_info info = { 0, };
+		struct rte_port *port = &ports[port_id];
 
 		mb = pkts[i];
 		eth_hdr = rte_pktmbuf_read(mb, 0, sizeof(_eth_hdr), &_eth_hdr);
 		eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
 		packet_type = mb->packet_type;
 		is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
-		ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
+
+		ret = rte_flow_get_restore_info(port->flow_transfer_proxy,
+						mb, &info, &error);
 		if (!ret) {
 			MKDUMPSTR(print_buf, buf_size, cur_len,
 				  "restore info:");
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 0787baed8c..894a23caba 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -67,6 +67,9 @@ New Features
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
   TCP/UDP/SCTP header checksum field can be used as input set for RSS.
 
+* **Added an API to get a proxy port to manage "transfer" flows**
+  A new API, ``rte_flow_pick_transfer_proxy()``, was added.
+
 * **Updated Broadcom bnxt PMD.**
 
   * Added flow offload support for Thor.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 647bbf91ce..469a5f16b8 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1270,3 +1270,25 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				  NULL, rte_strerror(ENOTSUP));
 }
+
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error)
+{
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	struct rte_eth_dev *dev;
+
+	if (unlikely(ops == NULL))
+		return -rte_errno;
+
+	if (ops->pick_transfer_proxy == NULL) {
+		*proxy_port_id = port_id;
+		return 0;
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	return flow_err(port_id,
+			ops->pick_transfer_proxy(dev, proxy_port_id, error),
+			error);
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index f195aa7224..66cb3b475d 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -122,6 +122,9 @@ struct rte_flow_attr {
 	 *
 	 * In order to match traffic originating from specific source(s), the
 	 * application should use pattern items ETHDEV and ESWITCH_PORT.
+	 *
+	 * Managing "transfer" flows requires that the user communicate them
+	 * through a suitable port. @see rte_flow_pick_transfer_proxy().
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
@@ -4427,6 +4430,39 @@ rte_flow_tunnel_item_release(uint16_t port_id,
 			     struct rte_flow_item *items,
 			     uint32_t num_of_items,
 			     struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get a proxy port to manage "transfer" flows.
+ *
+ * Managing "transfer" flows requires that the user communicate them
+ * via a port which has the privilege to control the embedded switch.
+ * For some vendors, all ports in a given switching domain have
+ * this privilege. For other vendors, it's only one port.
+ *
+ * This API indicates such a privileged port (a "proxy")
+ * for a given port in the same switching domain.
+ *
+ * @note
+ *   If the PMD serving @p port_id doesn't have the corresponding method
+ *   implemented, the API will return @p port_id via @p proxy_port_id.
+ *
+ * @param port_id
+ *   Indicates the port to get a "proxy" for
+ * @param[out] proxy_port_id
+ *   Indicates the "proxy" port
+ * @param[out] error
+ *   If not NULL, allows the PMD to provide verbose report in case of error
+ *
+ * @return
+ *   0 on success, a negative error code otherwise
+ */
+__rte_experimental
+int
+rte_flow_pick_transfer_proxy(uint16_t port_id, uint16_t *proxy_port_id,
+			     struct rte_flow_error *error);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index 46f62c2ec2..ed52e59a0a 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -139,6 +139,11 @@ struct rte_flow_ops {
 		 struct rte_flow_item *pmd_items,
 		 uint32_t num_of_items,
 		 struct rte_flow_error *err);
+	/** See rte_flow_pick_transfer_proxy() */
+	int (*pick_transfer_proxy)
+		(struct rte_eth_dev *dev,
+		 uint16_t *proxy_port_id,
+		 struct rte_flow_error *error);
 };
 
 /**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 904bce6ea1..d4286dc8dd 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -247,6 +247,9 @@ EXPERIMENTAL {
 	rte_mtr_meter_policy_delete;
 	rte_mtr_meter_policy_update;
 	rte_mtr_meter_policy_validate;
+
+	# added in 21.11
+	rte_flow_pick_transfer_proxy;
 };
 
 INTERNAL {
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (11 preceding siblings ...)
  2021-10-01 13:47   ` [dpdk-dev] [PATCH v1 12/12] net/sfc: support ethdev flow item Andrew Rybchenko
@ 2021-10-10  0:04   ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to " Ivan Malov
                       ` (11 more replies)
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                     ` (4 subsequent siblings)
  17 siblings, 12 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam

As per RFC [1], action PORT_ID appears to be ambiguous. Its name suggests
that matching traffic be sent to the ethdev with the specified ID, that
is, to the application. However, in Open vSwitch, the action is used to
send traffic to a remote entity represented by the given port, that is,
in the opposite direction. Its interpretation across PMDs also varies.

RFC [2] attempted to define action PORT_ID semantics in vSwitch sense.
However, this solution would completely abandon the opposite meaning.

One more effort, RFC [3], was meant to declare that the use of direction
attributes in "transfer" flows assumed implicit filtering by the port ID
appearing as the first argument in rte_flow_create(). However, not all
PMDs require such filtering, so the RFC turned out rather disputable.


Since then, all of that has been given more thought:

1. One should not attempt to fix action PORT_ID. Instead, two new actions
   should be introduced. The first one should send traffic to the given
   ethdev. The second one should send it to the represented entity.

2. Similar to (1), two new items should be defined. The first one should
   match traffic going down from the given ethdev. The second one should
   match traffic going up from the entity represented by that ethdev.

3. The application always knows which packets come through which ethdevs.
   So, as per (2), the application can use the new item to match traffic
   arriving from precise entities represented by the relevant ethdev IDs.

4. New items suggested in (2) do not require the use of direction
   attributes. These items define precise directions on their own.

5. As a consequence of (3) and (4), the problem of implicit filtering
   by rte_flow_create() port ID argument and direction attributes is
   no longer a blocker. The new items allow to dispose of it.


The new items appear to be symmetrical to each other. So do the new
actions. This requires that their names reflect the symmetry. Also,
the names should respect the existing concept of port representors.
By the looks of it, terms "PORT_REPRESENTOR" and "REPRESENTED_PORT"
satisfy these requirements. However, currently, ethdevs associated
with network ports are not considered as their representors. Such
understanding is mentioned in the documentation, but it's not
expressed in the code (see enum rte_eth_representor_type).


The short of it, this patch series follows points (1-5) to rework
support for "transfer" flows accordingly. On the way, a string of
ambiguous pattern items (PF, VF, PHY_PORT) is deprecated.

The patch series also updates PMDs which support item and action PORT_ID
to add support for replacements (1-2). However, there're some exceptions:

 - Support for traffic source items in the case of net/mlx5 is really
   complicated. This series does not rework it. The PMD maintainer
   can do the job much better and test the new code accordingly;

 - Support for action REPRESENTED_PORT is not added to net/sfc.
   This will be done when support for VF representors has been
   upstreamed, just for the new code to apply cleanly.


[1] https://patches.dpdk.org/project/dpdk/patch/20210907125157.3843-1-ivan.malov@oktetlabs.ru/
[2] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/
[3] https://patches.dpdk.org/project/dpdk/patch/20210901151104.3923889-1-andrew.rybchenko@oktetlabs.ru/

Andrew Rybchenko (6):
  net/bnxt: support meta flow items to match on traffic source
  net/bnxt: support meta flow actions to overrule destinations
  net/enic: support meta flow actions to overrule destinations
  net/mlx5: support represented port flow action
  net/octeontx2: support port representor flow action
  net/sfc: support port representor flow item

Ivan Malov (6):
  ethdev: add port representor item to flow API
  ethdev: add represented port item to flow API
  ethdev: add port representor action to flow API
  ethdev: add represented port action to flow API
  ethdev: deprecate hard-to-use or ambiguous items and actions
  ethdev: deprecate direction attributes in transfer flows

 app/test-pmd/cmdline_flow.c                   | 104 +++++++
 doc/guides/nics/mlx5.rst                      |   4 +-
 doc/guides/nics/octeontx2.rst                 |   5 +-
 doc/guides/nics/sfc_efx.rst                   |   2 +
 doc/guides/prog_guide/rte_flow.rst            | 270 +++++++++++++++++-
 doc/guides/rel_notes/deprecation.rst          |  18 +-
 doc/guides/rel_notes/release_21_11.rst        |   8 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst   |  19 ++
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |  22 +-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 161 ++++++++---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  12 +-
 drivers/net/enic/enic_fm_flow.c               |  93 ++++--
 drivers/net/mlx5/mlx5_flow_dv.c               |  62 +++-
 drivers/net/octeontx2/otx2_flow_parse.c       |  16 +-
 drivers/net/sfc/sfc_mae.c                     |  72 +++++
 lib/ethdev/rte_flow.c                         |   4 +
 lib/ethdev/rte_flow.h                         | 162 ++++++++++-
 17 files changed, 914 insertions(+), 120 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to flow API
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10 11:15       ` Ori Kam
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 02/12] ethdev: add represented port " Ivan Malov
                       ` (10 subsequent siblings)
  11 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to match traffic
entering the embedded switch from the given ethdev.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 27 ++++++++++
 6 files changed, 120 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index bb22294dd3..a912a8d815 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -306,6 +306,8 @@ enum index {
 	ITEM_POL_PORT,
 	ITEM_POL_METER,
 	ITEM_POL_POLICY,
+	ITEM_PORT_REPRESENTOR,
+	ITEM_PORT_REPRESENTOR_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
+	ITEM_PORT_REPRESENTOR,
 	END_SET,
 	ZERO,
 };
@@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_port_representor[] = {
+	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
 	},
+	[ITEM_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "match traffic entering the embedded switch from the given ethdev",
+		.priv = PRIV_ITEM(PORT_REPRESENTOR,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_port_representor),
+		.call = parse_vc,
+	},
+	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+		mask = &rte_flow_item_ethdev_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2b42d5ec8c..2e0f590777 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .------------------------.
+    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
+    '------------------------'
+                ||
+                \/
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                ||
+                ||
+                ||
+                \/
+    .------------------------.
+    |  Embedded Flow Engine  |
+    '------------------------'
+                :
+                 :
+                :
+                 :
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                :
+                 :
+    .------------------------.
+    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same Application)
+    '------------------------'
+
+
+- Incompatibe with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_item_ethdev:
+
+.. table:: ``struct rte_flow_item_ethdev``
+
+   +----------+-------------+---------------------------+
+   | Field    | Subfield    | Value                     |
+   +==========+=============+===========================+
+   | ``spec`` | ``port_id`` | ethdev port ID            |
+   +----------+-------------+---------------------------+
+   | ``last`` | ``port_id`` | upper range value         |
+   +----------+-------------+---------------------------+
+   | ``mask`` | ``port_id`` | zeroed for wildcard match |
+   +----------+-------------+---------------------------+
+
+- Default ``mask`` provides exact match behaviour.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 89d4b33ef1..1261cb2bf3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,6 +188,8 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 8ead7a4a71..dcb9f47d98 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3795,6 +3795,10 @@ This section lists supported pattern items and their attributes, if any.
 
 - ``conntrack``: match conntrack state.
 
+- ``port_representor``: match traffic entering the embedded switch from the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..5e9317c6d1 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -100,6 +100,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
+	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 7b1ed7f110..3625fd2c12 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -574,6 +574,15 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following items:
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_item_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
+/** Default mask for items based on struct rte_flow_item_ethdev */
+#ifndef __cplusplus
+static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
+	.port_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 02/12] ethdev: add represented port item to flow API
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to " Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 03/12] ethdev: add port representor action " Ivan Malov
                       ` (9 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to match traffic entering the
embedded switch from the entity represented by the given ethdev.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 25 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 46 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 13 +++++-
 6 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a912a8d815..68698d805d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -308,6 +308,8 @@ enum index {
 	ITEM_POL_POLICY,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_REPRESENTED_PORT,
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
+	ITEM_REPRESENTED_PORT,
 	END_SET,
 	ZERO,
 };
@@ -1377,6 +1380,12 @@ static const enum index item_port_representor[] = {
 	ZERO,
 };
 
+static const enum index item_represented_port[] = {
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "match traffic entering the embedded switch from the entity represented by the given ethdev",
+		.priv = PRIV_ITEM(REPRESENTED_PORT,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_represented_port),
+		.call = parse_vc,
+	},
+	[ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8368,6 +8392,7 @@ flow_item_default_mask(const struct rte_flow_item *item)
 		mask = &rte_flow_item_pfcp_mask;
 		break;
 	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
 	default:
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2e0f590777..3dc209af4d 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,52 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+Item: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .------------------------.
+    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
+    '------------------------'
+                :
+                 :
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                :
+                 :
+                :
+                 :
+    .------------------------.
+    |  Embedded Flow Engine  |
+    '------------------------'
+                /\
+                ||
+                ||
+                ||
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                /\
+                ||
+    .------------------------.
+    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same Application)
+    '------------------------'
+
+
+- Incompatibe with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1261cb2bf3..39ff16780b 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index dcb9f47d98..44a399899f 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3799,6 +3799,11 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: match traffic entering the embedded switch from
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 5e9317c6d1..d4b654a2c6 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -101,6 +101,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 3625fd2c12..24d41aeb7b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -583,6 +583,16 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -1813,7 +1823,8 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following items:
- * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_item_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 03/12] ethdev: add port representor action to flow API
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to " Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 02/12] ethdev: add represented port " Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 04/12] ethdev: add represented port " Ivan Malov
                       ` (8 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to send matching traffic to
the given ethdev (to the application), at embedded switch level.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 56 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 18 +++++++
 6 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 68698d805d..ee6dac411a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -460,6 +460,8 @@ enum index {
 	ACTION_POL_G,
 	ACTION_POL_Y,
 	ACTION_POL_R,
+	ACTION_PORT_REPRESENTOR,
+	ACTION_PORT_REPRESENTOR_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1452,6 +1454,7 @@ static const enum index next_action[] = {
 	ACTION_MODIFY_FIELD,
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
+	ACTION_PORT_REPRESENTOR,
 	ZERO,
 };
 
@@ -1733,6 +1736,12 @@ static const enum index action_update_conntrack[] = {
 	ZERO,
 };
 
+static const enum index action_port_representor[] = {
+	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4820,6 +4829,23 @@ static const struct token token_list[] = {
 		.next = NEXT(action_update_conntrack),
 		.call = parse_vc_action_conntrack_update,
 	},
+	[ACTION_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "at embedded switch level, send matching traffic to the given ethdev",
+		.priv = PRIV_ACTION(PORT_REPRESENTOR,
+				    sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_port_representor),
+		.call = parse_vc,
+	},
+	[ACTION_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_port_representor,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3dc209af4d..e85880c2d4 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+See also `Action: PORT_REPRESENTOR`_.
+
 Item: ``REPRESENTED_PORT``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -3104,6 +3106,60 @@ which is set in the packet meta-data (i.e. struct ``rte_mbuf::sched::color``)
    | ``meter_color`` | Packet color |
    +-----------------+--------------+
 
+Action: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .------------------------.
+    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
+    '------------------------'
+                /\
+                ||
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                /\
+                ||
+                ||
+                ||
+    .------------------------.      .--------------------.
+    |  Embedded Flow Engine  |  <=  |  Matching Traffic  |
+    '------------------------'      '--------------------'
+                :
+                 :
+                :
+                 :
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                :
+                 :
+    .------------------------.
+    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same Application)
+    '------------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_action_ethdev:
+
+.. table:: ``struct rte_flow_action_ethdev``
+
+   +-------------+----------------+
+   | Field       | Value          |
+   +=============+================+
+   | ``port_id`` | ethdev port ID |
+   +-------------+----------------+
+
+See also `Item: PORT_REPRESENTOR`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 39ff16780b..bf46329e52 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 44a399899f..5f127fdbcc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4079,6 +4079,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``type {value}``: Set color type with specified value(green/yellow/red)
 
+- ``port_representor``: at embedded switch level, send matching traffic to
+  the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index d4b654a2c6..b074b1c77d 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -191,6 +191,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	 */
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
+	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 24d41aeb7b..cf4165bef3 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2447,6 +2447,13 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_meter_color.
 	 */
 	RTE_FLOW_ACTION_TYPE_METER_COLOR,
+
+	/**
+	 * At embedded switch level, sends matching traffic to the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -3206,6 +3213,17 @@ struct rte_flow_action_meter_color {
 	enum rte_color color; /**< Packet color. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following actions:
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_action_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
 /**
  * Field IDs for MODIFY_FIELD action.
  */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 04/12] ethdev: add represented port action to flow API
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (2 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 03/12] ethdev: add port representor action " Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
                       ` (7 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to send matching traffic to the
entity represented by the given ethdev, at embedded switch level.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 11 ++++-
 6 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ee6dac411a..c704bbaead 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -462,6 +462,8 @@ enum index {
 	ACTION_POL_R,
 	ACTION_PORT_REPRESENTOR,
 	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_REPRESENTED_PORT,
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1455,6 +1457,7 @@ static const enum index next_action[] = {
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
 	ACTION_PORT_REPRESENTOR,
+	ACTION_REPRESENTED_PORT,
 	ZERO,
 };
 
@@ -1742,6 +1745,12 @@ static const enum index action_port_representor[] = {
 	ZERO,
 };
 
+static const enum index action_represented_port[] = {
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4846,6 +4855,23 @@ static const struct token token_list[] = {
 					port_id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev",
+		.priv = PRIV_ACTION(REPRESENTED_PORT,
+				sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_represented_port),
+		.call = parse_vc,
+	},
+	[ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_represented_port,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index e85880c2d4..2056cfae38 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1532,6 +1532,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
+See also `Action: REPRESENTED_PORT`_.
+
 Actions
 ~~~~~~~
 
@@ -3160,6 +3162,53 @@ at the opposite end of the "wire" leading to the ethdev.
 
 See also `Item: PORT_REPRESENTOR`_.
 
+Action: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .------------------------.
+    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
+    '------------------------'
+                :
+                 :
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                :
+                 :
+                :
+                 :
+    .------------------------.      .--------------------.
+    |  Embedded Flow Engine  |  <=  |  Matching Traffic  |
+    '------------------------'      '--------------------'
+                ||
+                ||
+                ||
+                \/
+    .------------------------.
+    |  Embedded Switch Port  |  Logical Port
+    '------------------------'
+                ||
+                \/
+    .------------------------.
+    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same Application)
+    '------------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+This action is meant to use the same structure as `Action: PORT_REPRESENTOR`_.
+
+See also `Item: REPRESENTED_PORT`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index bf46329e52..f689a10e63 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 5f127fdbcc..d1c5cb7383 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4084,6 +4084,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: at embedded switch level, send matching traffic to
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index b074b1c77d..542e40e496 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -192,6 +192,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
 	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
+	MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index cf4165bef3..afd1f4c193 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2454,6 +2454,14 @@ enum rte_flow_action_type {
 	 * @see struct rte_flow_action_ethdev
 	 */
 	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * At embedded switch level, send matching traffic to
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -3218,7 +3226,8 @@ struct rte_flow_action_meter_color {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following actions:
- * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_action_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (3 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 04/12] ethdev: add represented port " Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
                       ` (6 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Ray Kinsella, Ferruh Yigit, Andrew Rybchenko

PF, VF and PHY_PORT require that applications have extra
knowledge of the underlying NIC and thus are hard to use.
Also, the corresponding items depend on the direction
attribute (ingress / egress), which complicates their
use in applications and interpretation in PMDs.

The concept of PORT_ID is ambiguous as it doesn't say whether
the port in question is an ethdev or the represented entity.

Items and actions PORT_REPRESENTOR, REPRESENTED_PORT
should be used instead.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 32 +++++++++++++++
 doc/guides/rel_notes/deprecation.rst   |  9 ++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 56 ++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2056cfae38..04ec1093be 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -504,6 +504,10 @@ Usage example, matching non-TCPv4 packets only:
 Item: ``PF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) the physical
 function of the current device.
 
@@ -531,6 +535,10 @@ the application and thus not associated with a DPDK port ID.
 Item: ``VF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given
 virtual function of the current device.
 
@@ -562,6 +570,10 @@ separate entities, should be addressed through their own DPDK port IDs.
 Item: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a physical
 port of the underlying device.
 
@@ -596,6 +608,10 @@ associated with a port_id should be retrieved by other means.
 Item: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given DPDK
 port ID.
 
@@ -1965,6 +1981,10 @@ only matching traffic goes through.
 Action: ``PF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to the physical function (PF) of the current
 device.
 
@@ -1985,6 +2005,10 @@ See `Item: PF`_.
 Action: ``VF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given virtual function of the current device.
 
 Packets matched by a VF pattern item can be redirected to their original VF
@@ -2009,6 +2033,10 @@ See `Item: VF`_.
 Action: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given physical port index of the underlying
 device.
 
@@ -2028,6 +2056,10 @@ See `Item: PHY_PORT`_.
 
 Action: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^^^
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given DPDK port ID.
 
 See `Item: PORT_ID`_.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b86147dda1..c91d570099 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -122,12 +122,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Definition of the flow API action ``RTE_FLOW_ACTION_TYPE_PORT_ID``
-  is ambiguous and needs clarification.
-  Structure ``rte_flow_action_port_id`` will be extended to specify
-  traffic direction to the represented entity or ethdev port itself
-  in DPDK 21.11.
-
 * ethdev: Flow API documentation is unclear if ethdev port used to create
   a flow rule adds any implicit match criteria in the case of transfer rules.
   The semantics will be clarified in DPDK 21.11 and it will require fixes in
@@ -256,3 +250,6 @@ Deprecation Notices
 * cmdline: ``cmdline`` structure will be made opaque to hide platform-specific
   content. On Linux and FreeBSD, supported prior to DPDK 20.11,
   original structure will be kept until DPDK 21.11.
+
+* ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
+  deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index f689a10e63..63f946ad88 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -190,6 +190,9 @@ API Changes
 
 * ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
+* ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
+  Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index afd1f4c193..afd50d6d51 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -160,6 +160,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_ANY,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress)
@@ -170,6 +174,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -180,6 +188,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -190,6 +202,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -640,6 +656,10 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_VF
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -669,6 +689,10 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PHY_PORT
  *
  * Matches traffic originating from (ingress) or going to (egress) a
@@ -700,6 +724,10 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PORT_ID
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -1990,6 +2018,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_RSS,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to the physical function (PF) of the
 	 * current device.
 	 *
@@ -1998,6 +2030,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given virtual function of the
 	 * current device.
 	 *
@@ -2006,6 +2042,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs packets to a given physical port index of the underlying
 	 * device.
 	 *
@@ -2014,6 +2054,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given DPDK port ID.
 	 *
 	 * See struct rte_flow_action_port_id.
@@ -2654,6 +2698,10 @@ struct rte_flow_action_rss {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_VF
  *
  * Directs matching traffic to a given virtual function of the current
@@ -2672,6 +2720,10 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PHY_PORT
  *
  * Directs packets to a given physical port index of the underlying
@@ -2686,6 +2738,10 @@ struct rte_flow_action_phy_port {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PORT_ID
  *
  * Directs matching traffic to a given DPDK port ID.
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (4 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
                       ` (5 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Ray Kinsella, Ferruh Yigit, Andrew Rybchenko

Attributes "ingress" and "egress" can only apply unambiguosly
to non-"transfer" flows. In "transfer" flows, the standpoint
is effectively shifted to the embedded switch. There can be
many different endpoints connected to the switch, so the
use of "ingress" / "egress" does not shed light on which
endpoints precisely can be considered as traffic sources.

Add relevant deprecation notices and suggest the use of precise
traffic source items (PORT_REPRESENTOR and REPRESENTED_PORT).

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 28 ++++++++----------
 doc/guides/rel_notes/deprecation.rst   |  9 +++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 41 ++++++++++++++++++++------
 4 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 04ec1093be..f2e04fc7d8 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -9,8 +9,8 @@ Overview
 --------
 
 This API provides a generic means to configure hardware to match specific
-ingress or egress traffic, alter its fate and query related counters
-according to any number of user-defined rules.
+traffic, alter its fate and query related counters according to any
+number of user-defined rules.
 
 It is named *rte_flow* after the prefix used for all its symbols, and is
 defined in ``rte_flow.h``.
@@ -146,13 +146,10 @@ Note that support for more than a single priority level is not guaranteed.
 Attribute: Traffic direction
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Flow rule patterns apply to inbound and/or outbound traffic.
-
-In the context of this API, **ingress** and **egress** respectively stand
-for **inbound** and **outbound** based on the standpoint of the application
-creating a flow rule.
-
-There are no exceptions to this definition.
+Unless `Attribute: Transfer`_ is specified, flow rule patterns apply
+to inbound and / or outbound traffic. With this respect, ``ingress``
+and ``egress`` respectively stand for **inbound** and **outbound**
+based on the standpoint of the application creating a flow rule.
 
 Several pattern items and actions are valid and can be used in both
 directions. At least one direction must be specified.
@@ -171,12 +168,13 @@ When supported, this effectively enables an application to reroute traffic
 not necessarily intended for it (e.g. coming from or addressed to different
 physical ports, VFs or applications) at the device level.
 
-It complements the behavior of some pattern items such as `Item: PHY_PORT`_
-and is meaningless without them.
-
-When transferring flow rules, **ingress** and **egress** attributes
-(`Attribute: Traffic direction`_) keep their original meaning, as if
-processing traffic emitted or received by the application.
+In "transfer" flows, the use of `Attribute: Traffic direction`_ in the sense of
+implicitly matching packets going to or going from the ethdev used to create
+flow rules is **deprecated**. `Attribute: Transfer`_ shifts the viewpoint to
+the embedded switch. In it, `Attribute: Traffic direction`_ is ambiguous as
+the switch serves many different endpoints. The application should match
+traffic originating from precise locations. To do so, it should
+use `Item: PORT_REPRESENTOR`_ and `Item: REPRESENTED_PORT`_.
 
 Pattern item
 ~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index c91d570099..02a5b6eeba 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -122,11 +122,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Flow API documentation is unclear if ethdev port used to create
-  a flow rule adds any implicit match criteria in the case of transfer rules.
-  The semantics will be clarified in DPDK 21.11 and it will require fixes in
-  drivers and applications which interpret it in a different way.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header.
   Some matching pattern structures implements this by duplicating protocol header
@@ -253,3 +248,7 @@ Deprecation Notices
 
 * ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
   deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
+
+* ethdev: The use of attributes ``ingress`` / ``egress`` in "transfer" flows
+  is deprecated as ambiguous with respect to the embedded switch. The use of
+  these attributes will become invalid starting from DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 63f946ad88..d4dadbfcf4 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -193,6 +193,9 @@ API Changes
 * ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
   Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
 
+* ethdev: Deprecated the use of attributes ``ingress`` / ``egress`` combined
+  with ``transfer``. See items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT``.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index afd50d6d51..9e0adf7302 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -67,7 +67,10 @@ extern "C" {
  * Note that support for more than a single group and priority level is not
  * guaranteed.
  *
- * Flow rules can apply to inbound and/or outbound traffic (ingress/egress).
+ * At vNIC / ethdev level, flow rules can apply to inbound and / or outbound
+ * traffic (ingress / egress), with respect to the vNIC / ethdev in question.
+ * At embedded switch level, flow rules apply to all traffic seen by it
+ * unless fitting meta items are used to set concrete traffic source(s).
  *
  * Several pattern items and actions are valid and can be used in both
  * directions. Those valid for only one direction are described as such.
@@ -80,8 +83,32 @@ extern "C" {
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
 	uint32_t priority; /**< Rule priority level within group. */
-	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
-	uint32_t egress:1; /**< Rule applies to egress traffic. */
+	/**
+	 * The rule in question applies to ingress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic going from within the embedded switch toward the
+	 * ethdev the flow rule being created through. This behaviour
+	 * is deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t ingress:1;
+	/**
+	 * The rule in question applies to egress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic sent by the application by virtue of the ethdev
+	 * the flow rule being created through. This behaviour is now
+	 * deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t egress:1;
 	/**
 	 * Instead of simply matching the properties of traffic as it would
 	 * appear on a given DPDK port ID, enabling this attribute transfers
@@ -93,12 +120,8 @@ struct rte_flow_attr {
 	 * from or addressed to different physical ports, VFs or
 	 * applications) at the device level.
 	 *
-	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
-	 *
-	 * When transferring flow rules, ingress and egress attributes keep
-	 * their original meaning, as if processing traffic emitted or
-	 * received by the application.
+	 * The application should match traffic originating from precise
+	 * locations. See items PORT_REPRESENTOR and REPRESENTED_PORT.
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 07/12] net/bnxt: support meta flow items to match on traffic source
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (5 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 08/12] net/bnxt: support meta flow actions to overrule destinations Ivan Malov
                       ` (4 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for items PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for item PORT_ID.

The use of item PORT_ID depends on the specified direction attribute.
Items PORT_REPRESENTOR and REPRESENTED_PORT, in turn, define traffic
direction themselves. The former matches traffic from the driver's
vNIC. The latter matches packets from either a v-port (network) or
a VF's vNIC (if the driver's port is a VF representor).

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 10 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 77 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 3 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index 9b165c12b5..d28dd2e587 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -266,7 +266,7 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	},
 	[RTE_FLOW_ITEM_TYPE_PORT_ID] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
-	.proto_hdr_func          = ulp_rte_port_id_hdr_handler
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	},
 	[RTE_FLOW_ITEM_TYPE_RAW] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
@@ -427,6 +427,14 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	[RTE_FLOW_ITEM_TYPE_HIGIG2] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
 	.proto_hdr_func          = NULL
+	},
+	[RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
+	},
+	[RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	}
 };
 
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 3a9c9bba27..e1ea8932b0 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -400,7 +400,8 @@ bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
 static int32_t
 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 			uint32_t ifindex,
-			uint16_t mask)
+			uint16_t mask,
+			enum bnxt_ulp_direction_type item_dir)
 {
 	uint16_t svif;
 	enum bnxt_ulp_direction_type dir;
@@ -429,11 +430,14 @@ ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 	bnxt_ulp_rte_parser_direction_compute(params);
 
 	/* Get the computed direction */
-	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_INGRESS) {
+	dir = (item_dir != BNXT_ULP_DIR_INVALID) ? item_dir :
+		ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
+	if (dir == BNXT_ULP_DIR_INGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
 	} else {
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
+		    item_dir != BNXT_ULP_DIR_EGRESS)
 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
 		else
 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
@@ -474,7 +478,8 @@ ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
 	}
 
 	/* Update the SVIF details */
-	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				     BNXT_ULP_DIR_INVALID);
 	return rc;
 }
 
@@ -522,7 +527,8 @@ ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
 	}
 
 	/* Update the SVIF details */
-	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	return ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow item VF Header. */
@@ -555,39 +561,72 @@ ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow item port id  Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params)
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params)
 {
-	const struct rte_flow_item_port_id *port_spec = item->spec;
-	const struct rte_flow_item_port_id *port_mask = item->mask;
+	enum bnxt_ulp_direction_type item_dir;
+	uint16_t ethdev_id;
 	uint16_t mask = 0;
 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
 	uint32_t ifindex;
 
-	if (!port_spec) {
-		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
+	if (!item->spec) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port spec is not valid\n");
 		return rc;
 	}
-	if (!port_mask) {
-		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
+	if (!item->mask) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port mask is not valid\n");
+		return rc;
+	}
+
+	switch (item->type) {
+	case RTE_FLOW_ITEM_TYPE_PORT_ID: {
+		const struct rte_flow_item_port_id *port_spec = item->spec;
+		const struct rte_flow_item_port_id *port_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INVALID;
+		ethdev_id = port_spec->id;
+		mask = port_mask->id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_EGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "ParseErr:Unexpected item\n");
 		return rc;
 	}
-	mask = port_mask->id;
 
 	/* perform the conversion from dpdk port to bnxt ifindex */
 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
-					      port_spec->id,
+					      ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask, item_dir);
 }
 
 /* Function to handle the parsing of RTE Flow item phy port Header. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e14f86278a..0acb93946b 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -90,10 +90,10 @@ int32_t
 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow item port id Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow item port Header. */
 int32_t
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 08/12] net/bnxt: support meta flow actions to overrule destinations
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (6 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
@ 2021-10-10  0:04     ` Ivan Malov
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 09/12] net/enic: " Ivan Malov
                       ` (3 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:04 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for action PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 12 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 84 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index d28dd2e587..e9337ecd2c 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -67,7 +67,7 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	},
 	[RTE_FLOW_ACTION_TYPE_PORT_ID] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
-	.proto_act_func          = ulp_rte_port_id_act_handler
+	.proto_act_func          = ulp_rte_port_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_METER] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
@@ -212,7 +212,15 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	[RTE_FLOW_ACTION_TYPE_SAMPLE] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
 	.proto_act_func          = ulp_rte_sample_act_handler
-	}
+	},
+	[RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
+	[RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
 };
 
 struct bnxt_ulp_rte_act_info ulp_vendor_act_info[] = {
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index e1ea8932b0..f0e218d8ec 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -496,10 +496,11 @@ ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
 		return BNXT_TF_RC_SUCCESS;
 	}
 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
+	action_item.type = RTE_FLOW_ACTION_TYPE_PORT_ID;
 	action_item.conf = &port_id;
 
 	/* Update the action port based on incoming port */
-	ulp_rte_port_id_act_handler(&action_item, params);
+	ulp_rte_port_act_handler(&action_item, params);
 
 	/* Reset the action port set bit */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
@@ -2168,7 +2169,8 @@ ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
 /* Function to handle the parsing of action ports. */
 static int32_t
 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
-			    uint32_t ifindex)
+			    uint32_t ifindex,
+			    enum bnxt_ulp_direction_type act_dir)
 {
 	enum bnxt_ulp_direction_type dir;
 	uint16_t pid_s;
@@ -2178,8 +2180,13 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 	uint32_t vnic_type;
 
 	/* Get the direction */
-	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_EGRESS) {
+	/* If action implicitly specifies direction, use the specification. */
+	dir = (act_dir == BNXT_ULP_DIR_INVALID) ?
+		ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION) :
+		act_dir;
+	port_type = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
+	if (dir == BNXT_ULP_DIR_EGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		/* For egress direction, fill vport */
 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
 			return BNXT_TF_RC_ERROR;
@@ -2190,9 +2197,17 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
 	} else {
 		/* For ingress direction, fill vnic */
-		port_type = ULP_COMP_FLD_IDX_RD(param,
-						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		/*
+		 * Action		Destination
+		 * ------------------------------------
+		 * PORT_REPRESENTOR	Driver Function
+		 * ------------------------------------
+		 * REPRESENTED_PORT	VF
+		 * ------------------------------------
+		 * PORT_ID		VF
+		 */
+		if (act_dir != BNXT_ULP_DIR_INGRESS &&
+		    port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
 		else
 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
@@ -2239,7 +2254,8 @@ ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
 	}
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow action VF. */
@@ -2290,31 +2306,59 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/* Parse actions PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *param)
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *param)
 {
-	const struct rte_flow_action_port_id *port_id = act_item->conf;
+	uint32_t ethdev_id;
 	uint32_t ifindex;
 	enum bnxt_ulp_intf_type intf_type;
+	enum bnxt_ulp_direction_type act_dir;
 
-	if (!port_id) {
+	if (!act_item->conf) {
 		BNXT_TF_DBG(ERR,
 			    "ParseErr: Invalid Argument\n");
 		return BNXT_TF_RC_PARSE_ERR;
 	}
-	if (port_id->original) {
-		BNXT_TF_DBG(ERR,
-			    "ParseErr:Portid Original not supported\n");
-		return BNXT_TF_RC_PARSE_ERR;
+	switch (act_item->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *port_id = act_item->conf;
+
+		if (port_id->original) {
+			BNXT_TF_DBG(ERR,
+				    "ParseErr:Portid Original not supported\n");
+			return BNXT_TF_RC_PARSE_ERR;
+		}
+		ethdev_id = port_id->id;
+		act_dir = BNXT_ULP_DIR_INVALID;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->port_id;
+		act_dir = BNXT_ULP_DIR_INGRESS;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->port_id;
+		act_dir = BNXT_ULP_DIR_EGRESS;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "Unknown port action\n");
+		return BNXT_TF_RC_ERROR;
 	}
 
 	/* Get the port db ifindex */
-	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, port_id->id,
+	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "Invalid port id\n");
 		return BNXT_TF_RC_ERROR;
@@ -2329,7 +2373,7 @@ ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
 
 	/* Set the action port */
 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(param, ifindex);
+	return ulp_rte_parser_act_port_set(param, ifindex, act_dir);
 }
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index 0acb93946b..e4225d00f8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -204,10 +204,10 @@ int32_t
 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/* Parse actions PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
 int32_t
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 09/12] net/enic: support meta flow actions to overrule destinations
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (7 preceding siblings ...)
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 08/12] net/bnxt: support meta flow actions to overrule destinations Ivan Malov
@ 2021-10-10  0:05     ` Ivan Malov
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 10/12] net/mlx5: support represented port flow action Ivan Malov
                       ` (2 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:05 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, John Daley, Hyong Youb Kim

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for action PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/enic/enic_fm_flow.c | 93 ++++++++++++++++++++++++++-------
 1 file changed, 75 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index cd364ee16b..4092ff1f61 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1242,6 +1242,35 @@ vf_egress_port_id_action(struct enic_flowman *fm,
 	return 0;
 }
 
+static int
+enic_fm_check_transfer_dst(struct enic *enic, uint16_t dst_port_id,
+			   struct rte_eth_dev **dst_dev,
+			   struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev;
+
+	ENICPMD_LOG(DEBUG, "port id %u", dst_port_id);
+	if (!rte_eth_dev_is_valid_port(dst_port_id)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "invalid port_id");
+	}
+	dev = &rte_eth_devices[dst_port_id];
+	if (!dev_is_enic(dev)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "port_id is not enic");
+	}
+	if (enic->switch_domain_id != pmd_priv(dev)->switch_domain_id) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "destination and source ports are not in the same switch domain");
+	}
+
+	*dst_dev = dev;
+	return 0;
+}
+
 /* Translate flow actions to flowman TCAM entry actions */
 static int
 enic_fm_copy_action(struct enic_flowman *fm,
@@ -1446,24 +1475,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
 				vnic_h = enic->fm_vnic_handle; /* This port */
 				break;
 			}
-			ENICPMD_LOG(DEBUG, "port id %u", port->id);
-			if (!rte_eth_dev_is_valid_port(port->id)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "invalid port_id");
-			}
-			dev = &rte_eth_devices[port->id];
-			if (!dev_is_enic(dev)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "port_id is not enic");
-			}
-			if (enic->switch_domain_id !=
-			    pmd_priv(dev)->switch_domain_id) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "destination and source ports are not in the same switch domain");
-			}
+			ret = enic_fm_check_transfer_dst(enic, port->id, &dev,
+							 error);
+			if (ret)
+				return ret;
 			vnic_h = pmd_priv(dev)->fm_vnic_handle;
 			overlap |= PORT_ID;
 			/*
@@ -1560,6 +1575,48 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			ovlan |= rte_be_to_cpu_16(vid->vlan_vid);
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->port_id,
+							 &dev, error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/*
+			 * Action PORT_REPRESENTOR implies ingress destination.
+			 * Noting to do. We add an implicit stree at the
+			 * end if needed.
+			 */
+			ingress = 1;
+			break;
+		}
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			if (overlap & PORT_ID) {
+				ENICPMD_LOG(DEBUG, "cannot have multiple egress PORT_ID actions");
+				goto unsupported;
+			}
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->port_id,
+							 &dev, error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/* Action REPRESENTED_PORT: always egress destination */
+			ingress = 0;
+			ret = vf_egress_port_id_action(fm, dev, vnic_h, &fm_op,
+				error);
+			if (ret)
+				return ret;
+			break;
+		}
 		default:
 			goto unsupported;
 		}
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 10/12] net/mlx5: support represented port flow action
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (8 preceding siblings ...)
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 09/12] net/enic: " Ivan Malov
@ 2021-10-10  0:05     ` Ivan Malov
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 11/12] net/octeontx2: support port representor " Ivan Malov
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 12/12] net/sfc: support port representor flow item Ivan Malov
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:05 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Matan Azrad,
	Viacheslav Ovsiienko

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Semantics of the existing support for action PORT_ID suggests
that support for equal action REPRESENTED_PORT be implemented.

Helper functions keep port_id suffix since action
MLX5_FLOW_ACTION_PORT_ID is still used internally.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/mlx5.rst        |  4 +--
 drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++-------
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index bae73f42d8..b76e979f47 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -431,8 +431,8 @@ Limitations
      - yellow: NULL or END.
      - RED: DROP / END.
   - The only supported meter policy actions:
-     - green: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
-     - yellow: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
+     - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
+     - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
      - RED: must be DROP.
   - Policy actions of RSS for green and yellow should have the same configuration except queues.
   - meter profile packet mode is supported.
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index c6370cd1d6..835cc5018c 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -5048,14 +5048,14 @@ flow_dv_validate_action_jump(struct rte_eth_dev *dev,
 }
 
 /*
- * Validate the port_id action.
+ * Validate action PORT_ID / REPRESENTED_PORT.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action_flags
  *   Bit-fields that holds the actions detected until now.
  * @param[in] action
- *   Port_id RTE action structure.
+ *   PORT_ID / REPRESENTED_PORT action structure.
  * @param[in] attr
  *   Attributes of flow that includes this action.
  * @param[out] error
@@ -5072,6 +5072,7 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 				struct rte_flow_error *error)
 {
 	const struct rte_flow_action_port_id *port_id;
+	const struct rte_flow_action_ethdev *ethdev;
 	struct mlx5_priv *act_priv;
 	struct mlx5_priv *dev_priv;
 	uint16_t port;
@@ -5080,13 +5081,13 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
-					  "port id action is valid in transfer"
+					  "port action is valid in transfer"
 					  " mode only");
 	if (!action || !action->conf)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  NULL,
-					  "port id action parameters must be"
+					  "port action parameters must be"
 					  " specified");
 	if (action_flags & (MLX5_FLOW_FATE_ACTIONS |
 			    MLX5_FLOW_FATE_ESWITCH_ACTIONS))
@@ -5100,13 +5101,26 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
 					  "failed to obtain E-Switch info");
-	port_id = action->conf;
-	port = port_id->original ? dev->data->port_id : port_id->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		port_id = action->conf;
+		port = port_id->original ? dev->data->port_id : port_id->id;
+		break;
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
+		ethdev = action->conf;
+		port = ethdev->port_id;
+		break;
+	default:
+		return rte_flow_error_set
+				(error, EINVAL,
+				 RTE_FLOW_ERROR_TYPE_ACTION, action,
+				 "unknown E-Switch action");
+	}
 	act_priv = mlx5_port_to_eswitch_info(port, false);
 	if (!act_priv)
 		return rte_flow_error_set
 				(error, rte_errno,
-				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, port_id,
+				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, action->conf,
 				 "failed to obtain E-Switch port id for port");
 	if (act_priv->domain_id != dev_priv->domain_id)
 		return rte_flow_error_set
@@ -5669,6 +5683,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 			++actions_n;
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      sub_action_flags,
 							      act,
@@ -7296,6 +7311,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      action_flags,
 							      actions,
@@ -10770,12 +10786,12 @@ flow_dv_tag_release(struct rte_eth_dev *dev,
 }
 
 /**
- * Translate port ID action to vport.
+ * Translate action PORT_ID / REPRESENTED_PORT to vport.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to the port ID action.
+ *   Pointer to action PORT_ID / REPRESENTED_PORT.
  * @param[out] dst_port_id
  *   The target port ID.
  * @param[out] error
@@ -10792,10 +10808,28 @@ flow_dv_translate_action_port_id(struct rte_eth_dev *dev,
 {
 	uint32_t port;
 	struct mlx5_priv *priv;
-	const struct rte_flow_action_port_id *conf =
-			(const struct rte_flow_action_port_id *)action->conf;
 
-	port = conf->original ? dev->data->port_id : conf->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *conf;
+
+		conf = (const struct rte_flow_action_port_id *)action->conf;
+		port = conf->original ? dev->data->port_id : conf->id;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_action_ethdev *ethdev;
+
+		ethdev = (const struct rte_flow_action_ethdev *)action->conf;
+		port = ethdev->port_id;
+		break;
+	}
+	default:
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "unknown E-Switch action");
+	}
+
 	priv = mlx5_port_to_eswitch_info(port, false);
 	if (!priv)
 		return rte_flow_error_set(error, -rte_errno,
@@ -11634,6 +11668,7 @@ flow_dv_translate_action_sample(struct rte_eth_dev *dev,
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 		{
 			struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -12714,6 +12749,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			if (flow_dv_translate_action_port_id(dev, action,
 							     &port_id, error))
 				return -rte_errno;
@@ -15475,6 +15511,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 				break;
 			}
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			{
 				struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -17683,6 +17720,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 					  NULL, "too many actions");
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 				if (!priv->config.dv_esw_en)
 					return -rte_mtr_error_set(error,
 					ENOTSUP,
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 11/12] net/octeontx2: support port representor flow action
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (9 preceding siblings ...)
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 10/12] net/mlx5: support represented port flow action Ivan Malov
@ 2021-10-10  0:05     ` Ivan Malov
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 12/12] net/sfc: support port representor flow item Ivan Malov
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:05 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Jerin Jacob,
	Nithin Dabilpuram, Kiran Kumar K

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Action PORT_ID implementation assumes ingress only. Its semantics
suggests that support for equal action PORT_REPRESENTOR be added.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/octeontx2.rst           |  5 ++++-
 drivers/net/octeontx2/otx2_flow_parse.c | 16 ++++++++++++----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/octeontx2.rst b/doc/guides/nics/octeontx2.rst
index e35c8116f7..eae32f0afe 100644
--- a/doc/guides/nics/octeontx2.rst
+++ b/doc/guides/nics/octeontx2.rst
@@ -403,10 +403,13 @@ Actions:
    +----+-----------------------------------------+
    | 12 | RTE_FLOW_ACTION_TYPE_PORT_ID            |
    +----+-----------------------------------------+
+   | 13 | RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR   |
+   +----+-----------------------------------------+
 
 .. note::
 
-   ``RTE_FLOW_ACTION_TYPE_PORT_ID`` is only supported between PF and its VFs.
+   ``RTE_FLOW_ACTION_TYPE_PORT_ID``, ``RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR``
+   are only supported between PF and its VFs.
 
 .. _table_octeontx2_supported_egress_action_types:
 
diff --git a/drivers/net/octeontx2/otx2_flow_parse.c b/drivers/net/octeontx2/otx2_flow_parse.c
index 63a33142a5..890c6d0719 100644
--- a/drivers/net/octeontx2/otx2_flow_parse.c
+++ b/drivers/net/octeontx2/otx2_flow_parse.c
@@ -900,7 +900,6 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 {
 	struct otx2_eth_dev *hw = dev->data->dev_private;
 	struct otx2_npc_flow_info *npc = &hw->npc_flow;
-	const struct rte_flow_action_port_id *port_act;
 	const struct rte_flow_action_count *act_count;
 	const struct rte_flow_action_mark *act_mark;
 	const struct rte_flow_action_queue *act_q;
@@ -987,9 +986,18 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 			break;
 
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
-			port_act = (const struct rte_flow_action_port_id *)
-				actions->conf;
-			port_id = port_act->id;
+		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+			if (actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
+				const struct rte_flow_action_port_id *port_act;
+
+				port_act = actions->conf;
+				port_id = port_act->id;
+			} else {
+				const struct rte_flow_action_ethdev *ethdev_act;
+
+				ethdev_act = actions->conf;
+				port_id = ethdev_act->port_id;
+			}
 			if (rte_eth_dev_get_name_by_port(port_id, if_name)) {
 				errmsg = "Name not found for output port id";
 				errcode = EINVAL;
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 12/12] net/sfc: support port representor flow item
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (10 preceding siblings ...)
  2021-10-10  0:05     ` [dpdk-dev] [PATCH v2 11/12] net/octeontx2: support port representor " Ivan Malov
@ 2021-10-10  0:05     ` Ivan Malov
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10  0:05 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for item PORT_REPRESENTOR which should
be used instead of ambiguous item PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/sfc_efx.rst |  2 ++
 drivers/net/sfc/sfc_mae.c   | 72 +++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 163bc2533f..9a9710325f 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -190,6 +190,8 @@ Supported actions (***non-transfer*** rules):
 
 Supported pattern items (***transfer*** rules):
 
+- PORT_REPRESENTOR (cannot repeat; conflicts with other traffic source items)
+
 - PORT_ID (cannot repeat; conflicts with other traffic source items)
 
 - PHY_PORT (cannot repeat; conflicts with other traffic source items)
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 4b520bc619..392f6ec098 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -1100,6 +1100,66 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
 	return 0;
 }
 
+static int
+sfc_mae_rule_parse_item_port_representor(const struct rte_flow_item *item,
+					 struct sfc_flow_parse_ctx *ctx,
+					 struct rte_flow_error *error)
+{
+	struct sfc_mae_parse_ctx *ctx_mae = ctx->mae;
+	const struct rte_flow_item_ethdev supp_mask = {
+		.port_id = 0xffff,
+	};
+	const void *def_mask = &rte_flow_item_ethdev_mask;
+	const struct rte_flow_item_ethdev *spec = NULL;
+	const struct rte_flow_item_ethdev *mask = NULL;
+	efx_mport_sel_t mport_sel;
+	int rc;
+
+	if (ctx_mae->match_mport_set) {
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't handle multiple traffic source items");
+	}
+
+	rc = sfc_flow_parse_init(item,
+				 (const void **)&spec, (const void **)&mask,
+				 (const void *)&supp_mask, def_mask,
+				 sizeof(struct rte_flow_item_ethdev), error);
+	if (rc != 0)
+		return rc;
+
+	if (mask->port_id != supp_mask.port_id) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Bad mask in the PORT_REPRESENTOR pattern item");
+	}
+
+	/* If "spec" is not set, could be any port ID */
+	if (spec == NULL)
+		return 0;
+
+	rc = sfc_mae_switch_port_by_ethdev(
+			ctx_mae->sa->mae.switch_domain_id,
+			spec->port_id, &mport_sel);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't find RTE ethdev by the port ID");
+	}
+
+	rc = efx_mae_match_spec_mport_set(ctx_mae->match_spec,
+					  &mport_sel, NULL);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Failed to set MPORT for the port ID");
+	}
+
+	ctx_mae->match_mport_set = B_TRUE;
+
+	return 0;
+}
+
 static int
 sfc_mae_rule_parse_item_phy_port(const struct rte_flow_item *item,
 				 struct sfc_flow_parse_ctx *ctx,
@@ -1995,6 +2055,18 @@ static const struct sfc_flow_item sfc_flow_items[] = {
 		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
 		.parse = sfc_mae_rule_parse_item_port_id,
 	},
+	{
+		.type = RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+		.name = "PORT_REPRESENTOR",
+		/*
+		 * In terms of RTE flow, this item is a META one,
+		 * and its position in the pattern is don't care.
+		 */
+		.prev_layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
+		.parse = sfc_mae_rule_parse_item_port_representor,
+	},
 	{
 		.type = RTE_FLOW_ITEM_TYPE_PHY_PORT,
 		.name = "PHY_PORT",
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to flow API
  2021-10-10  0:04     ` [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to " Ivan Malov
@ 2021-10-10 11:15       ` Ori Kam
  2021-10-10 13:30         ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-10 11:15 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan,

From the new patches I saw you choose port_representor and represented_port
Didn't we agree to go with ETHDEV_PORT and SHADOW_PORT?
The only thing that worries me is that the naming are very easy to get wrong.
port_representor and represented_port.

Also there is an issue with wording if we assume like in previous thread that
DPDK can have both the representor port and also the represented_port.
While if we look at for example ethdev_port and shadow port are better defined
as ethdev_port -> the port that is closest to the DPDK ethdev while shadow port
is defined as the other side of the ethdev port.

What do you think?

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 3:05 AM
> Subject: [PATCH v2 01/12] ethdev: add port representor item to flow API
> ?
> For use in "transfer" flows. Supposed to match traffic entering the embedded
> switch from the given ethdev.


I would also add a comment that says the since we are in transfer it means
that all rules are located in the E-Switch which means that the matching is done
on the source port of the traffic. 

I think this will also help understand the view point that we are looking from the point
of the switch, and to add the drawing.

> 
> Must not be combined with direction attributes.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---
>  app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
>  doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
>  doc/guides/rel_notes/release_21_11.rst      |  2 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
>  lib/ethdev/rte_flow.c                       |  1 +
>  lib/ethdev/rte_flow.h                       | 27 ++++++++++
>  6 files changed, 120 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
> bb22294dd3..a912a8d815 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -306,6 +306,8 @@ enum index {
>  	ITEM_POL_PORT,
>  	ITEM_POL_METER,
>  	ITEM_POL_POLICY,
> +	ITEM_PORT_REPRESENTOR,
> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
>  	ITEM_GENEVE_OPT,
>  	ITEM_INTEGRITY,
>  	ITEM_CONNTRACK,
> +	ITEM_PORT_REPRESENTOR,
>  	END_SET,
>  	ZERO,
>  };
> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_port_representor[] = {
> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
>  			     item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack,
> flags)),
>  	},
> +	[ITEM_PORT_REPRESENTOR] = {
> +		.name = "port_representor",
> +		.help = "match traffic entering the embedded switch from the
> given ethdev",
> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
> +				  sizeof(struct rte_flow_item_ethdev)),
> +		.next = NEXT(item_port_representor),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
> +		.name = "port_id",
> +		.help = "ethdev port ID",
> +		.next = NEXT(item_port_representor,
> NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> port_id)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct rte_flow_item
> *item)
>  	case RTE_FLOW_ITEM_TYPE_PFCP:
>  		mask = &rte_flow_item_pfcp_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
> +		mask = &rte_flow_item_ethdev_mask;
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index 2b42d5ec8c..2e0f590777 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
>  - ``flags``: conntrack packet state flags.
>  - Default ``mask`` matches all state bits.
> 
> +Item: ``PORT_REPRESENTOR``
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches traffic entering the embedded switch from the given ethdev.
> +
> +Term **ethdev** and the concept of **port representor** are synonymous.
> +The **represented port** is an *entity* plugged to the embedded switch
> +at the opposite end of the "wire" leading to the ethdev.
> +
> +::
> +
> +    .------------------------.
> +    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
> +    '------------------------'
> +                ||
> +                \/
> +    .------------------------.
> +    |  Embedded Switch Port  |  Logical Port
> +    '------------------------'
> +                ||
> +                ||
> +                ||
> +                \/
> +    .------------------------.
> +    |  Embedded Flow Engine  |
> +    '------------------------'
> +                :
> +                 :
> +                :
> +                 :
> +    .------------------------.
> +    |  Embedded Switch Port  |  Logical Port
> +    '------------------------'
> +                :
> +                 :
> +    .------------------------.
> +    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same
> Application)
> +    '------------------------'
> +
> +

I think this drawing is harder to understand than the one
you draw in the previous thread (A-> ethdev, b-> embedded switch, switch , c-> embedded switch, d -> represented entity (shadow port).

> +- Incompatibe with `Attribute: Traffic direction`_.
> +- Requires `Attribute: Transfer`_.
> +
> +.. _table_rte_flow_item_ethdev:
> +
> +.. table:: ``struct rte_flow_item_ethdev``
> +
> +   +----------+-------------+---------------------------+
> +   | Field    | Subfield    | Value                     |
> +   +==========+=============+===========================+
> +   | ``spec`` | ``port_id`` | ethdev port ID            |
> +   +----------+-------------+---------------------------+
> +   | ``last`` | ``port_id`` | upper range value         |
> +   +----------+-------------+---------------------------+
> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
> +   +----------+-------------+---------------------------+
> +
> +- Default ``mask`` provides exact match behaviour.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 89d4b33ef1..1261cb2bf3 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -188,6 +188,8 @@ API Changes
>     Also, make sure to start the actual text at the margin.
>     =======================================================
> 
> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
> +
>  * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
>    removed. Its usages have been replaced by a new function
>    ``rte_kvargs_get_with_value()``.
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 8ead7a4a71..dcb9f47d98 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and their
> attributes, if any.
> 
>  - ``conntrack``: match conntrack state.
> 
> +- ``port_representor``: match traffic entering the embedded switch from
> +the given ethdev
> +
> +  - ``port_id {unsigned}``: ethdev port ID
> +
>  Actions list
>  ^^^^^^^^^^^^
> 
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> 8cb7a069c8..5e9317c6d1 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
> rte_flow_item_geneve_opt)),
>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
> rte_flow_item_ethdev)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> 7b1ed7f110..3625fd2c12 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_conntrack.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> +
> +	/**
> +	 * [META]
> +	 *
> +	 * Matches traffic entering the embedded switch from the given ethdev.
> +	 *
> +	 * @see struct rte_flow_item_ethdev
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
>  };
> 
>  /**
> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * Provides an ethdev port ID for use with the following items:
> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
> + */
> +struct rte_flow_item_ethdev {
> +	uint16_t port_id; /**< ethdev port ID */ };
> +
> +/** Default mask for items based on struct rte_flow_item_ethdev */
> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
> +rte_flow_item_ethdev_mask = {
> +	.port_id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to flow API
  2021-10-10 11:15       ` Ori Kam
@ 2021-10-10 13:30         ` Ivan Malov
  2021-10-10 14:04           ` Ori Kam
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 13:30 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ori,

Thanks a lot for reviewing this.

On 10/10/2021 14:15, Ori Kam wrote:
> Hi Ivan,
> 
>>From the new patches I saw you choose port_representor and represented_port
> Didn't we agree to go with ETHDEV_PORT and SHADOW_PORT?

Yes, in the previous thread I suggested a different option. But
I gave it more thought and decided to go for PORT_REPRESENTOR
and REPRESENTED_PORT instead. In any case, I apologise for it
being such short notice.

> The only thing that worries me is that the naming are very easy to get wrong.
> port_representor and represented_port.

Is that so? In "port representor", the key word is "representor", a
noun. In "represented port", the key word is "port". Word "represented"
acts like an adjective. More to that, the order of words is chosen on
purpose to prevent someone from accidentally writing "representOR_port"
in their code, for example. That simply won't compile.

Well, at least, these two are harder to get wrong compared to "employer"
and "employee", for example.

The new names are better because they are paired terms. Each one
suggests the existence of the other one. This spares one from the
need to have wordy explanations of the symmetry of the diagram.
The new names speak themselves.

Saying "shadow" is in fact vague. The reader doesn't see clearly
that it's the shadow of the ethdev. And, in turn, "ethdev" is also
not as good as "representor". It's even hard to pronounce because
of being a combination of multiple contractions.

I hope you get the idea.

> 
> Also there is an issue with wording if we assume like in previous thread that
> DPDK can have both the representor port and also the represented_port.
> While if we look at for example ethdev_port and shadow port are better defined
> as ethdev_port -> the port that is closest to the DPDK ethdev while shadow port
> is defined as the other side of the ethdev port.
> 
> What do you think?

The semantics hasn't changed since the previous thread.
Representor coincides with the ethdev, so it's still the closest port.
And represented port is still the other side. It's all the same in fact.

If both VF and its representor are plugged to DPDK, they represent each
other in fact. Mutual representors. You can equally name the first one
a representor and the other one a represented port, - and vice versa.

The new naming doesn't deny both these ports being ethdevs, while
the previous option (ethdev and shadow) may trick the reader into
thinking that only one of the two can be an ethdev. The reader may
think that this use case (when VF and its representor are plugged to
the application) is completely wrong. Let's avoid this mistake.

> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 3:05 AM
>> Subject: [PATCH v2 01/12] ethdev: add port representor item to flow API
>> ?
>> For use in "transfer" flows. Supposed to match traffic entering the embedded
>> switch from the given ethdev.
> 
> 
> I would also add a comment that says the since we are in transfer it means
> that all rules are located in the E-Switch which means that the matching is done
> on the source port of the traffic.

Let me put it clear: I don't mind adding more comments. I can do that,
yes. But look. You say "matching is done on the source port". Isn't that
what "entering the embedded switch FROM the given ethdev" already says?

> 
> I think this will also help understand the view point that we are looking from the point
> of the switch, and to add the drawing.

Well, as I said, technically, I don't object adding more comments. But
the above description says: "entering the embedded switch". Doesn't it
indicate the viewpoint clear enough? Should I reword this?

Also, "flow engine" is showed in the diagram. And there are arrows.
Doesn't that explain the viewpoint fully?

I'm ready to discuss / improve.

> 
>>
>> Must not be combined with direction attributes.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
>>   app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
>>   doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
>>   doc/guides/rel_notes/release_21_11.rst      |  2 +
>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
>>   lib/ethdev/rte_flow.c                       |  1 +
>>   lib/ethdev/rte_flow.h                       | 27 ++++++++++
>>   6 files changed, 120 insertions(+)
>>
>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
>> bb22294dd3..a912a8d815 100644
>> --- a/app/test-pmd/cmdline_flow.c
>> +++ b/app/test-pmd/cmdline_flow.c
>> @@ -306,6 +306,8 @@ enum index {
>>   	ITEM_POL_PORT,
>>   	ITEM_POL_METER,
>>   	ITEM_POL_POLICY,
>> +	ITEM_PORT_REPRESENTOR,
>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>>
>>   	/* Validate/create actions. */
>>   	ACTIONS,
>> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
>>   	ITEM_GENEVE_OPT,
>>   	ITEM_INTEGRITY,
>>   	ITEM_CONNTRACK,
>> +	ITEM_PORT_REPRESENTOR,
>>   	END_SET,
>>   	ZERO,
>>   };
>> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
>>   	ZERO,
>>   };
>>
>> +static const enum index item_port_representor[] = {
>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>> +	ITEM_NEXT,
>> +	ZERO,
>> +};
>> +
>>   static const enum index next_action[] = {
>>   	ACTION_END,
>>   	ACTION_VOID,
>> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
>>   			     item_param),
>>   		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack,
>> flags)),
>>   	},
>> +	[ITEM_PORT_REPRESENTOR] = {
>> +		.name = "port_representor",
>> +		.help = "match traffic entering the embedded switch from the
>> given ethdev",
>> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
>> +				  sizeof(struct rte_flow_item_ethdev)),
>> +		.next = NEXT(item_port_representor),
>> +		.call = parse_vc,
>> +	},
>> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
>> +		.name = "port_id",
>> +		.help = "ethdev port ID",
>> +		.next = NEXT(item_port_representor,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>> +			     item_param),
>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>> port_id)),
>> +	},
>>   	/* Validate/create actions. */
>>   	[ACTIONS] = {
>>   		.name = "actions",
>> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct rte_flow_item
>> *item)
>>   	case RTE_FLOW_ITEM_TYPE_PFCP:
>>   		mask = &rte_flow_item_pfcp_mask;
>>   		break;
>> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
>> +		mask = &rte_flow_item_ethdev_mask;
>> +		break;
>>   	default:
>>   		break;
>>   	}
>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>> b/doc/guides/prog_guide/rte_flow.rst
>> index 2b42d5ec8c..2e0f590777 100644
>> --- a/doc/guides/prog_guide/rte_flow.rst
>> +++ b/doc/guides/prog_guide/rte_flow.rst
>> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
>>   - ``flags``: conntrack packet state flags.
>>   - Default ``mask`` matches all state bits.
>>
>> +Item: ``PORT_REPRESENTOR``
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +Matches traffic entering the embedded switch from the given ethdev.
>> +
>> +Term **ethdev** and the concept of **port representor** are synonymous.
>> +The **represented port** is an *entity* plugged to the embedded switch
>> +at the opposite end of the "wire" leading to the ethdev.
>> +
>> +::
>> +
>> +    .------------------------.
>> +    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
>> +    '------------------------'
>> +                ||
>> +                \/
>> +    .------------------------.
>> +    |  Embedded Switch Port  |  Logical Port
>> +    '------------------------'
>> +                ||
>> +                ||
>> +                ||
>> +                \/
>> +    .------------------------.
>> +    |  Embedded Flow Engine  |
>> +    '------------------------'
>> +                :
>> +                 :
>> +                :
>> +                 :
>> +    .------------------------.
>> +    |  Embedded Switch Port  |  Logical Port
>> +    '------------------------'
>> +                :
>> +                 :
>> +    .------------------------.
>> +    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same
>> Application)
>> +    '------------------------'
>> +
>> +
> 
> I think this drawing is harder to understand than the one
> you draw in the previous thread (A-> ethdev, b-> embedded switch, switch , c-> embedded switch, d -> represented entity (shadow port).

Is that so? Here's the previous drawing:


      [ A ]       <-- ethdev
        |
      [ B ]       <-- embedded switch (logical) port
        |
        |
        |
===============  <-- plane of symmetry
        |
        |
        |
      [ C ]       <-- embedded switch (logical) port
        |
      [ D ]       <-- represented entity


Technically, these two are exactly the same. Yes, I use precise names
instead of letters (A, B, C, D) and more formatting, but that should
help, not confuse.

And, as I say, in the new one, I don't have to use complex terms
like "plane of symmetry". The names speak for it themselves.

> 
>> +- Incompatibe with `Attribute: Traffic direction`_.
>> +- Requires `Attribute: Transfer`_.
>> +
>> +.. _table_rte_flow_item_ethdev:
>> +
>> +.. table:: ``struct rte_flow_item_ethdev``
>> +
>> +   +----------+-------------+---------------------------+
>> +   | Field    | Subfield    | Value                     |
>> +   +==========+=============+===========================+
>> +   | ``spec`` | ``port_id`` | ethdev port ID            |
>> +   +----------+-------------+---------------------------+
>> +   | ``last`` | ``port_id`` | upper range value         |
>> +   +----------+-------------+---------------------------+
>> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
>> +   +----------+-------------+---------------------------+
>> +
>> +- Default ``mask`` provides exact match behaviour.
>> +
>>   Actions
>>   ~~~~~~~
>>
>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>> b/doc/guides/rel_notes/release_21_11.rst
>> index 89d4b33ef1..1261cb2bf3 100644
>> --- a/doc/guides/rel_notes/release_21_11.rst
>> +++ b/doc/guides/rel_notes/release_21_11.rst
>> @@ -188,6 +188,8 @@ API Changes
>>      Also, make sure to start the actual text at the margin.
>>      =======================================================
>>
>> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
>> +
>>   * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
>>     removed. Its usages have been replaced by a new function
>>     ``rte_kvargs_get_with_value()``.
>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> index 8ead7a4a71..dcb9f47d98 100644
>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and their
>> attributes, if any.
>>
>>   - ``conntrack``: match conntrack state.
>>
>> +- ``port_representor``: match traffic entering the embedded switch from
>> +the given ethdev
>> +
>> +  - ``port_id {unsigned}``: ethdev port ID
>> +
>>   Actions list
>>   ^^^^^^^^^^^^
>>
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>> 8cb7a069c8..5e9317c6d1 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
>> rte_flow_desc_item[] = {
>>   	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
>> rte_flow_item_geneve_opt)),
>>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
>> rte_flow_item_ethdev)),
>>   };
>>
>>   /** Generate flow_action[] entry. */
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> 7b1ed7f110..3625fd2c12 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>   	 * @see struct rte_flow_item_conntrack.
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_CONNTRACK,
>> +
>> +	/**
>> +	 * [META]
>> +	 *
>> +	 * Matches traffic entering the embedded switch from the given ethdev.
>> +	 *
>> +	 * @see struct rte_flow_item_ethdev
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
>>   };
>>
>>   /**
>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>> rte_flow_item_conntrack_mask = {  };  #endif
>>
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + *
>> + * Provides an ethdev port ID for use with the following items:
>> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
>> + */
>> +struct rte_flow_item_ethdev {
>> +	uint16_t port_id; /**< ethdev port ID */ };
>> +
>> +/** Default mask for items based on struct rte_flow_item_ethdev */
>> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
>> +rte_flow_item_ethdev_mask = {
>> +	.port_id = 0xffff,
>> +};
>> +#endif
>> +
>>   /**
>>    * Matching pattern item definition.
>>    *
>> --
>> 2.20.1

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to flow API
  2021-10-10 13:30         ` Ivan Malov
@ 2021-10-10 14:04           ` Ori Kam
  2021-10-10 15:02             ` Ivan Malov
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-10 14:04 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan.

> -----Original Message-----
> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 4:30 PM
> Subject: Re: [PATCH v2 01/12] ethdev: add port representor item to flow API
> 
> Hi Ori,
> 
> Thanks a lot for reviewing this.
> 
> On 10/10/2021 14:15, Ori Kam wrote:
> > Hi Ivan,
> >
> >>From the new patches I saw you choose port_representor and
> >>represented_port
> > Didn't we agree to go with ETHDEV_PORT and SHADOW_PORT?
> 
> Yes, in the previous thread I suggested a different option. But I gave it more thought and decided to go for
> PORT_REPRESENTOR and REPRESENTED_PORT instead. In any case, I apologise for it being such short
> notice.
> 
> > The only thing that worries me is that the naming are very easy to get wrong.
> > port_representor and represented_port.
> 
> Is that so? In "port representor", the key word is "representor", a noun. In "represented port", the key
> word is "port". Word "represented"
> acts like an adjective. More to that, the order of words is chosen on purpose to prevent someone from
> accidentally writing "representOR_port"
> in their code, for example. That simply won't compile.
> 
> Well, at least, these two are harder to get wrong compared to "employer"
> and "employee", for example.
> 
> The new names are better because they are paired terms. Each one suggests the existence of the other
> one. This spares one from the need to have wordy explanations of the symmetry of the diagram.
> The new names speak themselves.
> 
> Saying "shadow" is in fact vague. The reader doesn't see clearly that it's the shadow of the ethdev. And, in
> turn, "ethdev" is also not as good as "representor". It's even hard to pronounce because of being a
> combination of multiple contractions.
> 
> I hope you get the idea.
> 

I get the idea, since my English is not perfect from my view point those are a bit more confusing and easy
to get wrong but I have no objection to keep them.
Lets see what others will think about it.

> >
> > Also there is an issue with wording if we assume like in previous
> > thread that DPDK can have both the representor port and also the represented_port.
> > While if we look at for example ethdev_port and shadow port are better
> > defined as ethdev_port -> the port that is closest to the DPDK ethdev
> > while shadow port is defined as the other side of the ethdev port.
> >
> > What do you think?
> 
> The semantics hasn't changed since the previous thread.
> Representor coincides with the ethdev, so it's still the closest port.
> And represented port is still the other side. It's all the same in fact.
> 
> If both VF and its representor are plugged to DPDK, they represent each other in fact. Mutual
> representors. You can equally name the first one a representor and the other one a represented port, -
> and vice versa.
> 
> The new naming doesn't deny both these ports being ethdevs, while the previous option (ethdev and
> shadow) may trick the reader into thinking that only one of the two can be an ethdev. The reader may
> think that this use case (when VF and its representor are plugged to the application) is completely wrong.
> Let's avoid this mistake.
> 

I agree those are semantics and there is no perfect world.
I accept your case.

> >
> >> -----Original Message-----
> >> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> Sent: Sunday, October 10, 2021 3:05 AM
> >> Subject: [PATCH v2 01/12] ethdev: add port representor item to flow
> >> API ?
> >> For use in "transfer" flows. Supposed to match traffic entering the
> >> embedded switch from the given ethdev.
> >
> >
> > I would also add a comment that says the since we are in transfer it
> > means that all rules are located in the E-Switch which means that the
> > matching is done on the source port of the traffic.
> 
> Let me put it clear: I don't mind adding more comments. I can do that, yes. But look. You say "matching is
> done on the source port". Isn't that what "entering the embedded switch FROM the given ethdev" already
> says?
> 
Yes,  the idea of this series is to clear everything.
Do you think that someone who just read this commit log can without prior knowledge of RTE flow
and transfer can fully understand the idea?

If so I'm, O.K. with leaving the comment as is.

In most related comment about pharsing I'm giving my view point with all
the comments I got about how much hard it is to create rules and understand the
documentation.

Unless there is something wrong or misleading I can except most answers and comments,
but I steel think that sometime it is worth saying them even if it is just for the developer to think
again if something can be improved.

> >
> > I think this will also help understand the view point that we are
> > looking from the point of the switch, and to add the drawing.
> 
> Well, as I said, technically, I don't object adding more comments. But the above description says: "entering
> the embedded switch". Doesn't it indicate the viewpoint clear enough? Should I reword this?
> 
> Also, "flow engine" is showed in the diagram. And there are arrows.
> Doesn't that explain the viewpoint fully?
> 
> I'm ready to discuss / improve.

Yes, but I was thinking about also adding it in the commit log.

> 
> >
> >>
> >> Must not be combined with direction attributes.
> >>
> >> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> >> ---
> >>   app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
> >>   doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
> >>   doc/guides/rel_notes/release_21_11.rst      |  2 +
> >>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
> >>   lib/ethdev/rte_flow.c                       |  1 +
> >>   lib/ethdev/rte_flow.h                       | 27 ++++++++++
> >>   6 files changed, 120 insertions(+)
> >>
> >> diff --git a/app/test-pmd/cmdline_flow.c
> >> b/app/test-pmd/cmdline_flow.c index
> >> bb22294dd3..a912a8d815 100644
> >> --- a/app/test-pmd/cmdline_flow.c
> >> +++ b/app/test-pmd/cmdline_flow.c
> >> @@ -306,6 +306,8 @@ enum index {
> >>   	ITEM_POL_PORT,
> >>   	ITEM_POL_METER,
> >>   	ITEM_POL_POLICY,
> >> +	ITEM_PORT_REPRESENTOR,
> >> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> >>
> >>   	/* Validate/create actions. */
> >>   	ACTIONS,
> >> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
> >>   	ITEM_GENEVE_OPT,
> >>   	ITEM_INTEGRITY,
> >>   	ITEM_CONNTRACK,
> >> +	ITEM_PORT_REPRESENTOR,
> >>   	END_SET,
> >>   	ZERO,
> >>   };
> >> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
> >>   	ZERO,
> >>   };
> >>
> >> +static const enum index item_port_representor[] = {
> >> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> >> +	ITEM_NEXT,
> >> +	ZERO,
> >> +};
> >> +
> >>   static const enum index next_action[] = {
> >>   	ACTION_END,
> >>   	ACTION_VOID,
> >> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
> >>   			     item_param),
> >>   		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
> >>   	},
> >> +	[ITEM_PORT_REPRESENTOR] = {
> >> +		.name = "port_representor",
> >> +		.help = "match traffic entering the embedded switch from the
> >> given ethdev",
> >> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
> >> +				  sizeof(struct rte_flow_item_ethdev)),
> >> +		.next = NEXT(item_port_representor),
> >> +		.call = parse_vc,
> >> +	},
> >> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
> >> +		.name = "port_id",
> >> +		.help = "ethdev port ID",
> >> +		.next = NEXT(item_port_representor,
> >> NEXT_ENTRY(COMMON_UNSIGNED),
> >> +			     item_param),
> >> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> >> port_id)),
> >> +	},
> >>   	/* Validate/create actions. */
> >>   	[ACTIONS] = {
> >>   		.name = "actions",
> >> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct
> >> rte_flow_item
> >> *item)
> >>   	case RTE_FLOW_ITEM_TYPE_PFCP:
> >>   		mask = &rte_flow_item_pfcp_mask;
> >>   		break;
> >> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
> >> +		mask = &rte_flow_item_ethdev_mask;
> >> +		break;
> >>   	default:
> >>   		break;
> >>   	}
> >> diff --git a/doc/guides/prog_guide/rte_flow.rst
> >> b/doc/guides/prog_guide/rte_flow.rst
> >> index 2b42d5ec8c..2e0f590777 100644
> >> --- a/doc/guides/prog_guide/rte_flow.rst
> >> +++ b/doc/guides/prog_guide/rte_flow.rst
> >> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
> >>   - ``flags``: conntrack packet state flags.
> >>   - Default ``mask`` matches all state bits.
> >>
> >> +Item: ``PORT_REPRESENTOR``
> >> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> >> +
> >> +Matches traffic entering the embedded switch from the given ethdev.
> >> +
> >> +Term **ethdev** and the concept of **port representor** are synonymous.
> >> +The **represented port** is an *entity* plugged to the embedded
> >> +switch at the opposite end of the "wire" leading to the ethdev.
> >> +
> >> +::
> >> +
> >> +    .------------------------.
> >> +    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
> >> +    '------------------------'
> >> +                ||
> >> +                \/
> >> +    .------------------------.
> >> +    |  Embedded Switch Port  |  Logical Port
> >> +    '------------------------'
> >> +                ||
> >> +                ||
> >> +                ||
> >> +                \/
> >> +    .------------------------.
> >> +    |  Embedded Flow Engine  |
> >> +    '------------------------'
> >> +                :
> >> +                 :
> >> +                :
> >> +                 :
> >> +    .------------------------.
> >> +    |  Embedded Switch Port  |  Logical Port
> >> +    '------------------------'
> >> +                :
> >> +                 :
> >> +    .------------------------.
> >> +    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same
> >> Application)
> >> +    '------------------------'
> >> +
> >> +
> >
> > I think this drawing is harder to understand than the one you draw in
> > the previous thread (A-> ethdev, b-> embedded switch, switch , c-> embedded switch, d -> represented
> entity (shadow port).
> 
> Is that so? Here's the previous drawing:
> 
> 
>       [ A ]       <-- ethdev
>         |
>       [ B ]       <-- embedded switch (logical) port
>         |
>         |
>         |
> ===============  <-- plane of symmetry
>         |
>         |
>         |
>       [ C ]       <-- embedded switch (logical) port
>         |
>       [ D ]       <-- represented entity
> 
> 
> Technically, these two are exactly the same. Yes, I use precise names instead of letters (A, B, C, D) and
> more formatting, but that should help, not confuse.
> 
> And, as I say, in the new one, I don't have to use complex terms like "plane of symmetry". The names
> speak for it themselves.
> 

That was what I was missing and the only difference between the two,
Th plane of symmetry (I'm not sure I like this name) but it is much cleared them embedded engine.
Embedded engine has meaning for me which is very different.
maybe just replace it with  switch? Or Embedded switch?
 
> >
> >> +- Incompatibe with `Attribute: Traffic direction`_.
> >> +- Requires `Attribute: Transfer`_.
> >> +
> >> +.. _table_rte_flow_item_ethdev:
> >> +
> >> +.. table:: ``struct rte_flow_item_ethdev``
> >> +
> >> +   +----------+-------------+---------------------------+
> >> +   | Field    | Subfield    | Value                     |
> >> +   +==========+=============+===========================+
> >> +   | ``spec`` | ``port_id`` | ethdev port ID            |
> >> +   +----------+-------------+---------------------------+
> >> +   | ``last`` | ``port_id`` | upper range value         |
> >> +   +----------+-------------+---------------------------+
> >> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
> >> +   +----------+-------------+---------------------------+
> >> +
> >> +- Default ``mask`` provides exact match behaviour.
> >> +
> >>   Actions
> >>   ~~~~~~~
> >>
> >> diff --git a/doc/guides/rel_notes/release_21_11.rst
> >> b/doc/guides/rel_notes/release_21_11.rst
> >> index 89d4b33ef1..1261cb2bf3 100644
> >> --- a/doc/guides/rel_notes/release_21_11.rst
> >> +++ b/doc/guides/rel_notes/release_21_11.rst
> >> @@ -188,6 +188,8 @@ API Changes
> >>      Also, make sure to start the actual text at the margin.
> >>      =======================================================
> >>
> >> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
> >> +
> >>   * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
> >>     removed. Its usages have been replaced by a new function
> >>     ``rte_kvargs_get_with_value()``.
> >> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> index 8ead7a4a71..dcb9f47d98 100644
> >> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> >> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and
> >> their attributes, if any.
> >>
> >>   - ``conntrack``: match conntrack state.
> >>
> >> +- ``port_representor``: match traffic entering the embedded switch
> >> +from the given ethdev
> >> +
> >> +  - ``port_id {unsigned}``: ethdev port ID
> >> +
> >>   Actions list
> >>   ^^^^^^^^^^^^
> >>
> >> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> >> 8cb7a069c8..5e9317c6d1 100644
> >> --- a/lib/ethdev/rte_flow.c
> >> +++ b/lib/ethdev/rte_flow.c
> >> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
> >> rte_flow_desc_item[] = {
> >>   	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
> >>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
> >>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> >> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
> >> rte_flow_item_ethdev)),
> >>   };
> >>
> >>   /** Generate flow_action[] entry. */ diff --git
> >> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >> 7b1ed7f110..3625fd2c12 100644
> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
> >>   	 * @see struct rte_flow_item_conntrack.
> >>   	 */
> >>   	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> >> +
> >> +	/**
> >> +	 * [META]
> >> +	 *
> >> +	 * Matches traffic entering the embedded switch from the given ethdev.
> >> +	 *
> >> +	 * @see struct rte_flow_item_ethdev
> >> +	 */
> >> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
> >>   };
> >>
> >>   /**
> >> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
> >> rte_flow_item_conntrack_mask = {  };  #endif
> >>
> >> +/**
> >> + * @warning
> >> + * @b EXPERIMENTAL: this structure may change without prior notice
> >> + *
> >> + * Provides an ethdev port ID for use with the following items:
> >> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
> >> + */
> >> +struct rte_flow_item_ethdev {
> >> +	uint16_t port_id; /**< ethdev port ID */ };
> >> +
> >> +/** Default mask for items based on struct rte_flow_item_ethdev */
> >> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
> >> +rte_flow_item_ethdev_mask = {
> >> +	.port_id = 0xffff,
> >> +};
> >> +#endif
> >> +
> >>   /**
> >>    * Matching pattern item definition.
> >>    *
> >> --
> >> 2.20.1
> 
> --
> Ivan M

Best,
Ori

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

* [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (12 preceding siblings ...)
  2021-10-10  0:04   ` [dpdk-dev] [PATCH v2 00/12] ethdev: rework transfer flow API Ivan Malov
@ 2021-10-10 14:39   ` Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
                       ` (13 more replies)
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                     ` (3 subsequent siblings)
  17 siblings, 14 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam

As per RFC [1], action PORT_ID appears to be ambiguous. Its name suggests
that matching traffic be sent to the ethdev with the specified ID, that
is, to the application. However, in Open vSwitch, the action is used to
send traffic to a remote entity represented by the given port, that is,
in the opposite direction. Its interpretation across PMDs also varies.

RFC [2] attempted to define action PORT_ID semantics in vSwitch sense.
However, this solution would completely abandon the opposite meaning.

One more effort, RFC [3], was meant to declare that the use of direction
attributes in "transfer" flows assumed implicit filtering by the port ID
appearing as the first argument in rte_flow_create(). However, not all
PMDs require such filtering, so the RFC turned out rather disputable.


Since then, all of that has been given more thought:

1. One should not attempt to fix action PORT_ID. Instead, two new actions
   should be introduced. The first one should send traffic to the given
   ethdev. The second one should send it to the represented entity.

2. Similar to (1), two new items should be defined. The first one should
   match traffic going down from the given ethdev. The second one should
   match traffic going up from the entity represented by that ethdev.

3. The application always knows which packets come through which ethdevs.
   So, as per (2), the application can use the new item to match traffic
   arriving from precise entities represented by the relevant ethdev IDs.

4. New items suggested in (2) do not require the use of direction
   attributes. These items define precise directions on their own.

5. As a consequence of (3) and (4), the problem of implicit filtering
   by rte_flow_create() port ID argument and direction attributes is
   no longer a blocker. The new items allow to dispose of it.


The new items appear to be symmetrical to each other. So do the new
actions. This requires that their names reflect the symmetry. Also,
the names should respect the existing concept of port representors.
By the looks of it, terms "PORT_REPRESENTOR" and "REPRESENTED_PORT"
satisfy these requirements. However, currently, ethdevs associated
with network ports are not considered as their representors. Such
understanding is mentioned in the documentation, but it's not
expressed in the code (see enum rte_eth_representor_type).


The short of it, this patch series follows points (1-5) to rework
support for "transfer" flows accordingly. On the way, a string of
ambiguous pattern items (PF, VF, PHY_PORT) is deprecated.

The patch series also updates PMDs which support item and action PORT_ID
to add support for replacements (1-2). However, there're some exceptions:

 - Support for traffic source items in the case of net/mlx5 is really
   complicated. This series does not rework it. The PMD maintainer
   can do the job much better and test the new code accordingly;

 - Support for action REPRESENTED_PORT is not added to net/sfc.
   This will be done when support for VF representors has been
   upstreamed, just for the new code to apply cleanly.


Changes in v2:
* New naming and reworked comments
* New diagrams

Changes in v3:
* Diagram improvements
* Spelling fixes

[1] https://patches.dpdk.org/project/dpdk/patch/20210907125157.3843-1-ivan.malov@oktetlabs.ru/
[2] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/
[3] https://patches.dpdk.org/project/dpdk/patch/20210901151104.3923889-1-andrew.rybchenko@oktetlabs.ru/

Andrew Rybchenko (6):
  net/bnxt: support meta flow items to match on traffic source
  net/bnxt: support meta flow actions to overrule destinations
  net/enic: support meta flow actions to overrule destinations
  net/mlx5: support represented port flow action
  net/octeontx2: support port representor flow action
  net/sfc: support port representor flow item

Ivan Malov (6):
  ethdev: add port representor item to flow API
  ethdev: add represented port item to flow API
  ethdev: add port representor action to flow API
  ethdev: add represented port action to flow API
  ethdev: deprecate hard-to-use or ambiguous items and actions
  ethdev: deprecate direction attributes in transfer flows

 app/test-pmd/cmdline_flow.c                   | 104 +++++++
 doc/guides/nics/mlx5.rst                      |   4 +-
 doc/guides/nics/octeontx2.rst                 |   5 +-
 doc/guides/nics/sfc_efx.rst                   |   2 +
 doc/guides/prog_guide/rte_flow.rst            | 270 +++++++++++++++++-
 doc/guides/rel_notes/deprecation.rst          |  18 +-
 doc/guides/rel_notes/release_21_11.rst        |   8 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst   |  19 ++
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |  22 +-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 161 ++++++++---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  12 +-
 drivers/net/enic/enic_fm_flow.c               |  93 ++++--
 drivers/net/mlx5/mlx5_flow_dv.c               |  62 +++-
 drivers/net/octeontx2/otx2_flow_parse.c       |  16 +-
 drivers/net/sfc/sfc_mae.c                     |  72 +++++
 lib/ethdev/rte_flow.c                         |   4 +
 lib/ethdev/rte_flow.h                         | 162 ++++++++++-
 17 files changed, 914 insertions(+), 120 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 11:49       ` Ori Kam
                         ` (2 more replies)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port " Ivan Malov
                       ` (12 subsequent siblings)
  13 siblings, 3 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to match traffic
entering the embedded switch from the given ethdev.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 27 ++++++++++
 6 files changed, 120 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index bb22294dd3..a912a8d815 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -306,6 +306,8 @@ enum index {
 	ITEM_POL_PORT,
 	ITEM_POL_METER,
 	ITEM_POL_POLICY,
+	ITEM_PORT_REPRESENTOR,
+	ITEM_PORT_REPRESENTOR_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
+	ITEM_PORT_REPRESENTOR,
 	END_SET,
 	ZERO,
 };
@@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_port_representor[] = {
+	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
 	},
+	[ITEM_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "match traffic entering the embedded switch from the given ethdev",
+		.priv = PRIV_ITEM(PORT_REPRESENTOR,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_port_representor),
+		.call = parse_vc,
+	},
+	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+		mask = &rte_flow_item_ethdev_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2b42d5ec8c..91d5bdd712 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              ||
+              \/
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              ||
+              ||
+              ||
+              \/
+         .----------.
+         |  Switch  |
+         '----------'
+              :
+               :
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Incompatible with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_item_ethdev:
+
+.. table:: ``struct rte_flow_item_ethdev``
+
+   +----------+-------------+---------------------------+
+   | Field    | Subfield    | Value                     |
+   +==========+=============+===========================+
+   | ``spec`` | ``port_id`` | ethdev port ID            |
+   +----------+-------------+---------------------------+
+   | ``last`` | ``port_id`` | upper range value         |
+   +----------+-------------+---------------------------+
+   | ``mask`` | ``port_id`` | zeroed for wildcard match |
+   +----------+-------------+---------------------------+
+
+- Default ``mask`` provides exact match behaviour.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 89d4b33ef1..1261cb2bf3 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,6 +188,8 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 8ead7a4a71..dcb9f47d98 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3795,6 +3795,10 @@ This section lists supported pattern items and their attributes, if any.
 
 - ``conntrack``: match conntrack state.
 
+- ``port_representor``: match traffic entering the embedded switch from the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..5e9317c6d1 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -100,6 +100,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
+	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 7b1ed7f110..3625fd2c12 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -574,6 +574,15 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following items:
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_item_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
+/** Default mask for items based on struct rte_flow_item_ethdev */
+#ifndef __cplusplus
+static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
+	.port_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port item to flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 11:51       ` Ori Kam
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action " Ivan Malov
                       ` (11 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to match traffic entering the
embedded switch from the entity represented by the given ethdev.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 25 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 46 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 13 +++++-
 6 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a912a8d815..68698d805d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -308,6 +308,8 @@ enum index {
 	ITEM_POL_POLICY,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_REPRESENTED_PORT,
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1003,6 +1005,7 @@ static const enum index next_item[] = {
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
+	ITEM_REPRESENTED_PORT,
 	END_SET,
 	ZERO,
 };
@@ -1377,6 +1380,12 @@ static const enum index item_port_representor[] = {
 	ZERO,
 };
 
+static const enum index item_represented_port[] = {
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3632,6 +3641,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "match traffic entering the embedded switch from the entity represented by the given ethdev",
+		.priv = PRIV_ITEM(REPRESENTED_PORT,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_represented_port),
+		.call = parse_vc,
+	},
+	[ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8368,6 +8392,7 @@ flow_item_default_mask(const struct rte_flow_item *item)
 		mask = &rte_flow_item_pfcp_mask;
 		break;
 	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
 	default:
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 91d5bdd712..12a216c1e3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,52 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+Item: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+              :
+               :
+         .----------.
+         |  Switch  |
+         '----------'
+              /\
+              ||
+              ||
+              ||
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              /\
+              ||
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Incompatible with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 1261cb2bf3..39ff16780b 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index dcb9f47d98..44a399899f 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3799,6 +3799,11 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: match traffic entering the embedded switch from
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 5e9317c6d1..d4b654a2c6 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -101,6 +101,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 3625fd2c12..24d41aeb7b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -583,6 +583,16 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -1813,7 +1823,8 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following items:
- * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_item_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action to flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 18:18       ` Ori Kam
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port " Ivan Malov
                       ` (10 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to send matching traffic to
the given ethdev (to the application), at embedded switch level.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 56 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 18 +++++++
 6 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 68698d805d..ee6dac411a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -460,6 +460,8 @@ enum index {
 	ACTION_POL_G,
 	ACTION_POL_Y,
 	ACTION_POL_R,
+	ACTION_PORT_REPRESENTOR,
+	ACTION_PORT_REPRESENTOR_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1452,6 +1454,7 @@ static const enum index next_action[] = {
 	ACTION_MODIFY_FIELD,
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
+	ACTION_PORT_REPRESENTOR,
 	ZERO,
 };
 
@@ -1733,6 +1736,12 @@ static const enum index action_update_conntrack[] = {
 	ZERO,
 };
 
+static const enum index action_port_representor[] = {
+	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4820,6 +4829,23 @@ static const struct token token_list[] = {
 		.next = NEXT(action_update_conntrack),
 		.call = parse_vc_action_conntrack_update,
 	},
+	[ACTION_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "at embedded switch level, send matching traffic to the given ethdev",
+		.priv = PRIV_ACTION(PORT_REPRESENTOR,
+				    sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_port_representor),
+		.call = parse_vc,
+	},
+	[ACTION_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_port_representor,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 12a216c1e3..a6401fb5df 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+See also `Action: PORT_REPRESENTOR`_.
+
 Item: ``REPRESENTED_PORT``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -3104,6 +3106,60 @@ which is set in the packet meta-data (i.e. struct ``rte_mbuf::sched::color``)
    | ``meter_color`` | Packet color |
    +-----------------+--------------+
 
+Action: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              /\
+              ||
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              /\
+              ||
+              ||
+              ||
+         .----------.       .--------------------.
+         |  Switch  |  <==  |  Matching Traffic  |
+         '----------'       '--------------------'
+              :
+               :
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_action_ethdev:
+
+.. table:: ``struct rte_flow_action_ethdev``
+
+   +-------------+----------------+
+   | Field       | Value          |
+   +=============+================+
+   | ``port_id`` | ethdev port ID |
+   +-------------+----------------+
+
+See also `Item: PORT_REPRESENTOR`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 39ff16780b..bf46329e52 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 44a399899f..5f127fdbcc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4079,6 +4079,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``type {value}``: Set color type with specified value(green/yellow/red)
 
+- ``port_representor``: at embedded switch level, send matching traffic to
+  the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index d4b654a2c6..b074b1c77d 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -191,6 +191,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	 */
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
+	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 24d41aeb7b..cf4165bef3 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2447,6 +2447,13 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_meter_color.
 	 */
 	RTE_FLOW_ACTION_TYPE_METER_COLOR,
+
+	/**
+	 * At embedded switch level, sends matching traffic to the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -3206,6 +3213,17 @@ struct rte_flow_action_meter_color {
 	enum rte_color color; /**< Packet color. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following actions:
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_action_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
 /**
  * Field IDs for MODIFY_FIELD action.
  */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port action to flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (2 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 18:20       ` Ori Kam
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
                       ` (9 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

For use in "transfer" flows. Supposed to send matching traffic to the
entity represented by the given ethdev, at embedded switch level.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 11 ++++-
 6 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ee6dac411a..c704bbaead 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -462,6 +462,8 @@ enum index {
 	ACTION_POL_R,
 	ACTION_PORT_REPRESENTOR,
 	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_REPRESENTED_PORT,
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1455,6 +1457,7 @@ static const enum index next_action[] = {
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
 	ACTION_PORT_REPRESENTOR,
+	ACTION_REPRESENTED_PORT,
 	ZERO,
 };
 
@@ -1742,6 +1745,12 @@ static const enum index action_port_representor[] = {
 	ZERO,
 };
 
+static const enum index action_represented_port[] = {
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4846,6 +4855,23 @@ static const struct token token_list[] = {
 					port_id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev",
+		.priv = PRIV_ACTION(REPRESENTED_PORT,
+				sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_represented_port),
+		.call = parse_vc,
+	},
+	[ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_represented_port,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a6401fb5df..2bc437e5cd 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1532,6 +1532,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
+See also `Action: REPRESENTED_PORT`_.
+
 Actions
 ~~~~~~~
 
@@ -3160,6 +3162,53 @@ at the opposite end of the "wire" leading to the ethdev.
 
 See also `Item: PORT_REPRESENTOR`_.
 
+Action: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+              :
+               :
+         .----------.       .--------------------.
+         |  Switch  |  <==  |  Matching Traffic  |
+         '----------'       '--------------------'
+              ||
+              ||
+              ||
+              \/
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              ||
+              \/
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+This action is meant to use the same structure as `Action: PORT_REPRESENTOR`_.
+
+See also `Item: REPRESENTED_PORT`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index bf46329e52..f689a10e63 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -188,7 +188,7 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 5f127fdbcc..d1c5cb7383 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4084,6 +4084,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: at embedded switch level, send matching traffic to
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index b074b1c77d..542e40e496 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -192,6 +192,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
 	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
+	MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index cf4165bef3..afd1f4c193 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2454,6 +2454,14 @@ enum rte_flow_action_type {
 	 * @see struct rte_flow_action_ethdev
 	 */
 	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * At embedded switch level, send matching traffic to
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -3218,7 +3226,8 @@ struct rte_flow_action_meter_color {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following actions:
- * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_action_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (3 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 18:23       ` Ori Kam
  2021-10-13 11:53       ` Ferruh Yigit
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
                       ` (8 subsequent siblings)
  13 siblings, 2 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Ray Kinsella, Ferruh Yigit, Andrew Rybchenko

PF, VF and PHY_PORT require that applications have extra
knowledge of the underlying NIC and thus are hard to use.
Also, the corresponding items depend on the direction
attribute (ingress / egress), which complicates their
use in applications and interpretation in PMDs.

The concept of PORT_ID is ambiguous as it doesn't say whether
the port in question is an ethdev or the represented entity.

Items and actions PORT_REPRESENTOR, REPRESENTED_PORT
should be used instead.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 32 +++++++++++++++
 doc/guides/rel_notes/deprecation.rst   |  9 ++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 56 ++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2bc437e5cd..1aa24e0633 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -504,6 +504,10 @@ Usage example, matching non-TCPv4 packets only:
 Item: ``PF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) the physical
 function of the current device.
 
@@ -531,6 +535,10 @@ the application and thus not associated with a DPDK port ID.
 Item: ``VF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given
 virtual function of the current device.
 
@@ -562,6 +570,10 @@ separate entities, should be addressed through their own DPDK port IDs.
 Item: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a physical
 port of the underlying device.
 
@@ -596,6 +608,10 @@ associated with a port_id should be retrieved by other means.
 Item: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given DPDK
 port ID.
 
@@ -1965,6 +1981,10 @@ only matching traffic goes through.
 Action: ``PF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to the physical function (PF) of the current
 device.
 
@@ -1985,6 +2005,10 @@ See `Item: PF`_.
 Action: ``VF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given virtual function of the current device.
 
 Packets matched by a VF pattern item can be redirected to their original VF
@@ -2009,6 +2033,10 @@ See `Item: VF`_.
 Action: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given physical port index of the underlying
 device.
 
@@ -2028,6 +2056,10 @@ See `Item: PHY_PORT`_.
 
 Action: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^^^
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given DPDK port ID.
 
 See `Item: PORT_ID`_.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b86147dda1..c91d570099 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -122,12 +122,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Definition of the flow API action ``RTE_FLOW_ACTION_TYPE_PORT_ID``
-  is ambiguous and needs clarification.
-  Structure ``rte_flow_action_port_id`` will be extended to specify
-  traffic direction to the represented entity or ethdev port itself
-  in DPDK 21.11.
-
 * ethdev: Flow API documentation is unclear if ethdev port used to create
   a flow rule adds any implicit match criteria in the case of transfer rules.
   The semantics will be clarified in DPDK 21.11 and it will require fixes in
@@ -256,3 +250,6 @@ Deprecation Notices
 * cmdline: ``cmdline`` structure will be made opaque to hide platform-specific
   content. On Linux and FreeBSD, supported prior to DPDK 20.11,
   original structure will be kept until DPDK 21.11.
+
+* ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
+  deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index f689a10e63..63f946ad88 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -190,6 +190,9 @@ API Changes
 
 * ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
+* ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
+  Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index afd1f4c193..afd50d6d51 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -160,6 +160,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_ANY,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress)
@@ -170,6 +174,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -180,6 +188,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -190,6 +202,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -640,6 +656,10 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_VF
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -669,6 +689,10 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PHY_PORT
  *
  * Matches traffic originating from (ingress) or going to (egress) a
@@ -700,6 +724,10 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PORT_ID
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -1990,6 +2018,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_RSS,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to the physical function (PF) of the
 	 * current device.
 	 *
@@ -1998,6 +2030,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given virtual function of the
 	 * current device.
 	 *
@@ -2006,6 +2042,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs packets to a given physical port index of the underlying
 	 * device.
 	 *
@@ -2014,6 +2054,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given DPDK port ID.
 	 *
 	 * See struct rte_flow_action_port_id.
@@ -2654,6 +2698,10 @@ struct rte_flow_action_rss {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_VF
  *
  * Directs matching traffic to a given virtual function of the current
@@ -2672,6 +2720,10 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PHY_PORT
  *
  * Directs packets to a given physical port index of the underlying
@@ -2686,6 +2738,10 @@ struct rte_flow_action_phy_port {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PORT_ID
  *
  * Directs matching traffic to a given DPDK port ID.
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (4 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-11 18:33       ` Ori Kam
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
                       ` (7 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Ray Kinsella, Ferruh Yigit, Andrew Rybchenko

Attributes "ingress" and "egress" can only apply unambiguosly
to non-"transfer" flows. In "transfer" flows, the standpoint
is effectively shifted to the embedded switch. There can be
many different endpoints connected to the switch, so the
use of "ingress" / "egress" does not shed light on which
endpoints precisely can be considered as traffic sources.

Add relevant deprecation notices and suggest the use of precise
traffic source items (PORT_REPRESENTOR and REPRESENTED_PORT).

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 28 ++++++++----------
 doc/guides/rel_notes/deprecation.rst   |  9 +++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 41 ++++++++++++++++++++------
 4 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 1aa24e0633..f82b20c7b1 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -9,8 +9,8 @@ Overview
 --------
 
 This API provides a generic means to configure hardware to match specific
-ingress or egress traffic, alter its fate and query related counters
-according to any number of user-defined rules.
+traffic, alter its fate and query related counters according to any
+number of user-defined rules.
 
 It is named *rte_flow* after the prefix used for all its symbols, and is
 defined in ``rte_flow.h``.
@@ -146,13 +146,10 @@ Note that support for more than a single priority level is not guaranteed.
 Attribute: Traffic direction
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Flow rule patterns apply to inbound and/or outbound traffic.
-
-In the context of this API, **ingress** and **egress** respectively stand
-for **inbound** and **outbound** based on the standpoint of the application
-creating a flow rule.
-
-There are no exceptions to this definition.
+Unless `Attribute: Transfer`_ is specified, flow rule patterns apply
+to inbound and / or outbound traffic. With this respect, ``ingress``
+and ``egress`` respectively stand for **inbound** and **outbound**
+based on the standpoint of the application creating a flow rule.
 
 Several pattern items and actions are valid and can be used in both
 directions. At least one direction must be specified.
@@ -171,12 +168,13 @@ When supported, this effectively enables an application to reroute traffic
 not necessarily intended for it (e.g. coming from or addressed to different
 physical ports, VFs or applications) at the device level.
 
-It complements the behavior of some pattern items such as `Item: PHY_PORT`_
-and is meaningless without them.
-
-When transferring flow rules, **ingress** and **egress** attributes
-(`Attribute: Traffic direction`_) keep their original meaning, as if
-processing traffic emitted or received by the application.
+In "transfer" flows, the use of `Attribute: Traffic direction`_ in the sense of
+implicitly matching packets going to or going from the ethdev used to create
+flow rules is **deprecated**. `Attribute: Transfer`_ shifts the viewpoint to
+the embedded switch. In it, `Attribute: Traffic direction`_ is ambiguous as
+the switch serves many different endpoints. The application should match
+traffic originating from precise locations. To do so, it should
+use `Item: PORT_REPRESENTOR`_ and `Item: REPRESENTED_PORT`_.
 
 Pattern item
 ~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index c91d570099..02a5b6eeba 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -122,11 +122,6 @@ Deprecation Notices
   is deprecated and will be removed in DPDK 21.11. Shared counters should
   be managed using shared actions API (``rte_flow_shared_action_create`` etc).
 
-* ethdev: Flow API documentation is unclear if ethdev port used to create
-  a flow rule adds any implicit match criteria in the case of transfer rules.
-  The semantics will be clarified in DPDK 21.11 and it will require fixes in
-  drivers and applications which interpret it in a different way.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header.
   Some matching pattern structures implements this by duplicating protocol header
@@ -253,3 +248,7 @@ Deprecation Notices
 
 * ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
   deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
+
+* ethdev: The use of attributes ``ingress`` / ``egress`` in "transfer" flows
+  is deprecated as ambiguous with respect to the embedded switch. The use of
+  these attributes will become invalid starting from DPDK 22.11.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 63f946ad88..d4dadbfcf4 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -193,6 +193,9 @@ API Changes
 * ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
   Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
 
+* ethdev: Deprecated the use of attributes ``ingress`` / ``egress`` combined
+  with ``transfer``. See items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT``.
+
 * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
   removed. Its usages have been replaced by a new function
   ``rte_kvargs_get_with_value()``.
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index afd50d6d51..9e0adf7302 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -67,7 +67,10 @@ extern "C" {
  * Note that support for more than a single group and priority level is not
  * guaranteed.
  *
- * Flow rules can apply to inbound and/or outbound traffic (ingress/egress).
+ * At vNIC / ethdev level, flow rules can apply to inbound and / or outbound
+ * traffic (ingress / egress), with respect to the vNIC / ethdev in question.
+ * At embedded switch level, flow rules apply to all traffic seen by it
+ * unless fitting meta items are used to set concrete traffic source(s).
  *
  * Several pattern items and actions are valid and can be used in both
  * directions. Those valid for only one direction are described as such.
@@ -80,8 +83,32 @@ extern "C" {
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
 	uint32_t priority; /**< Rule priority level within group. */
-	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
-	uint32_t egress:1; /**< Rule applies to egress traffic. */
+	/**
+	 * The rule in question applies to ingress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic going from within the embedded switch toward the
+	 * ethdev the flow rule being created through. This behaviour
+	 * is deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t ingress:1;
+	/**
+	 * The rule in question applies to egress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic sent by the application by virtue of the ethdev
+	 * the flow rule being created through. This behaviour is now
+	 * deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t egress:1;
 	/**
 	 * Instead of simply matching the properties of traffic as it would
 	 * appear on a given DPDK port ID, enabling this attribute transfers
@@ -93,12 +120,8 @@ struct rte_flow_attr {
 	 * from or addressed to different physical ports, VFs or
 	 * applications) at the device level.
 	 *
-	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
-	 *
-	 * When transferring flow rules, ingress and egress attributes keep
-	 * their original meaning, as if processing traffic emitted or
-	 * received by the application.
+	 * The application should match traffic originating from precise
+	 * locations. See items PORT_REPRESENTOR and REPRESENTED_PORT.
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 07/12] net/bnxt: support meta flow items to match on traffic source
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (5 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 08/12] net/bnxt: support meta flow actions to overrule destinations Ivan Malov
                       ` (6 subsequent siblings)
  13 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for items PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for item PORT_ID.

The use of item PORT_ID depends on the specified direction attribute.
Items PORT_REPRESENTOR and REPRESENTED_PORT, in turn, define traffic
direction themselves. The former matches traffic from the driver's
vNIC. The latter matches packets from either a v-port (network) or
a VF's vNIC (if the driver's port is a VF representor).

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 10 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 77 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 3 files changed, 70 insertions(+), 23 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index 9b165c12b5..d28dd2e587 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -266,7 +266,7 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	},
 	[RTE_FLOW_ITEM_TYPE_PORT_ID] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
-	.proto_hdr_func          = ulp_rte_port_id_hdr_handler
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	},
 	[RTE_FLOW_ITEM_TYPE_RAW] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
@@ -427,6 +427,14 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	[RTE_FLOW_ITEM_TYPE_HIGIG2] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
 	.proto_hdr_func          = NULL
+	},
+	[RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
+	},
+	[RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	}
 };
 
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 3a9c9bba27..e1ea8932b0 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -400,7 +400,8 @@ bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
 static int32_t
 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 			uint32_t ifindex,
-			uint16_t mask)
+			uint16_t mask,
+			enum bnxt_ulp_direction_type item_dir)
 {
 	uint16_t svif;
 	enum bnxt_ulp_direction_type dir;
@@ -429,11 +430,14 @@ ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 	bnxt_ulp_rte_parser_direction_compute(params);
 
 	/* Get the computed direction */
-	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_INGRESS) {
+	dir = (item_dir != BNXT_ULP_DIR_INVALID) ? item_dir :
+		ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
+	if (dir == BNXT_ULP_DIR_INGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
 	} else {
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
+		    item_dir != BNXT_ULP_DIR_EGRESS)
 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
 		else
 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
@@ -474,7 +478,8 @@ ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
 	}
 
 	/* Update the SVIF details */
-	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				     BNXT_ULP_DIR_INVALID);
 	return rc;
 }
 
@@ -522,7 +527,8 @@ ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
 	}
 
 	/* Update the SVIF details */
-	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	return ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow item VF Header. */
@@ -555,39 +561,72 @@ ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow item port id  Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params)
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params)
 {
-	const struct rte_flow_item_port_id *port_spec = item->spec;
-	const struct rte_flow_item_port_id *port_mask = item->mask;
+	enum bnxt_ulp_direction_type item_dir;
+	uint16_t ethdev_id;
 	uint16_t mask = 0;
 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
 	uint32_t ifindex;
 
-	if (!port_spec) {
-		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
+	if (!item->spec) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port spec is not valid\n");
 		return rc;
 	}
-	if (!port_mask) {
-		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
+	if (!item->mask) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port mask is not valid\n");
+		return rc;
+	}
+
+	switch (item->type) {
+	case RTE_FLOW_ITEM_TYPE_PORT_ID: {
+		const struct rte_flow_item_port_id *port_spec = item->spec;
+		const struct rte_flow_item_port_id *port_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INVALID;
+		ethdev_id = port_spec->id;
+		mask = port_mask->id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_EGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "ParseErr:Unexpected item\n");
 		return rc;
 	}
-	mask = port_mask->id;
 
 	/* perform the conversion from dpdk port to bnxt ifindex */
 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
-					      port_spec->id,
+					      ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask, item_dir);
 }
 
 /* Function to handle the parsing of RTE Flow item phy port Header. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e14f86278a..0acb93946b 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -90,10 +90,10 @@ int32_t
 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow item port id Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow item port Header. */
 int32_t
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 08/12] net/bnxt: support meta flow actions to overrule destinations
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (6 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 09/12] net/enic: " Ivan Malov
                       ` (5 subsequent siblings)
  13 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for action PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 12 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 84 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index d28dd2e587..e9337ecd2c 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -67,7 +67,7 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	},
 	[RTE_FLOW_ACTION_TYPE_PORT_ID] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
-	.proto_act_func          = ulp_rte_port_id_act_handler
+	.proto_act_func          = ulp_rte_port_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_METER] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
@@ -212,7 +212,15 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	[RTE_FLOW_ACTION_TYPE_SAMPLE] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
 	.proto_act_func          = ulp_rte_sample_act_handler
-	}
+	},
+	[RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
+	[RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
 };
 
 struct bnxt_ulp_rte_act_info ulp_vendor_act_info[] = {
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index e1ea8932b0..f0e218d8ec 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -496,10 +496,11 @@ ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
 		return BNXT_TF_RC_SUCCESS;
 	}
 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
+	action_item.type = RTE_FLOW_ACTION_TYPE_PORT_ID;
 	action_item.conf = &port_id;
 
 	/* Update the action port based on incoming port */
-	ulp_rte_port_id_act_handler(&action_item, params);
+	ulp_rte_port_act_handler(&action_item, params);
 
 	/* Reset the action port set bit */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
@@ -2168,7 +2169,8 @@ ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
 /* Function to handle the parsing of action ports. */
 static int32_t
 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
-			    uint32_t ifindex)
+			    uint32_t ifindex,
+			    enum bnxt_ulp_direction_type act_dir)
 {
 	enum bnxt_ulp_direction_type dir;
 	uint16_t pid_s;
@@ -2178,8 +2180,13 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 	uint32_t vnic_type;
 
 	/* Get the direction */
-	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_EGRESS) {
+	/* If action implicitly specifies direction, use the specification. */
+	dir = (act_dir == BNXT_ULP_DIR_INVALID) ?
+		ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION) :
+		act_dir;
+	port_type = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
+	if (dir == BNXT_ULP_DIR_EGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		/* For egress direction, fill vport */
 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
 			return BNXT_TF_RC_ERROR;
@@ -2190,9 +2197,17 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
 	} else {
 		/* For ingress direction, fill vnic */
-		port_type = ULP_COMP_FLD_IDX_RD(param,
-						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		/*
+		 * Action		Destination
+		 * ------------------------------------
+		 * PORT_REPRESENTOR	Driver Function
+		 * ------------------------------------
+		 * REPRESENTED_PORT	VF
+		 * ------------------------------------
+		 * PORT_ID		VF
+		 */
+		if (act_dir != BNXT_ULP_DIR_INGRESS &&
+		    port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
 		else
 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
@@ -2239,7 +2254,8 @@ ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
 	}
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow action VF. */
@@ -2290,31 +2306,59 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/* Parse actions PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *param)
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *param)
 {
-	const struct rte_flow_action_port_id *port_id = act_item->conf;
+	uint32_t ethdev_id;
 	uint32_t ifindex;
 	enum bnxt_ulp_intf_type intf_type;
+	enum bnxt_ulp_direction_type act_dir;
 
-	if (!port_id) {
+	if (!act_item->conf) {
 		BNXT_TF_DBG(ERR,
 			    "ParseErr: Invalid Argument\n");
 		return BNXT_TF_RC_PARSE_ERR;
 	}
-	if (port_id->original) {
-		BNXT_TF_DBG(ERR,
-			    "ParseErr:Portid Original not supported\n");
-		return BNXT_TF_RC_PARSE_ERR;
+	switch (act_item->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *port_id = act_item->conf;
+
+		if (port_id->original) {
+			BNXT_TF_DBG(ERR,
+				    "ParseErr:Portid Original not supported\n");
+			return BNXT_TF_RC_PARSE_ERR;
+		}
+		ethdev_id = port_id->id;
+		act_dir = BNXT_ULP_DIR_INVALID;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->port_id;
+		act_dir = BNXT_ULP_DIR_INGRESS;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_action_ethdev *ethdev = act_item->conf;
+
+		ethdev_id = ethdev->port_id;
+		act_dir = BNXT_ULP_DIR_EGRESS;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "Unknown port action\n");
+		return BNXT_TF_RC_ERROR;
 	}
 
 	/* Get the port db ifindex */
-	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, port_id->id,
+	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "Invalid port id\n");
 		return BNXT_TF_RC_ERROR;
@@ -2329,7 +2373,7 @@ ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
 
 	/* Set the action port */
 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(param, ifindex);
+	return ulp_rte_parser_act_port_set(param, ifindex, act_dir);
 }
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index 0acb93946b..e4225d00f8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -204,10 +204,10 @@ int32_t
 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/* Parse actions PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow action phy_port. */
 int32_t
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 09/12] net/enic: support meta flow actions to overrule destinations
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (7 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 08/12] net/bnxt: support meta flow actions to overrule destinations Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-12 17:03       ` Hyong Youb Kim (hyonkim)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 10/12] net/mlx5: support represented port flow action Ivan Malov
                       ` (4 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, John Daley, Hyong Youb Kim

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for action PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 drivers/net/enic/enic_fm_flow.c | 93 ++++++++++++++++++++++++++-------
 1 file changed, 75 insertions(+), 18 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index cd364ee16b..4092ff1f61 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1242,6 +1242,35 @@ vf_egress_port_id_action(struct enic_flowman *fm,
 	return 0;
 }
 
+static int
+enic_fm_check_transfer_dst(struct enic *enic, uint16_t dst_port_id,
+			   struct rte_eth_dev **dst_dev,
+			   struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev;
+
+	ENICPMD_LOG(DEBUG, "port id %u", dst_port_id);
+	if (!rte_eth_dev_is_valid_port(dst_port_id)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "invalid port_id");
+	}
+	dev = &rte_eth_devices[dst_port_id];
+	if (!dev_is_enic(dev)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "port_id is not enic");
+	}
+	if (enic->switch_domain_id != pmd_priv(dev)->switch_domain_id) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "destination and source ports are not in the same switch domain");
+	}
+
+	*dst_dev = dev;
+	return 0;
+}
+
 /* Translate flow actions to flowman TCAM entry actions */
 static int
 enic_fm_copy_action(struct enic_flowman *fm,
@@ -1446,24 +1475,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
 				vnic_h = enic->fm_vnic_handle; /* This port */
 				break;
 			}
-			ENICPMD_LOG(DEBUG, "port id %u", port->id);
-			if (!rte_eth_dev_is_valid_port(port->id)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "invalid port_id");
-			}
-			dev = &rte_eth_devices[port->id];
-			if (!dev_is_enic(dev)) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "port_id is not enic");
-			}
-			if (enic->switch_domain_id !=
-			    pmd_priv(dev)->switch_domain_id) {
-				return rte_flow_error_set(error, EINVAL,
-					RTE_FLOW_ERROR_TYPE_ACTION,
-					NULL, "destination and source ports are not in the same switch domain");
-			}
+			ret = enic_fm_check_transfer_dst(enic, port->id, &dev,
+							 error);
+			if (ret)
+				return ret;
 			vnic_h = pmd_priv(dev)->fm_vnic_handle;
 			overlap |= PORT_ID;
 			/*
@@ -1560,6 +1575,48 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			ovlan |= rte_be_to_cpu_16(vid->vlan_vid);
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->port_id,
+							 &dev, error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/*
+			 * Action PORT_REPRESENTOR implies ingress destination.
+			 * Noting to do. We add an implicit stree at the
+			 * end if needed.
+			 */
+			ingress = 1;
+			break;
+		}
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+			const struct rte_flow_action_ethdev *ethdev;
+			struct rte_eth_dev *dev;
+
+			if (overlap & PORT_ID) {
+				ENICPMD_LOG(DEBUG, "cannot have multiple egress PORT_ID actions");
+				goto unsupported;
+			}
+			ethdev = actions->conf;
+			ret = enic_fm_check_transfer_dst(enic, ethdev->port_id,
+							 &dev, error);
+			if (ret)
+				return ret;
+			vnic_h = pmd_priv(dev)->fm_vnic_handle;
+			overlap |= PORT_ID;
+			/* Action REPRESENTED_PORT: always egress destination */
+			ingress = 0;
+			ret = vf_egress_port_id_action(fm, dev, vnic_h, &fm_op,
+				error);
+			if (ret)
+				return ret;
+			break;
+		}
 		default:
 			goto unsupported;
 		}
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 10/12] net/mlx5: support represented port flow action
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (8 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 09/12] net/enic: " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-12 21:23       ` Slava Ovsiienko
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 11/12] net/octeontx2: support port representor " Ivan Malov
                       ` (3 subsequent siblings)
  13 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Matan Azrad,
	Viacheslav Ovsiienko

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Semantics of the existing support for action PORT_ID suggests
that support for equal action REPRESENTED_PORT be implemented.

Helper functions keep port_id suffix since action
MLX5_FLOW_ACTION_PORT_ID is still used internally.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/mlx5.rst        |  4 +--
 drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++-------
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index bae73f42d8..b76e979f47 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -431,8 +431,8 @@ Limitations
      - yellow: NULL or END.
      - RED: DROP / END.
   - The only supported meter policy actions:
-     - green: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
-     - yellow: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
+     - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
+     - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
      - RED: must be DROP.
   - Policy actions of RSS for green and yellow should have the same configuration except queues.
   - meter profile packet mode is supported.
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index c6370cd1d6..835cc5018c 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -5048,14 +5048,14 @@ flow_dv_validate_action_jump(struct rte_eth_dev *dev,
 }
 
 /*
- * Validate the port_id action.
+ * Validate action PORT_ID / REPRESENTED_PORT.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action_flags
  *   Bit-fields that holds the actions detected until now.
  * @param[in] action
- *   Port_id RTE action structure.
+ *   PORT_ID / REPRESENTED_PORT action structure.
  * @param[in] attr
  *   Attributes of flow that includes this action.
  * @param[out] error
@@ -5072,6 +5072,7 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 				struct rte_flow_error *error)
 {
 	const struct rte_flow_action_port_id *port_id;
+	const struct rte_flow_action_ethdev *ethdev;
 	struct mlx5_priv *act_priv;
 	struct mlx5_priv *dev_priv;
 	uint16_t port;
@@ -5080,13 +5081,13 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
-					  "port id action is valid in transfer"
+					  "port action is valid in transfer"
 					  " mode only");
 	if (!action || !action->conf)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  NULL,
-					  "port id action parameters must be"
+					  "port action parameters must be"
 					  " specified");
 	if (action_flags & (MLX5_FLOW_FATE_ACTIONS |
 			    MLX5_FLOW_FATE_ESWITCH_ACTIONS))
@@ -5100,13 +5101,26 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
 					  "failed to obtain E-Switch info");
-	port_id = action->conf;
-	port = port_id->original ? dev->data->port_id : port_id->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		port_id = action->conf;
+		port = port_id->original ? dev->data->port_id : port_id->id;
+		break;
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
+		ethdev = action->conf;
+		port = ethdev->port_id;
+		break;
+	default:
+		return rte_flow_error_set
+				(error, EINVAL,
+				 RTE_FLOW_ERROR_TYPE_ACTION, action,
+				 "unknown E-Switch action");
+	}
 	act_priv = mlx5_port_to_eswitch_info(port, false);
 	if (!act_priv)
 		return rte_flow_error_set
 				(error, rte_errno,
-				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, port_id,
+				 RTE_FLOW_ERROR_TYPE_ACTION_CONF, action->conf,
 				 "failed to obtain E-Switch port id for port");
 	if (act_priv->domain_id != dev_priv->domain_id)
 		return rte_flow_error_set
@@ -5669,6 +5683,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 			++actions_n;
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      sub_action_flags,
 							      act,
@@ -7296,6 +7311,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			ret = flow_dv_validate_action_port_id(dev,
 							      action_flags,
 							      actions,
@@ -10770,12 +10786,12 @@ flow_dv_tag_release(struct rte_eth_dev *dev,
 }
 
 /**
- * Translate port ID action to vport.
+ * Translate action PORT_ID / REPRESENTED_PORT to vport.
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to the port ID action.
+ *   Pointer to action PORT_ID / REPRESENTED_PORT.
  * @param[out] dst_port_id
  *   The target port ID.
  * @param[out] error
@@ -10792,10 +10808,28 @@ flow_dv_translate_action_port_id(struct rte_eth_dev *dev,
 {
 	uint32_t port;
 	struct mlx5_priv *priv;
-	const struct rte_flow_action_port_id *conf =
-			(const struct rte_flow_action_port_id *)action->conf;
 
-	port = conf->original ? dev->data->port_id : conf->id;
+	switch (action->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *conf;
+
+		conf = (const struct rte_flow_action_port_id *)action->conf;
+		port = conf->original ? dev->data->port_id : conf->id;
+		break;
+	}
+	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_action_ethdev *ethdev;
+
+		ethdev = (const struct rte_flow_action_ethdev *)action->conf;
+		port = ethdev->port_id;
+		break;
+	}
+	default:
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, action,
+					  "unknown E-Switch action");
+	}
+
 	priv = mlx5_port_to_eswitch_info(port, false);
 	if (!priv)
 		return rte_flow_error_set(error, -rte_errno,
@@ -11634,6 +11668,7 @@ flow_dv_translate_action_sample(struct rte_eth_dev *dev,
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 		{
 			struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -12714,6 +12749,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ACTION_TYPE_VOID:
 			break;
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			if (flow_dv_translate_action_port_id(dev, action,
 							     &port_id, error))
 				return -rte_errno;
@@ -15475,6 +15511,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 				break;
 			}
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 			{
 				struct mlx5_flow_dv_port_id_action_resource
 					port_id_resource;
@@ -17683,6 +17720,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 					  NULL, "too many actions");
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 				if (!priv->config.dv_esw_en)
 					return -rte_mtr_error_set(error,
 					ENOTSUP,
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 11/12] net/octeontx2: support port representor flow action
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (9 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 10/12] net/mlx5: support represented port flow action Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 12/12] net/sfc: support port representor flow item Ivan Malov
                       ` (2 subsequent siblings)
  13 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, Jerin Jacob,
	Nithin Dabilpuram, Kiran Kumar K

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Action PORT_ID implementation assumes ingress only. Its semantics
suggests that support for equal action PORT_REPRESENTOR be added.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/octeontx2.rst           |  5 ++++-
 drivers/net/octeontx2/otx2_flow_parse.c | 16 ++++++++++++----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/octeontx2.rst b/doc/guides/nics/octeontx2.rst
index e35c8116f7..eae32f0afe 100644
--- a/doc/guides/nics/octeontx2.rst
+++ b/doc/guides/nics/octeontx2.rst
@@ -403,10 +403,13 @@ Actions:
    +----+-----------------------------------------+
    | 12 | RTE_FLOW_ACTION_TYPE_PORT_ID            |
    +----+-----------------------------------------+
+   | 13 | RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR   |
+   +----+-----------------------------------------+
 
 .. note::
 
-   ``RTE_FLOW_ACTION_TYPE_PORT_ID`` is only supported between PF and its VFs.
+   ``RTE_FLOW_ACTION_TYPE_PORT_ID``, ``RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR``
+   are only supported between PF and its VFs.
 
 .. _table_octeontx2_supported_egress_action_types:
 
diff --git a/drivers/net/octeontx2/otx2_flow_parse.c b/drivers/net/octeontx2/otx2_flow_parse.c
index 63a33142a5..890c6d0719 100644
--- a/drivers/net/octeontx2/otx2_flow_parse.c
+++ b/drivers/net/octeontx2/otx2_flow_parse.c
@@ -900,7 +900,6 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 {
 	struct otx2_eth_dev *hw = dev->data->dev_private;
 	struct otx2_npc_flow_info *npc = &hw->npc_flow;
-	const struct rte_flow_action_port_id *port_act;
 	const struct rte_flow_action_count *act_count;
 	const struct rte_flow_action_mark *act_mark;
 	const struct rte_flow_action_queue *act_q;
@@ -987,9 +986,18 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 			break;
 
 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
-			port_act = (const struct rte_flow_action_port_id *)
-				actions->conf;
-			port_id = port_act->id;
+		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+			if (actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
+				const struct rte_flow_action_port_id *port_act;
+
+				port_act = actions->conf;
+				port_id = port_act->id;
+			} else {
+				const struct rte_flow_action_ethdev *ethdev_act;
+
+				ethdev_act = actions->conf;
+				port_id = ethdev_act->port_id;
+			}
 			if (rte_eth_dev_get_name_by_port(port_id, if_name)) {
 				errmsg = "Name not found for output port id";
 				errcode = EINVAL;
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 12/12] net/sfc: support port representor flow item
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (10 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 11/12] net/octeontx2: support port representor " Ivan Malov
@ 2021-10-10 14:39     ` Ivan Malov
  2021-10-12 14:45     ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ferruh Yigit
  2021-10-13 11:51     ` Ferruh Yigit
  13 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 14:39 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for item PORT_REPRESENTOR which should
be used instead of ambiguous item PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/sfc_efx.rst |  2 ++
 drivers/net/sfc/sfc_mae.c   | 72 +++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 163bc2533f..9a9710325f 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -190,6 +190,8 @@ Supported actions (***non-transfer*** rules):
 
 Supported pattern items (***transfer*** rules):
 
+- PORT_REPRESENTOR (cannot repeat; conflicts with other traffic source items)
+
 - PORT_ID (cannot repeat; conflicts with other traffic source items)
 
 - PHY_PORT (cannot repeat; conflicts with other traffic source items)
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 4b520bc619..392f6ec098 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -1100,6 +1100,66 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
 	return 0;
 }
 
+static int
+sfc_mae_rule_parse_item_port_representor(const struct rte_flow_item *item,
+					 struct sfc_flow_parse_ctx *ctx,
+					 struct rte_flow_error *error)
+{
+	struct sfc_mae_parse_ctx *ctx_mae = ctx->mae;
+	const struct rte_flow_item_ethdev supp_mask = {
+		.port_id = 0xffff,
+	};
+	const void *def_mask = &rte_flow_item_ethdev_mask;
+	const struct rte_flow_item_ethdev *spec = NULL;
+	const struct rte_flow_item_ethdev *mask = NULL;
+	efx_mport_sel_t mport_sel;
+	int rc;
+
+	if (ctx_mae->match_mport_set) {
+		return rte_flow_error_set(error, ENOTSUP,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't handle multiple traffic source items");
+	}
+
+	rc = sfc_flow_parse_init(item,
+				 (const void **)&spec, (const void **)&mask,
+				 (const void *)&supp_mask, def_mask,
+				 sizeof(struct rte_flow_item_ethdev), error);
+	if (rc != 0)
+		return rc;
+
+	if (mask->port_id != supp_mask.port_id) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Bad mask in the PORT_REPRESENTOR pattern item");
+	}
+
+	/* If "spec" is not set, could be any port ID */
+	if (spec == NULL)
+		return 0;
+
+	rc = sfc_mae_switch_port_by_ethdev(
+			ctx_mae->sa->mae.switch_domain_id,
+			spec->port_id, &mport_sel);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Can't find RTE ethdev by the port ID");
+	}
+
+	rc = efx_mae_match_spec_mport_set(ctx_mae->match_spec,
+					  &mport_sel, NULL);
+	if (rc != 0) {
+		return rte_flow_error_set(error, rc,
+				RTE_FLOW_ERROR_TYPE_ITEM, item,
+				"Failed to set MPORT for the port ID");
+	}
+
+	ctx_mae->match_mport_set = B_TRUE;
+
+	return 0;
+}
+
 static int
 sfc_mae_rule_parse_item_phy_port(const struct rte_flow_item *item,
 				 struct sfc_flow_parse_ctx *ctx,
@@ -1995,6 +2055,18 @@ static const struct sfc_flow_item sfc_flow_items[] = {
 		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
 		.parse = sfc_mae_rule_parse_item_port_id,
 	},
+	{
+		.type = RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+		.name = "PORT_REPRESENTOR",
+		/*
+		 * In terms of RTE flow, this item is a META one,
+		 * and its position in the pattern is don't care.
+		 */
+		.prev_layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.layer = SFC_FLOW_ITEM_ANY_LAYER,
+		.ctx_type = SFC_FLOW_PARSE_CTX_MAE,
+		.parse = sfc_mae_rule_parse_item_port_representor,
+	},
 	{
 		.type = RTE_FLOW_ITEM_TYPE_PHY_PORT,
 		.name = "PHY_PORT",
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add port representor item to flow API
  2021-10-10 14:04           ` Ori Kam
@ 2021-10-10 15:02             ` Ivan Malov
  0 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-10 15:02 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ori,

On 10/10/2021 17:04, Ori Kam wrote:
> Hi Ivan.
> 
>> -----Original Message-----
>> From: Ivan Malov <Ivan.Malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 4:30 PM
>> Subject: Re: [PATCH v2 01/12] ethdev: add port representor item to flow API
>>
>> Hi Ori,
>>
>> Thanks a lot for reviewing this.
>>
>> On 10/10/2021 14:15, Ori Kam wrote:
>>> Hi Ivan,
>>>
>>> >From the new patches I saw you choose port_representor and
>>>> represented_port
>>> Didn't we agree to go with ETHDEV_PORT and SHADOW_PORT?
>>
>> Yes, in the previous thread I suggested a different option. But I gave it more thought and decided to go for
>> PORT_REPRESENTOR and REPRESENTED_PORT instead. In any case, I apologise for it being such short
>> notice.
>>
>>> The only thing that worries me is that the naming are very easy to get wrong.
>>> port_representor and represented_port.
>>
>> Is that so? In "port representor", the key word is "representor", a noun. In "represented port", the key
>> word is "port". Word "represented"
>> acts like an adjective. More to that, the order of words is chosen on purpose to prevent someone from
>> accidentally writing "representOR_port"
>> in their code, for example. That simply won't compile.
>>
>> Well, at least, these two are harder to get wrong compared to "employer"
>> and "employee", for example.
>>
>> The new names are better because they are paired terms. Each one suggests the existence of the other
>> one. This spares one from the need to have wordy explanations of the symmetry of the diagram.
>> The new names speak themselves.
>>
>> Saying "shadow" is in fact vague. The reader doesn't see clearly that it's the shadow of the ethdev. And, in
>> turn, "ethdev" is also not as good as "representor". It's even hard to pronounce because of being a
>> combination of multiple contractions.
>>
>> I hope you get the idea.
>>
> 
> I get the idea, since my English is not perfect from my view point those are a bit more confusing and easy
> to get wrong but I have no objection to keep them.

Please don't think me forward: my English is not any better. But I just
think that if English is the lingua franca in DPDK and in the community,
then the corresponding rules of the language are supposed to apply.

> Lets see what others will think about it.
> 
>>>
>>> Also there is an issue with wording if we assume like in previous
>>> thread that DPDK can have both the representor port and also the represented_port.
>>> While if we look at for example ethdev_port and shadow port are better
>>> defined as ethdev_port -> the port that is closest to the DPDK ethdev
>>> while shadow port is defined as the other side of the ethdev port.
>>>
>>> What do you think?
>>
>> The semantics hasn't changed since the previous thread.
>> Representor coincides with the ethdev, so it's still the closest port.
>> And represented port is still the other side. It's all the same in fact.
>>
>> If both VF and its representor are plugged to DPDK, they represent each other in fact. Mutual
>> representors. You can equally name the first one a representor and the other one a represented port, -
>> and vice versa.
>>
>> The new naming doesn't deny both these ports being ethdevs, while the previous option (ethdev and
>> shadow) may trick the reader into thinking that only one of the two can be an ethdev. The reader may
>> think that this use case (when VF and its representor are plugged to the application) is completely wrong.
>> Let's avoid this mistake.
>>
> 
> I agree those are semantics and there is no perfect world.
> I accept your case.

Thank you.

> 
>>>
>>>> -----Original Message-----
>>>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>> Sent: Sunday, October 10, 2021 3:05 AM
>>>> Subject: [PATCH v2 01/12] ethdev: add port representor item to flow
>>>> API ?
>>>> For use in "transfer" flows. Supposed to match traffic entering the
>>>> embedded switch from the given ethdev.
>>>
>>>
>>> I would also add a comment that says the since we are in transfer it
>>> means that all rules are located in the E-Switch which means that the
>>> matching is done on the source port of the traffic.
>>
>> Let me put it clear: I don't mind adding more comments. I can do that, yes. But look. You say "matching is
>> done on the source port". Isn't that what "entering the embedded switch FROM the given ethdev" already
>> says?
>>
> Yes,  the idea of this series is to clear everything.
> Do you think that someone who just read this commit log can without prior knowledge of RTE flow
> and transfer can fully understand the idea?

Well, the commit log is just an introduction to the diff itself. And,
in the diff, there is more commentary, diagrams, etc. Yes, of course,
I could have added some brief introduction to the commit log on what
RTE flow is and what "transfer" flows stand for, but I believe it's
already described in the existing documentation. However, I have no
strong opinion.

> 
> If so I'm, O.K. with leaving the comment as is.

I don't object changing it and probably I should do that in the next 
version should more reviewers indicate the same issue.

> 
> In most related comment about pharsing I'm giving my view point with all
> the comments I got about how much hard it is to create rules and understand the
> documentation.

I see.

> 
> Unless there is something wrong or misleading I can except most answers and comments,
> but I steel think that sometime it is worth saying them even if it is just for the developer to think
> again if something can be improved.

I'm just trying to use shorter comments in the code and commit logs as a 
starting point for being more concise. If necessary, I can extend that.

> 
>>>
>>> I think this will also help understand the view point that we are
>>> looking from the point of the switch, and to add the drawing.
>>
>> Well, as I said, technically, I don't object adding more comments. But the above description says: "entering
>> the embedded switch". Doesn't it indicate the viewpoint clear enough? Should I reword this?
>>
>> Also, "flow engine" is showed in the diagram. And there are arrows.
>> Doesn't that explain the viewpoint fully?
>>
>> I'm ready to discuss / improve.
> 
> Yes, but I was thinking about also adding it in the commit log.

I see. In the new version I improve the diagram as suggested. Maybe that
makes the concept clearer. But I keep in mind improving my commit logs.

> 
>>
>>>
>>>>
>>>> Must not be combined with direction attributes.
>>>>
>>>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>>>> ---
>>>>    app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
>>>>    doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
>>>>    doc/guides/rel_notes/release_21_11.rst      |  2 +
>>>>    doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
>>>>    lib/ethdev/rte_flow.c                       |  1 +
>>>>    lib/ethdev/rte_flow.h                       | 27 ++++++++++
>>>>    6 files changed, 120 insertions(+)
>>>>
>>>> diff --git a/app/test-pmd/cmdline_flow.c
>>>> b/app/test-pmd/cmdline_flow.c index
>>>> bb22294dd3..a912a8d815 100644
>>>> --- a/app/test-pmd/cmdline_flow.c
>>>> +++ b/app/test-pmd/cmdline_flow.c
>>>> @@ -306,6 +306,8 @@ enum index {
>>>>    	ITEM_POL_PORT,
>>>>    	ITEM_POL_METER,
>>>>    	ITEM_POL_POLICY,
>>>> +	ITEM_PORT_REPRESENTOR,
>>>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>>>>
>>>>    	/* Validate/create actions. */
>>>>    	ACTIONS,
>>>> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
>>>>    	ITEM_GENEVE_OPT,
>>>>    	ITEM_INTEGRITY,
>>>>    	ITEM_CONNTRACK,
>>>> +	ITEM_PORT_REPRESENTOR,
>>>>    	END_SET,
>>>>    	ZERO,
>>>>    };
>>>> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
>>>>    	ZERO,
>>>>    };
>>>>
>>>> +static const enum index item_port_representor[] = {
>>>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>>>> +	ITEM_NEXT,
>>>> +	ZERO,
>>>> +};
>>>> +
>>>>    static const enum index next_action[] = {
>>>>    	ACTION_END,
>>>>    	ACTION_VOID,
>>>> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
>>>>    			     item_param),
>>>>    		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
>>>>    	},
>>>> +	[ITEM_PORT_REPRESENTOR] = {
>>>> +		.name = "port_representor",
>>>> +		.help = "match traffic entering the embedded switch from the
>>>> given ethdev",
>>>> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
>>>> +				  sizeof(struct rte_flow_item_ethdev)),
>>>> +		.next = NEXT(item_port_representor),
>>>> +		.call = parse_vc,
>>>> +	},
>>>> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
>>>> +		.name = "port_id",
>>>> +		.help = "ethdev port ID",
>>>> +		.next = NEXT(item_port_representor,
>>>> NEXT_ENTRY(COMMON_UNSIGNED),
>>>> +			     item_param),
>>>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>>>> port_id)),
>>>> +	},
>>>>    	/* Validate/create actions. */
>>>>    	[ACTIONS] = {
>>>>    		.name = "actions",
>>>> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct
>>>> rte_flow_item
>>>> *item)
>>>>    	case RTE_FLOW_ITEM_TYPE_PFCP:
>>>>    		mask = &rte_flow_item_pfcp_mask;
>>>>    		break;
>>>> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
>>>> +		mask = &rte_flow_item_ethdev_mask;
>>>> +		break;
>>>>    	default:
>>>>    		break;
>>>>    	}
>>>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>>>> b/doc/guides/prog_guide/rte_flow.rst
>>>> index 2b42d5ec8c..2e0f590777 100644
>>>> --- a/doc/guides/prog_guide/rte_flow.rst
>>>> +++ b/doc/guides/prog_guide/rte_flow.rst
>>>> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
>>>>    - ``flags``: conntrack packet state flags.
>>>>    - Default ``mask`` matches all state bits.
>>>>
>>>> +Item: ``PORT_REPRESENTOR``
>>>> +^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> +
>>>> +Matches traffic entering the embedded switch from the given ethdev.
>>>> +
>>>> +Term **ethdev** and the concept of **port representor** are synonymous.
>>>> +The **represented port** is an *entity* plugged to the embedded
>>>> +switch at the opposite end of the "wire" leading to the ethdev.
>>>> +
>>>> +::
>>>> +
>>>> +    .------------------------.
>>>> +    |    PORT_REPRESENTOR    |  Ethdev (Application Port Referred to by its ID)
>>>> +    '------------------------'
>>>> +                ||
>>>> +                \/
>>>> +    .------------------------.
>>>> +    |  Embedded Switch Port  |  Logical Port
>>>> +    '------------------------'
>>>> +                ||
>>>> +                ||
>>>> +                ||
>>>> +                \/
>>>> +    .------------------------.
>>>> +    |  Embedded Flow Engine  |
>>>> +    '------------------------'
>>>> +                :
>>>> +                 :
>>>> +                :
>>>> +                 :
>>>> +    .------------------------.
>>>> +    |  Embedded Switch Port  |  Logical Port
>>>> +    '------------------------'
>>>> +                :
>>>> +                 :
>>>> +    .------------------------.
>>>> +    |    REPRESENTED_PORT    |  Net / Guest / Another Ethdev (Same
>>>> Application)
>>>> +    '------------------------'
>>>> +
>>>> +
>>>
>>> I think this drawing is harder to understand than the one you draw in
>>> the previous thread (A-> ethdev, b-> embedded switch, switch , c-> embedded switch, d -> represented
>> entity (shadow port).
>>
>> Is that so? Here's the previous drawing:
>>
>>
>>        [ A ]       <-- ethdev
>>          |
>>        [ B ]       <-- embedded switch (logical) port
>>          |
>>          |
>>          |
>> ===============  <-- plane of symmetry
>>          |
>>          |
>>          |
>>        [ C ]       <-- embedded switch (logical) port
>>          |
>>        [ D ]       <-- represented entity
>>
>>
>> Technically, these two are exactly the same. Yes, I use precise names instead of letters (A, B, C, D) and
>> more formatting, but that should help, not confuse.
>>
>> And, as I say, in the new one, I don't have to use complex terms like "plane of symmetry". The names
>> speak for it themselves.
>>
> 
> That was what I was missing and the only difference between the two,
> Th plane of symmetry (I'm not sure I like this name) but it is much cleared them embedded engine.
> Embedded engine has meaning for me which is very different.
> maybe just replace it with  switch? Or Embedded switch?

Agreed. Please see the new (v3) version. I improved the diagrams.
Do they look clearer now? I'm ready to discuss.

>   
>>>
>>>> +- Incompatibe with `Attribute: Traffic direction`_.
>>>> +- Requires `Attribute: Transfer`_.
>>>> +
>>>> +.. _table_rte_flow_item_ethdev:
>>>> +
>>>> +.. table:: ``struct rte_flow_item_ethdev``
>>>> +
>>>> +   +----------+-------------+---------------------------+
>>>> +   | Field    | Subfield    | Value                     |
>>>> +   +==========+=============+===========================+
>>>> +   | ``spec`` | ``port_id`` | ethdev port ID            |
>>>> +   +----------+-------------+---------------------------+
>>>> +   | ``last`` | ``port_id`` | upper range value         |
>>>> +   +----------+-------------+---------------------------+
>>>> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
>>>> +   +----------+-------------+---------------------------+
>>>> +
>>>> +- Default ``mask`` provides exact match behaviour.
>>>> +
>>>>    Actions
>>>>    ~~~~~~~
>>>>
>>>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>>>> b/doc/guides/rel_notes/release_21_11.rst
>>>> index 89d4b33ef1..1261cb2bf3 100644
>>>> --- a/doc/guides/rel_notes/release_21_11.rst
>>>> +++ b/doc/guides/rel_notes/release_21_11.rst
>>>> @@ -188,6 +188,8 @@ API Changes
>>>>       Also, make sure to start the actual text at the margin.
>>>>       =======================================================
>>>>
>>>> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
>>>> +
>>>>    * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
>>>>      removed. Its usages have been replaced by a new function
>>>>      ``rte_kvargs_get_with_value()``.
>>>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> index 8ead7a4a71..dcb9f47d98 100644
>>>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>>>> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and
>>>> their attributes, if any.
>>>>
>>>>    - ``conntrack``: match conntrack state.
>>>>
>>>> +- ``port_representor``: match traffic entering the embedded switch
>>>> +from the given ethdev
>>>> +
>>>> +  - ``port_id {unsigned}``: ethdev port ID
>>>> +
>>>>    Actions list
>>>>    ^^^^^^^^^^^^
>>>>
>>>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>>>> 8cb7a069c8..5e9317c6d1 100644
>>>> --- a/lib/ethdev/rte_flow.c
>>>> +++ b/lib/ethdev/rte_flow.c
>>>> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
>>>> rte_flow_desc_item[] = {
>>>>    	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
>>>>    	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>>>    	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>>>> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
>>>> rte_flow_item_ethdev)),
>>>>    };
>>>>
>>>>    /** Generate flow_action[] entry. */ diff --git
>>>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>>>> 7b1ed7f110..3625fd2c12 100644
>>>> --- a/lib/ethdev/rte_flow.h
>>>> +++ b/lib/ethdev/rte_flow.h
>>>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>>>    	 * @see struct rte_flow_item_conntrack.
>>>>    	 */
>>>>    	RTE_FLOW_ITEM_TYPE_CONNTRACK,
>>>> +
>>>> +	/**
>>>> +	 * [META]
>>>> +	 *
>>>> +	 * Matches traffic entering the embedded switch from the given ethdev.
>>>> +	 *
>>>> +	 * @see struct rte_flow_item_ethdev
>>>> +	 */
>>>> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
>>>>    };
>>>>
>>>>    /**
>>>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>>>> rte_flow_item_conntrack_mask = {  };  #endif
>>>>
>>>> +/**
>>>> + * @warning
>>>> + * @b EXPERIMENTAL: this structure may change without prior notice
>>>> + *
>>>> + * Provides an ethdev port ID for use with the following items:
>>>> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
>>>> + */
>>>> +struct rte_flow_item_ethdev {
>>>> +	uint16_t port_id; /**< ethdev port ID */ };
>>>> +
>>>> +/** Default mask for items based on struct rte_flow_item_ethdev */
>>>> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
>>>> +rte_flow_item_ethdev_mask = {
>>>> +	.port_id = 0xffff,
>>>> +};
>>>> +#endif
>>>> +
>>>>    /**
>>>>     * Matching pattern item definition.
>>>>     *
>>>> --
>>>> 2.20.1
>>
>> --
>> Ivan M
> 
> Best,
> Ori
> 

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
@ 2021-10-11 11:49       ` Ori Kam
  2021-10-12 12:39         ` Andrew Rybchenko
  2021-10-12 20:55       ` Slava Ovsiienko
  2021-10-13 11:52       ` Ferruh Yigit
  2 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 11:49 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> Subject: [PATCH v3 01/12] ethdev: add port representor item to flow API
> 
> For use in "transfer" flows. Supposed to match traffic entering the embedded switch from the given
> ethdev.
> 
> Must not be combined with direction attributes.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori


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

* Re: [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port item to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port " Ivan Malov
@ 2021-10-11 11:51       ` Ori Kam
  2021-10-12 12:39         ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 11:51 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> To: dev@dpdk.org
> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Ori Kam <orika@nvidia.com>; Xiaoyun Li
> <xiaoyun.li@intel.com>; Ferruh Yigit <ferruh.yigit@intel.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>
> Subject: [PATCH v3 02/12] ethdev: add represented port item to flow API
> 
> For use in "transfer" flows. Supposed to match traffic entering the embedded switch from the entity
> represented by the given ethdev.
> Such an entity can be a network (via a network port), a guest machine (via a VF) or another ethdev in the
> same application.
> 
> Must not be combined with direction attributes.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action " Ivan Malov
@ 2021-10-11 18:18       ` Ori Kam
  2021-10-12 12:39         ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 18:18 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> Subject: [PATCH v3 03/12] ethdev: add port representor action to flow API
> 
> For use in "transfer" flows. Supposed to send matching traffic to the given ethdev (to the application), at
> embedded switch level.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port action to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port " Ivan Malov
@ 2021-10-11 18:20       ` Ori Kam
  2021-10-12 12:40         ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 18:20 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit, Andrew Rybchenko

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> Subject: [PATCH v3 04/12] ethdev: add represented port action to flow API
> 
> For use in "transfer" flows. Supposed to send matching traffic to the entity represented by the given
> ethdev, at embedded switch level.
> Such an entity can be a network (via a network port), a guest machine (via a VF) or another ethdev in the
> same application.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
@ 2021-10-11 18:23       ` Ori Kam
  2021-10-12 12:40         ` Andrew Rybchenko
  2021-10-13 11:53       ` Ferruh Yigit
  1 sibling, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 18:23 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ray Kinsella, Ferruh Yigit,
	Andrew Rybchenko

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> Subject: [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
> 
> PF, VF and PHY_PORT require that applications have extra knowledge of the underlying NIC and thus are
> hard to use.
> Also, the corresponding items depend on the direction attribute (ingress / egress), which complicates their
> use in applications and interpretation in PMDs.
> 
> The concept of PORT_ID is ambiguous as it doesn't say whether the port in question is an ethdev or the
> represented entity.
> 
> Items and actions PORT_REPRESENTOR, REPRESENTED_PORT should be used instead.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
@ 2021-10-11 18:33       ` Ori Kam
  2021-10-12 12:40         ` Andrew Rybchenko
  0 siblings, 1 reply; 161+ messages in thread
From: Ori Kam @ 2021-10-11 18:33 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ray Kinsella, Ferruh Yigit,
	Andrew Rybchenko

Hi Ivan,

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 5:39 PM
> Subject: [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows
> 
> Attributes "ingress" and "egress" can only apply unambiguosly to non-"transfer" flows. In "transfer"
> flows, the standpoint is effectively shifted to the embedded switch. There can be many different endpoints
> connected to the switch, so the use of "ingress" / "egress" does not shed light on which endpoints precisely
> can be considered as traffic sources.
> 
> Add relevant deprecation notices and suggest the use of precise traffic source items (PORT_REPRESENTOR
> and REPRESENTED_PORT).
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori

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

* Re: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-11 11:49       ` Ori Kam
@ 2021-10-12 12:39         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:39 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit

On 10/11/21 2:49 PM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> Subject: [PATCH v3 01/12] ethdev: add port representor item to flow API
>>
>> For use in "transfer" flows. Supposed to match traffic entering the embedded switch from the given
>> ethdev.
>>
>> Must not be combined with direction attributes.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>




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

* Re: [dpdk-dev] [PATCH v3 02/12] ethdev: add represented port item to flow API
  2021-10-11 11:51       ` Ori Kam
@ 2021-10-12 12:39         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:39 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit

On 10/11/21 2:51 PM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> To: dev@dpdk.org
>> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Ori Kam <orika@nvidia.com>; Xiaoyun Li
>> <xiaoyun.li@intel.com>; Ferruh Yigit <ferruh.yigit@intel.com>; Andrew Rybchenko
>> <andrew.rybchenko@oktetlabs.ru>
>> Subject: [PATCH v3 02/12] ethdev: add represented port item to flow API
>>
>> For use in "transfer" flows. Supposed to match traffic entering the embedded switch from the entity
>> represented by the given ethdev.
>> Such an entity can be a network (via a network port), a guest machine (via a VF) or another ethdev in the
>> same application.
>>
>> Must not be combined with direction attributes.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 


Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


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

* Re: [dpdk-dev] [PATCH v3 03/12] ethdev: add port representor action to flow API
  2021-10-11 18:18       ` Ori Kam
@ 2021-10-12 12:39         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:39 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit

On 10/11/21 9:18 PM, Ori Kam wrote:
> Hi Ivan
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> Subject: [PATCH v3 03/12] ethdev: add port representor action to flow API
>>
>> For use in "transfer" flows. Supposed to send matching traffic to the given ethdev (to the application), at
>> embedded switch level.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 


Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


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

* Re: [dpdk-dev] [PATCH v3 04/12] ethdev: add represented port action to flow API
  2021-10-11 18:20       ` Ori Kam
@ 2021-10-12 12:40         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:40 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Xiaoyun Li, Ferruh Yigit

On 10/11/21 9:20 PM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> Subject: [PATCH v3 04/12] ethdev: add represented port action to flow API
>>
>> For use in "transfer" flows. Supposed to send matching traffic to the entity represented by the given
>> ethdev, at embedded switch level.
>> Such an entity can be a network (via a network port), a guest machine (via a VF) or another ethdev in the
>> same application.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 


Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


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

* Re: [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-11 18:23       ` Ori Kam
@ 2021-10-12 12:40         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:40 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ray Kinsella, Ferruh Yigit

On 10/11/21 9:23 PM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> Subject: [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
>>
>> PF, VF and PHY_PORT require that applications have extra knowledge of the underlying NIC and thus are
>> hard to use.
>> Also, the corresponding items depend on the direction attribute (ingress / egress), which complicates their
>> use in applications and interpretation in PMDs.
>>
>> The concept of PORT_ID is ambiguous as it doesn't say whether the port in question is an ethdev or the
>> represented entity.
>>
>> Items and actions PORT_REPRESENTOR, REPRESENTED_PORT should be used instead.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 


Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


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

* Re: [dpdk-dev] [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-11 18:33       ` Ori Kam
@ 2021-10-12 12:40         ` Andrew Rybchenko
  0 siblings, 0 replies; 161+ messages in thread
From: Andrew Rybchenko @ 2021-10-12 12:40 UTC (permalink / raw)
  To: Ori Kam, Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ray Kinsella, Ferruh Yigit

On 10/11/21 9:33 PM, Ori Kam wrote:
> Hi Ivan,
> 
>> -----Original Message-----
>> From: Ivan Malov <ivan.malov@oktetlabs.ru>
>> Sent: Sunday, October 10, 2021 5:39 PM
>> Subject: [PATCH v3 06/12] ethdev: deprecate direction attributes in transfer flows
>>
>> Attributes "ingress" and "egress" can only apply unambiguosly to non-"transfer" flows. In "transfer"
>> flows, the standpoint is effectively shifted to the embedded switch. There can be many different endpoints
>> connected to the switch, so the use of "ingress" / "egress" does not shed light on which endpoints precisely
>> can be considered as traffic sources.
>>
>> Add relevant deprecation notices and suggest the use of precise traffic source items (PORT_REPRESENTOR
>> and REPRESENTED_PORT).
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
> 
> Acked-by: Ori Kam <orika@nvidia.com>
> Thanks,
> Ori
> 


Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


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

* Re: [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (11 preceding siblings ...)
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 12/12] net/sfc: support port representor flow item Ivan Malov
@ 2021-10-12 14:45     ` Ferruh Yigit
  2021-10-13 11:51     ` Ferruh Yigit
  13 siblings, 0 replies; 161+ messages in thread
From: Ferruh Yigit @ 2021-10-12 14:45 UTC (permalink / raw)
  To: Ajit Khaparde, Somnath Kotur, John Daley, Hyong Youb Kim,
	Matan Azrad, Viacheslav Ovsiienko, Jerin Jacob,
	Nithin Dabilpuram, Kiran Kumar K
  Cc: Thomas Monjalon, Ori Kam, Ivan Malov, dev, Andrew Rybchenko

On 10/10/2021 3:39 PM, Ivan Malov wrote:
> As per RFC [1], action PORT_ID appears to be ambiguous. Its name suggests
> that matching traffic be sent to the ethdev with the specified ID, that
> is, to the application. However, in Open vSwitch, the action is used to
> send traffic to a remote entity represented by the given port, that is,
> in the opposite direction. Its interpretation across PMDs also varies.
> 
> RFC [2] attempted to define action PORT_ID semantics in vSwitch sense.
> However, this solution would completely abandon the opposite meaning.
> 
> One more effort, RFC [3], was meant to declare that the use of direction
> attributes in "transfer" flows assumed implicit filtering by the port ID
> appearing as the first argument in rte_flow_create(). However, not all
> PMDs require such filtering, so the RFC turned out rather disputable.
> 
> 
> Since then, all of that has been given more thought:
> 
> 1. One should not attempt to fix action PORT_ID. Instead, two new actions
>     should be introduced. The first one should send traffic to the given
>     ethdev. The second one should send it to the represented entity.
> 
> 2. Similar to (1), two new items should be defined. The first one should
>     match traffic going down from the given ethdev. The second one should
>     match traffic going up from the entity represented by that ethdev.
> 
> 3. The application always knows which packets come through which ethdevs.
>     So, as per (2), the application can use the new item to match traffic
>     arriving from precise entities represented by the relevant ethdev IDs.
> 
> 4. New items suggested in (2) do not require the use of direction
>     attributes. These items define precise directions on their own.
> 
> 5. As a consequence of (3) and (4), the problem of implicit filtering
>     by rte_flow_create() port ID argument and direction attributes is
>     no longer a blocker. The new items allow to dispose of it.
> 
> 
> The new items appear to be symmetrical to each other. So do the new
> actions. This requires that their names reflect the symmetry. Also,
> the names should respect the existing concept of port representors.
> By the looks of it, terms "PORT_REPRESENTOR" and "REPRESENTED_PORT"
> satisfy these requirements. However, currently, ethdevs associated
> with network ports are not considered as their representors. Such
> understanding is mentioned in the documentation, but it's not
> expressed in the code (see enum rte_eth_representor_type).
> 
> 
> The short of it, this patch series follows points (1-5) to rework
> support for "transfer" flows accordingly. On the way, a string of
> ambiguous pattern items (PF, VF, PHY_PORT) is deprecated.
> 
> The patch series also updates PMDs which support item and action PORT_ID
> to add support for replacements (1-2). However, there're some exceptions:
> 
>   - Support for traffic source items in the case of net/mlx5 is really
>     complicated. This series does not rework it. The PMD maintainer
>     can do the job much better and test the new code accordingly;
> 
>   - Support for action REPRESENTED_PORT is not added to net/sfc.
>     This will be done when support for VF representors has been
>     upstreamed, just for the new code to apply cleanly.
> 
> 
> Changes in v2:
> * New naming and reworked comments
> * New diagrams
> 
> Changes in v3:
> * Diagram improvements
> * Spelling fixes
> 
> [1] https://patches.dpdk.org/project/dpdk/patch/20210907125157.3843-1-ivan.malov@oktetlabs.ru/
> [2] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/
> [3] https://patches.dpdk.org/project/dpdk/patch/20210901151104.3923889-1-andrew.rybchenko@oktetlabs.ru/
> 
> Andrew Rybchenko (6):
>    net/bnxt: support meta flow items to match on traffic source
>    net/bnxt: support meta flow actions to overrule destinations
>    net/enic: support meta flow actions to overrule destinations
>    net/mlx5: support represented port flow action
>    net/octeontx2: support port representor flow action
>    net/sfc: support port representor flow item
> 
> Ivan Malov (6):
>    ethdev: add port representor item to flow API
>    ethdev: add represented port item to flow API
>    ethdev: add port representor action to flow API
>    ethdev: add represented port action to flow API
>    ethdev: deprecate hard-to-use or ambiguous items and actions
>    ethdev: deprecate direction attributes in transfer flows
> 

This set also updates the drivers, 'bnxt', 'enic', 'mlx5' & 'octeontx2',
PMD maintainers please review/ack the patches.

If there is no review from PMDs, patch will go in as it is, FYI.


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

* Re: [dpdk-dev] [PATCH v3 09/12] net/enic: support meta flow actions to overrule destinations
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 09/12] net/enic: " Ivan Malov
@ 2021-10-12 17:03       ` Hyong Youb Kim (hyonkim)
  0 siblings, 0 replies; 161+ messages in thread
From: Hyong Youb Kim (hyonkim) @ 2021-10-12 17:03 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: Thomas Monjalon, Ori Kam, Andrew Rybchenko, John Daley (johndale)

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 11:39 PM
> To: dev@dpdk.org
> Cc: Thomas Monjalon <thomas@monjalon.net>; Ori Kam
> <orika@nvidia.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; John Daley (johndale)
> <johndale@cisco.com>; Hyong Youb Kim (hyonkim) <hyonkim@cisco.com>
> Subject: [PATCH v3 09/12] net/enic: support meta flow actions to overrule
> destinations
> 
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
> Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
> based on the existing support for action PORT_ID.
> 
> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
>  drivers/net/enic/enic_fm_flow.c | 93 ++++++++++++++++++++++++++-----
> --
>  1 file changed, 75 insertions(+), 18 deletions(-)
> 

Looks good to me. Thanks a lot.

Acked-by: Hyong Youb Kim <hyonkim@cisco.com>

-Hyong

> diff --git a/drivers/net/enic/enic_fm_flow.c
> b/drivers/net/enic/enic_fm_flow.c
> index cd364ee16b..4092ff1f61 100644
> --- a/drivers/net/enic/enic_fm_flow.c
> +++ b/drivers/net/enic/enic_fm_flow.c
> @@ -1242,6 +1242,35 @@ vf_egress_port_id_action(struct enic_flowman
> *fm,
>  	return 0;
>  }
> 
> +static int
> +enic_fm_check_transfer_dst(struct enic *enic, uint16_t dst_port_id,
> +			   struct rte_eth_dev **dst_dev,
> +			   struct rte_flow_error *error)
> +{
> +	struct rte_eth_dev *dev;
> +
> +	ENICPMD_LOG(DEBUG, "port id %u", dst_port_id);
> +	if (!rte_eth_dev_is_valid_port(dst_port_id)) {
> +		return rte_flow_error_set(error, EINVAL,
> +			RTE_FLOW_ERROR_TYPE_ACTION,
> +			NULL, "invalid port_id");
> +	}
> +	dev = &rte_eth_devices[dst_port_id];
> +	if (!dev_is_enic(dev)) {
> +		return rte_flow_error_set(error, EINVAL,
> +			RTE_FLOW_ERROR_TYPE_ACTION,
> +			NULL, "port_id is not enic");
> +	}
> +	if (enic->switch_domain_id != pmd_priv(dev)->switch_domain_id) {
> +		return rte_flow_error_set(error, EINVAL,
> +			RTE_FLOW_ERROR_TYPE_ACTION,
> +			NULL, "destination and source ports are not in the
> same switch domain");
> +	}
> +
> +	*dst_dev = dev;
> +	return 0;
> +}
> +
>  /* Translate flow actions to flowman TCAM entry actions */
>  static int
>  enic_fm_copy_action(struct enic_flowman *fm,
> @@ -1446,24 +1475,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
>  				vnic_h = enic->fm_vnic_handle; /* This port
> */
>  				break;
>  			}
> -			ENICPMD_LOG(DEBUG, "port id %u", port->id);
> -			if (!rte_eth_dev_is_valid_port(port->id)) {
> -				return rte_flow_error_set(error, EINVAL,
> -					RTE_FLOW_ERROR_TYPE_ACTION,
> -					NULL, "invalid port_id");
> -			}
> -			dev = &rte_eth_devices[port->id];
> -			if (!dev_is_enic(dev)) {
> -				return rte_flow_error_set(error, EINVAL,
> -					RTE_FLOW_ERROR_TYPE_ACTION,
> -					NULL, "port_id is not enic");
> -			}
> -			if (enic->switch_domain_id !=
> -			    pmd_priv(dev)->switch_domain_id) {
> -				return rte_flow_error_set(error, EINVAL,
> -					RTE_FLOW_ERROR_TYPE_ACTION,
> -					NULL, "destination and source ports
> are not in the same switch domain");
> -			}
> +			ret = enic_fm_check_transfer_dst(enic, port->id,
> &dev,
> +							 error);
> +			if (ret)
> +				return ret;
>  			vnic_h = pmd_priv(dev)->fm_vnic_handle;
>  			overlap |= PORT_ID;
>  			/*
> @@ -1560,6 +1575,48 @@ enic_fm_copy_action(struct enic_flowman *fm,
>  			ovlan |= rte_be_to_cpu_16(vid->vlan_vid);
>  			break;
>  		}
> +		case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
> +			const struct rte_flow_action_ethdev *ethdev;
> +			struct rte_eth_dev *dev;
> +
> +			ethdev = actions->conf;
> +			ret = enic_fm_check_transfer_dst(enic, ethdev-
> >port_id,
> +							 &dev, error);
> +			if (ret)
> +				return ret;
> +			vnic_h = pmd_priv(dev)->fm_vnic_handle;
> +			overlap |= PORT_ID;
> +			/*
> +			 * Action PORT_REPRESENTOR implies ingress
> destination.
> +			 * Noting to do. We add an implicit stree at the
> +			 * end if needed.
> +			 */
> +			ingress = 1;
> +			break;
> +		}
> +		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
> +			const struct rte_flow_action_ethdev *ethdev;
> +			struct rte_eth_dev *dev;
> +
> +			if (overlap & PORT_ID) {
> +				ENICPMD_LOG(DEBUG, "cannot have
> multiple egress PORT_ID actions");
> +				goto unsupported;
> +			}
> +			ethdev = actions->conf;
> +			ret = enic_fm_check_transfer_dst(enic, ethdev-
> >port_id,
> +							 &dev, error);
> +			if (ret)
> +				return ret;
> +			vnic_h = pmd_priv(dev)->fm_vnic_handle;
> +			overlap |= PORT_ID;
> +			/* Action REPRESENTED_PORT: always egress
> destination */
> +			ingress = 0;
> +			ret = vf_egress_port_id_action(fm, dev, vnic_h,
> &fm_op,
> +				error);
> +			if (ret)
> +				return ret;
> +			break;
> +		}
>  		default:
>  			goto unsupported;
>  		}
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
  2021-10-11 11:49       ` Ori Kam
@ 2021-10-12 20:55       ` Slava Ovsiienko
  2021-10-12 23:14         ` Ivan Malov
  2021-10-13 11:52       ` Ferruh Yigit
  2 siblings, 1 reply; 161+ messages in thread
From: Slava Ovsiienko @ 2021-10-12 20:55 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit,
	Andrew Rybchenko

Hi,

Please, see below.

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Ivan Malov
> Sent: Sunday, October 10, 2021 17:39
> To: dev@dpdk.org
> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Ori Kam
> <orika@nvidia.com>; Xiaoyun Li <xiaoyun.li@intel.com>; Ferruh Yigit
> <ferruh.yigit@intel.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>
> Subject: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to
> flow API
> 
> For use in "transfer" flows. Supposed to match traffic entering the embedded
> switch from the given ethdev.
> 
> Must not be combined with direction attributes.
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---
>  app/test-pmd/cmdline_flow.c                 | 27 ++++++++++

Should we separate testpmd changes into dedicated commit?
This patch intermixes RTE Flow API update and testpmd.

With best regards,
Slava

>  doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
>  doc/guides/rel_notes/release_21_11.rst      |  2 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
>  lib/ethdev/rte_flow.c                       |  1 +
>  lib/ethdev/rte_flow.h                       | 27 ++++++++++
>  6 files changed, 120 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index bb22294dd3..a912a8d815 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -306,6 +306,8 @@ enum index {
>  	ITEM_POL_PORT,
>  	ITEM_POL_METER,
>  	ITEM_POL_POLICY,
> +	ITEM_PORT_REPRESENTOR,
> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
>  	ITEM_GENEVE_OPT,
>  	ITEM_INTEGRITY,
>  	ITEM_CONNTRACK,
> +	ITEM_PORT_REPRESENTOR,
>  	END_SET,
>  	ZERO,
>  };
> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_port_representor[] = {
> +	ITEM_PORT_REPRESENTOR_PORT_ID,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
>  			     item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack,
> flags)),
>  	},
> +	[ITEM_PORT_REPRESENTOR] = {
> +		.name = "port_representor",
> +		.help = "match traffic entering the embedded switch from the
> given ethdev",
> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
> +				  sizeof(struct rte_flow_item_ethdev)),
> +		.next = NEXT(item_port_representor),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
> +		.name = "port_id",
> +		.help = "ethdev port ID",
> +		.next = NEXT(item_port_representor,
> NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
> port_id)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct
> rte_flow_item *item)
>  	case RTE_FLOW_ITEM_TYPE_PFCP:
>  		mask = &rte_flow_item_pfcp_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
> +		mask = &rte_flow_item_ethdev_mask;
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index 2b42d5ec8c..91d5bdd712 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
>  - ``flags``: conntrack packet state flags.
>  - Default ``mask`` matches all state bits.
> 
> +Item: ``PORT_REPRESENTOR``
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches traffic entering the embedded switch from the given ethdev.
> +
> +Term **ethdev** and the concept of **port representor** are synonymous.
> +The **represented port** is an *entity* plugged to the embedded switch
> +at the opposite end of the "wire" leading to the ethdev.
> +
> +::
> +
> +    .--------------------.
> +    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
> +    '--------------------'
> +              ||
> +              \/
> +      .----------------.
> +      |  Logical Port  |
> +      '----------------'
> +              ||
> +              ||
> +              ||
> +              \/
> +         .----------.
> +         |  Switch  |
> +         '----------'
> +              :
> +               :
> +              :
> +               :
> +      .----------------.
> +      |  Logical Port  |
> +      '----------------'
> +              :
> +               :
> +    .--------------------.
> +    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same
> Application)
> +    '--------------------'
> +
> +
> +- Incompatible with `Attribute: Traffic direction`_.
> +- Requires `Attribute: Transfer`_.
> +
> +.. _table_rte_flow_item_ethdev:
> +
> +.. table:: ``struct rte_flow_item_ethdev``
> +
> +   +----------+-------------+---------------------------+
> +   | Field    | Subfield    | Value                     |
> +   +==========+=============+===========================+
> +   | ``spec`` | ``port_id`` | ethdev port ID            |
> +   +----------+-------------+---------------------------+
> +   | ``last`` | ``port_id`` | upper range value         |
> +   +----------+-------------+---------------------------+
> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
> +   +----------+-------------+---------------------------+
> +
> +- Default ``mask`` provides exact match behaviour.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 89d4b33ef1..1261cb2bf3 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -188,6 +188,8 @@ API Changes
>     Also, make sure to start the actual text at the margin.
>     =======================================================
> 
> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
> +
>  * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
>    removed. Its usages have been replaced by a new function
>    ``rte_kvargs_get_with_value()``.
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 8ead7a4a71..dcb9f47d98 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and
> their attributes, if any.
> 
>  - ``conntrack``: match conntrack state.
> 
> +- ``port_representor``: match traffic entering the embedded switch from
> +the given ethdev
> +
> +  - ``port_id {unsigned}``: ethdev port ID
> +
>  Actions list
>  ^^^^^^^^^^^^
> 
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> 8cb7a069c8..5e9317c6d1 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
> rte_flow_item_geneve_opt)),
>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
> rte_flow_item_ethdev)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> 7b1ed7f110..3625fd2c12 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_conntrack.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> +
> +	/**
> +	 * [META]
> +	 *
> +	 * Matches traffic entering the embedded switch from the given
> ethdev.
> +	 *
> +	 * @see struct rte_flow_item_ethdev
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
>  };
> 
>  /**
> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * Provides an ethdev port ID for use with the following items:
> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
> + */
> +struct rte_flow_item_ethdev {
> +	uint16_t port_id; /**< ethdev port ID */ };
> +
> +/** Default mask for items based on struct rte_flow_item_ethdev */
> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
> +rte_flow_item_ethdev_mask = {
> +	.port_id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v3 10/12] net/mlx5: support represented port flow action
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 10/12] net/mlx5: support represented port flow action Ivan Malov
@ 2021-10-12 21:23       ` Slava Ovsiienko
  0 siblings, 0 replies; 161+ messages in thread
From: Slava Ovsiienko @ 2021-10-12 21:23 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: NBU-Contact-Thomas Monjalon, Ori Kam, Andrew Rybchenko, Matan Azrad

Hi, Ivan

> -----Original Message-----
> From: Ivan Malov <ivan.malov@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 17:39
> To: dev@dpdk.org
> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Ori Kam
> <orika@nvidia.com>; Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>;
> Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>
> Subject: [PATCH v3 10/12] net/mlx5: support represented port flow action
> 
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
> Semantics of the existing support for action PORT_ID suggests that support
> for equal action REPRESENTED_PORT be implemented.
> 
> Helper functions keep port_id suffix since action
> MLX5_FLOW_ACTION_PORT_ID is still used internally.
> 
> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
>  doc/guides/nics/mlx5.rst        |  4 +--
>  drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++-------
>  2 files changed, 52 insertions(+), 14 deletions(-)
> 
> diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index
> bae73f42d8..b76e979f47 100644
> --- a/doc/guides/nics/mlx5.rst
> +++ b/doc/guides/nics/mlx5.rst
> @@ -431,8 +431,8 @@ Limitations
>       - yellow: NULL or END.
>       - RED: DROP / END.
>    - The only supported meter policy actions:
> -     - green: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
> -     - yellow: QUEUE, RSS, PORT_ID, JUMP, DROP, MARK and SET_TAG.
> +     - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK
> and SET_TAG.
> +     - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP,
> MARK and SET_TAG.
>       - RED: must be DROP.
>    - Policy actions of RSS for green and yellow should have the same
> configuration except queues.
>    - meter profile packet mode is supported.
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> b/drivers/net/mlx5/mlx5_flow_dv.c index c6370cd1d6..835cc5018c 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -5048,14 +5048,14 @@ flow_dv_validate_action_jump(struct
> rte_eth_dev *dev,  }
> 
>  /*
> - * Validate the port_id action.
> + * Validate action PORT_ID / REPRESENTED_PORT.
>   *
>   * @param[in] dev
>   *   Pointer to rte_eth_dev structure.
>   * @param[in] action_flags
>   *   Bit-fields that holds the actions detected until now.
>   * @param[in] action
> - *   Port_id RTE action structure.
> + *   PORT_ID / REPRESENTED_PORT action structure.
>   * @param[in] attr
>   *   Attributes of flow that includes this action.
>   * @param[out] error
> @@ -5072,6 +5072,7 @@ flow_dv_validate_action_port_id(struct
> rte_eth_dev *dev,
>  				struct rte_flow_error *error)
>  {
>  	const struct rte_flow_action_port_id *port_id;
> +	const struct rte_flow_action_ethdev *ethdev;
>  	struct mlx5_priv *act_priv;
>  	struct mlx5_priv *dev_priv;
>  	uint16_t port;
> @@ -5080,13 +5081,13 @@ flow_dv_validate_action_port_id(struct
> rte_eth_dev *dev,
>  		return rte_flow_error_set(error, ENOTSUP,
> 
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>  					  NULL,
> -					  "port id action is valid in transfer"
> +					  "port action is valid in transfer"
>  					  " mode only");
>  	if (!action || !action->conf)
>  		return rte_flow_error_set(error, ENOTSUP,
> 
> RTE_FLOW_ERROR_TYPE_ACTION_CONF,
>  					  NULL,
> -					  "port id action parameters must be"
> +					  "port action parameters must be"
>  					  " specified");
>  	if (action_flags & (MLX5_FLOW_FATE_ACTIONS |
>  			    MLX5_FLOW_FATE_ESWITCH_ACTIONS)) @@ -
> 5100,13 +5101,26 @@ flow_dv_validate_action_port_id(struct rte_eth_dev
> *dev,
> 
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
>  					  NULL,
>  					  "failed to obtain E-Switch info");
> -	port_id = action->conf;
> -	port = port_id->original ? dev->data->port_id : port_id->id;
> +	switch (action->type) {
> +	case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +		port_id = action->conf;
> +		port = port_id->original ? dev->data->port_id : port_id->id;
> +		break;
> +	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
> +		ethdev = action->conf;
> +		port = ethdev->port_id;
> +		break;
> +	default:

I would add MLX5_ASSERT(false) here.
It is not supposed to call flow_dv_validate_action_port_id() for other action types
but PORT_xxx only.

> +		return rte_flow_error_set
> +				(error, EINVAL,
> +				 RTE_FLOW_ERROR_TYPE_ACTION, action,
> +				 "unknown E-Switch action");
> +	}
>  	act_priv = mlx5_port_to_eswitch_info(port, false);
>  	if (!act_priv)
>  		return rte_flow_error_set
>  				(error, rte_errno,
> -				 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
> port_id,
> +				 RTE_FLOW_ERROR_TYPE_ACTION_CONF,
> action->conf,
>  				 "failed to obtain E-Switch port id for port");
>  	if (act_priv->domain_id != dev_priv->domain_id)
>  		return rte_flow_error_set
> @@ -5669,6 +5683,7 @@ flow_dv_validate_action_sample(uint64_t
> *action_flags,
>  			++actions_n;
>  			break;
>  		case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  			ret = flow_dv_validate_action_port_id(dev,
>  							      sub_action_flags,
>  							      act,
> @@ -7296,6 +7311,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const
> struct rte_flow_attr *attr,
>  		case RTE_FLOW_ACTION_TYPE_VOID:
>  			break;
>  		case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  			ret = flow_dv_validate_action_port_id(dev,
>  							      action_flags,
>  							      actions,
> @@ -10770,12 +10786,12 @@ flow_dv_tag_release(struct rte_eth_dev *dev,
> }
> 
>  /**
> - * Translate port ID action to vport.
> + * Translate action PORT_ID / REPRESENTED_PORT to vport.
>   *
>   * @param[in] dev
>   *   Pointer to rte_eth_dev structure.
>   * @param[in] action
> - *   Pointer to the port ID action.
> + *   Pointer to action PORT_ID / REPRESENTED_PORT.
>   * @param[out] dst_port_id
>   *   The target port ID.
>   * @param[out] error
> @@ -10792,10 +10808,28 @@ flow_dv_translate_action_port_id(struct
> rte_eth_dev *dev,  {
>  	uint32_t port;
>  	struct mlx5_priv *priv;
> -	const struct rte_flow_action_port_id *conf =
> -			(const struct rte_flow_action_port_id *)action->conf;
> 
> -	port = conf->original ? dev->data->port_id : conf->id;
> +	switch (action->type) {
> +	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
> +		const struct rte_flow_action_port_id *conf;
> +
> +		conf = (const struct rte_flow_action_port_id *)action->conf;
> +		port = conf->original ? dev->data->port_id : conf->id;
> +		break;
> +	}
> +	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
> +		const struct rte_flow_action_ethdev *ethdev;
> +
> +		ethdev = (const struct rte_flow_action_ethdev *)action->conf;
> +		port = ethdev->port_id;
> +		break;
> +	}
> +	default:
I would add MLX5_ASSERT(false) here as well.

With best regards,
Slava


> +		return rte_flow_error_set(error, EINVAL,
> +					  RTE_FLOW_ERROR_TYPE_ACTION,
> action,
> +					  "unknown E-Switch action");
> +	}
> +
>  	priv = mlx5_port_to_eswitch_info(port, false);
>  	if (!priv)
>  		return rte_flow_error_set(error, -rte_errno, @@ -11634,6
> +11668,7 @@ flow_dv_translate_action_sample(struct rte_eth_dev *dev,
>  			break;
>  		}
>  		case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  		{
>  			struct mlx5_flow_dv_port_id_action_resource
>  					port_id_resource;
> @@ -12714,6 +12749,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
>  		case RTE_FLOW_ACTION_TYPE_VOID:
>  			break;
>  		case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  			if (flow_dv_translate_action_port_id(dev, action,
>  							     &port_id, error))
>  				return -rte_errno;
> @@ -15475,6 +15511,7 @@ __flow_dv_create_domain_policy_acts(struct
> rte_eth_dev *dev,
>  				break;
>  			}
>  			case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  			{
>  				struct mlx5_flow_dv_port_id_action_resource
>  					port_id_resource;
> @@ -17683,6 +17720,7 @@ flow_dv_validate_mtr_policy_acts(struct
> rte_eth_dev *dev,
>  					  NULL, "too many actions");
>  			switch (act->type) {
>  			case RTE_FLOW_ACTION_TYPE_PORT_ID:
> +			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
>  				if (!priv->config.dv_esw_en)
>  					return -rte_mtr_error_set(error,
>  					ENOTSUP,
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-12 20:55       ` Slava Ovsiienko
@ 2021-10-12 23:14         ` Ivan Malov
  2021-10-13 18:26           ` Slava Ovsiienko
  0 siblings, 1 reply; 161+ messages in thread
From: Ivan Malov @ 2021-10-12 23:14 UTC (permalink / raw)
  To: Slava Ovsiienko, dev
  Cc: NBU-Contact-Thomas Monjalon, Ori Kam, Xiaoyun Li, Ferruh Yigit,
	Andrew Rybchenko

Hi,

On 12/10/2021 23:55, Slava Ovsiienko wrote:
> Hi,
> 
> Please, see below.
> 
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Ivan Malov
>> Sent: Sunday, October 10, 2021 17:39
>> To: dev@dpdk.org
>> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Ori Kam
>> <orika@nvidia.com>; Xiaoyun Li <xiaoyun.li@intel.com>; Ferruh Yigit
>> <ferruh.yigit@intel.com>; Andrew Rybchenko
>> <andrew.rybchenko@oktetlabs.ru>
>> Subject: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to
>> flow API
>>
>> For use in "transfer" flows. Supposed to match traffic entering the embedded
>> switch from the given ethdev.
>>
>> Must not be combined with direction attributes.
>>
>> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
>> ---
>>   app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
> 
> Should we separate testpmd changes into dedicated commit?
> This patch intermixes RTE Flow API update and testpmd.

I'm no fan of mixing things like that, but doing so appears to be rather 
logical. Each commit should be build testable. If the new defines have 
no users in the same commit, they are dummy. And I believe that readers 
typically want to see the use example in the same commit, too.

> 
> With best regards,
> Slava
> 
>>   doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
>>   doc/guides/rel_notes/release_21_11.rst      |  2 +
>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
>>   lib/ethdev/rte_flow.c                       |  1 +
>>   lib/ethdev/rte_flow.h                       | 27 ++++++++++
>>   6 files changed, 120 insertions(+)
>>
>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
>> index bb22294dd3..a912a8d815 100644
>> --- a/app/test-pmd/cmdline_flow.c
>> +++ b/app/test-pmd/cmdline_flow.c
>> @@ -306,6 +306,8 @@ enum index {
>>   	ITEM_POL_PORT,
>>   	ITEM_POL_METER,
>>   	ITEM_POL_POLICY,
>> +	ITEM_PORT_REPRESENTOR,
>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>>
>>   	/* Validate/create actions. */
>>   	ACTIONS,
>> @@ -1000,6 +1002,7 @@ static const enum index next_item[] = {
>>   	ITEM_GENEVE_OPT,
>>   	ITEM_INTEGRITY,
>>   	ITEM_CONNTRACK,
>> +	ITEM_PORT_REPRESENTOR,
>>   	END_SET,
>>   	ZERO,
>>   };
>> @@ -1368,6 +1371,12 @@ static const enum index item_integrity_lv[] = {
>>   	ZERO,
>>   };
>>
>> +static const enum index item_port_representor[] = {
>> +	ITEM_PORT_REPRESENTOR_PORT_ID,
>> +	ITEM_NEXT,
>> +	ZERO,
>> +};
>> +
>>   static const enum index next_action[] = {
>>   	ACTION_END,
>>   	ACTION_VOID,
>> @@ -3608,6 +3617,21 @@ static const struct token token_list[] = {
>>   			     item_param),
>>   		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack,
>> flags)),
>>   	},
>> +	[ITEM_PORT_REPRESENTOR] = {
>> +		.name = "port_representor",
>> +		.help = "match traffic entering the embedded switch from the
>> given ethdev",
>> +		.priv = PRIV_ITEM(PORT_REPRESENTOR,
>> +				  sizeof(struct rte_flow_item_ethdev)),
>> +		.next = NEXT(item_port_representor),
>> +		.call = parse_vc,
>> +	},
>> +	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
>> +		.name = "port_id",
>> +		.help = "ethdev port ID",
>> +		.next = NEXT(item_port_representor,
>> NEXT_ENTRY(COMMON_UNSIGNED),
>> +			     item_param),
>> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev,
>> port_id)),
>> +	},
>>   	/* Validate/create actions. */
>>   	[ACTIONS] = {
>>   		.name = "actions",
>> @@ -8343,6 +8367,9 @@ flow_item_default_mask(const struct
>> rte_flow_item *item)
>>   	case RTE_FLOW_ITEM_TYPE_PFCP:
>>   		mask = &rte_flow_item_pfcp_mask;
>>   		break;
>> +	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
>> +		mask = &rte_flow_item_ethdev_mask;
>> +		break;
>>   	default:
>>   		break;
>>   	}
>> diff --git a/doc/guides/prog_guide/rte_flow.rst
>> b/doc/guides/prog_guide/rte_flow.rst
>> index 2b42d5ec8c..91d5bdd712 100644
>> --- a/doc/guides/prog_guide/rte_flow.rst
>> +++ b/doc/guides/prog_guide/rte_flow.rst
>> @@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
>>   - ``flags``: conntrack packet state flags.
>>   - Default ``mask`` matches all state bits.
>>
>> +Item: ``PORT_REPRESENTOR``
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +Matches traffic entering the embedded switch from the given ethdev.
>> +
>> +Term **ethdev** and the concept of **port representor** are synonymous.
>> +The **represented port** is an *entity* plugged to the embedded switch
>> +at the opposite end of the "wire" leading to the ethdev.
>> +
>> +::
>> +
>> +    .--------------------.
>> +    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
>> +    '--------------------'
>> +              ||
>> +              \/
>> +      .----------------.
>> +      |  Logical Port  |
>> +      '----------------'
>> +              ||
>> +              ||
>> +              ||
>> +              \/
>> +         .----------.
>> +         |  Switch  |
>> +         '----------'
>> +              :
>> +               :
>> +              :
>> +               :
>> +      .----------------.
>> +      |  Logical Port  |
>> +      '----------------'
>> +              :
>> +               :
>> +    .--------------------.
>> +    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same
>> Application)
>> +    '--------------------'
>> +
>> +
>> +- Incompatible with `Attribute: Traffic direction`_.
>> +- Requires `Attribute: Transfer`_.
>> +
>> +.. _table_rte_flow_item_ethdev:
>> +
>> +.. table:: ``struct rte_flow_item_ethdev``
>> +
>> +   +----------+-------------+---------------------------+
>> +   | Field    | Subfield    | Value                     |
>> +   +==========+=============+===========================+
>> +   | ``spec`` | ``port_id`` | ethdev port ID            |
>> +   +----------+-------------+---------------------------+
>> +   | ``last`` | ``port_id`` | upper range value         |
>> +   +----------+-------------+---------------------------+
>> +   | ``mask`` | ``port_id`` | zeroed for wildcard match |
>> +   +----------+-------------+---------------------------+
>> +
>> +- Default ``mask`` provides exact match behaviour.
>> +
>>   Actions
>>   ~~~~~~~
>>
>> diff --git a/doc/guides/rel_notes/release_21_11.rst
>> b/doc/guides/rel_notes/release_21_11.rst
>> index 89d4b33ef1..1261cb2bf3 100644
>> --- a/doc/guides/rel_notes/release_21_11.rst
>> +++ b/doc/guides/rel_notes/release_21_11.rst
>> @@ -188,6 +188,8 @@ API Changes
>>      Also, make sure to start the actual text at the margin.
>>      =======================================================
>>
>> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
>> +
>>   * kvargs: The experimental function ``rte_kvargs_strcmp()`` has been
>>     removed. Its usages have been replaced by a new function
>>     ``rte_kvargs_get_with_value()``.
>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> index 8ead7a4a71..dcb9f47d98 100644
>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> @@ -3795,6 +3795,10 @@ This section lists supported pattern items and
>> their attributes, if any.
>>
>>   - ``conntrack``: match conntrack state.
>>
>> +- ``port_representor``: match traffic entering the embedded switch from
>> +the given ethdev
>> +
>> +  - ``port_id {unsigned}``: ethdev port ID
>> +
>>   Actions list
>>   ^^^^^^^^^^^^
>>
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>> 8cb7a069c8..5e9317c6d1 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -100,6 +100,7 @@ static const struct rte_flow_desc_data
>> rte_flow_desc_item[] = {
>>   	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
>> rte_flow_item_geneve_opt)),
>>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>> +	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
>> rte_flow_item_ethdev)),
>>   };
>>
>>   /** Generate flow_action[] entry. */
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> 7b1ed7f110..3625fd2c12 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -574,6 +574,15 @@ enum rte_flow_item_type {
>>   	 * @see struct rte_flow_item_conntrack.
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_CONNTRACK,
>> +
>> +	/**
>> +	 * [META]
>> +	 *
>> +	 * Matches traffic entering the embedded switch from the given
>> ethdev.
>> +	 *
>> +	 * @see struct rte_flow_item_ethdev
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
>>   };
>>
>>   /**
>> @@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack
>> rte_flow_item_conntrack_mask = {  };  #endif
>>
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + *
>> + * Provides an ethdev port ID for use with the following items:
>> + * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
>> + */
>> +struct rte_flow_item_ethdev {
>> +	uint16_t port_id; /**< ethdev port ID */ };
>> +
>> +/** Default mask for items based on struct rte_flow_item_ethdev */
>> +#ifndef __cplusplus static const struct rte_flow_item_ethdev
>> +rte_flow_item_ethdev_mask = {
>> +	.port_id = 0xffff,
>> +};
>> +#endif
>> +
>>   /**
>>    * Matching pattern item definition.
>>    *
>> --
>> 2.20.1

-- 
Ivan M

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

* Re: [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
                       ` (12 preceding siblings ...)
  2021-10-12 14:45     ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ferruh Yigit
@ 2021-10-13 11:51     ` Ferruh Yigit
  13 siblings, 0 replies; 161+ messages in thread
From: Ferruh Yigit @ 2021-10-13 11:51 UTC (permalink / raw)
  To: Ivan Malov, Thomas Monjalon; +Cc: Ori Kam, dev

On 10/10/2021 3:39 PM, Ivan Malov wrote:
> As per RFC [1], action PORT_ID appears to be ambiguous. Its name suggests
> that matching traffic be sent to the ethdev with the specified ID, that
> is, to the application. However, in Open vSwitch, the action is used to
> send traffic to a remote entity represented by the given port, that is,
> in the opposite direction. Its interpretation across PMDs also varies.
> 
> RFC [2] attempted to define action PORT_ID semantics in vSwitch sense.
> However, this solution would completely abandon the opposite meaning.
> 
> One more effort, RFC [3], was meant to declare that the use of direction
> attributes in "transfer" flows assumed implicit filtering by the port ID
> appearing as the first argument in rte_flow_create(). However, not all
> PMDs require such filtering, so the RFC turned out rather disputable.
> 
> 
> Since then, all of that has been given more thought:
> 
> 1. One should not attempt to fix action PORT_ID. Instead, two new actions
>     should be introduced. The first one should send traffic to the given
>     ethdev. The second one should send it to the represented entity.
> 
> 2. Similar to (1), two new items should be defined. The first one should
>     match traffic going down from the given ethdev. The second one should
>     match traffic going up from the entity represented by that ethdev.
> 
> 3. The application always knows which packets come through which ethdevs.
>     So, as per (2), the application can use the new item to match traffic
>     arriving from precise entities represented by the relevant ethdev IDs.
> 
> 4. New items suggested in (2) do not require the use of direction
>     attributes. These items define precise directions on their own.
> 
> 5. As a consequence of (3) and (4), the problem of implicit filtering
>     by rte_flow_create() port ID argument and direction attributes is
>     no longer a blocker. The new items allow to dispose of it.
> 
> 
> The new items appear to be symmetrical to each other. So do the new
> actions. This requires that their names reflect the symmetry. Also,
> the names should respect the existing concept of port representors.
> By the looks of it, terms "PORT_REPRESENTOR" and "REPRESENTED_PORT"
> satisfy these requirements. However, currently, ethdevs associated
> with network ports are not considered as their representors. Such
> understanding is mentioned in the documentation, but it's not
> expressed in the code (see enum rte_eth_representor_type).
> 
> 
> The short of it, this patch series follows points (1-5) to rework
> support for "transfer" flows accordingly. On the way, a string of
> ambiguous pattern items (PF, VF, PHY_PORT) is deprecated.
> 
> The patch series also updates PMDs which support item and action PORT_ID
> to add support for replacements (1-2). However, there're some exceptions:
> 
>   - Support for traffic source items in the case of net/mlx5 is really
>     complicated. This series does not rework it. The PMD maintainer
>     can do the job much better and test the new code accordingly;
> 
>   - Support for action REPRESENTED_PORT is not added to net/sfc.
>     This will be done when support for VF representors has been
>     upstreamed, just for the new code to apply cleanly.
> 
> 
> Changes in v2:
> * New naming and reworked comments
> * New diagrams
> 
> Changes in v3:
> * Diagram improvements
> * Spelling fixes
> 
> [1] https://patches.dpdk.org/project/dpdk/patch/20210907125157.3843-1-ivan.malov@oktetlabs.ru/
> [2] https://patches.dpdk.org/project/dpdk/patch/20210903074610.313622-1-andrew.rybchenko@oktetlabs.ru/
> [3] https://patches.dpdk.org/project/dpdk/patch/20210901151104.3923889-1-andrew.rybchenko@oktetlabs.ru/
> 
> Andrew Rybchenko (6):
>    net/bnxt: support meta flow items to match on traffic source
>    net/bnxt: support meta flow actions to overrule destinations
>    net/enic: support meta flow actions to overrule destinations
>    net/mlx5: support represented port flow action
>    net/octeontx2: support port representor flow action
>    net/sfc: support port representor flow item
> 
> Ivan Malov (6):
>    ethdev: add port representor item to flow API
>    ethdev: add represented port item to flow API
>    ethdev: add port representor action to flow API
>    ethdev: add represented port action to flow API
>    ethdev: deprecate hard-to-use or ambiguous items and actions
>    ethdev: deprecate direction attributes in transfer flows
> 

The rte flow documentation script is failing [1], should new actions
added to the documentation?

[1]
./devtools/check-doc-vs-code.sh
rte_flow doc out of sync for bnxt
         item port_representor
         item represented_port
         action port_representor
         action represented_port
rte_flow doc out of sync for enic
         action port_representor
         action represented_port
rte_flow doc out of sync for mlx5
         action represented_port
rte_flow doc out of sync for octeontx2
         action port_representor
rte_flow doc out of sync for sfc
         item port_representor


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

* Re: [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to flow API
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 01/12] ethdev: add port representor item to " Ivan Malov
  2021-10-11 11:49       ` Ori Kam
  2021-10-12 20:55       ` Slava Ovsiienko
@ 2021-10-13 11:52       ` Ferruh Yigit
  2 siblings, 0 replies; 161+ messages in thread
From: Ferruh Yigit @ 2021-10-13 11:52 UTC (permalink / raw)
  To: Ivan Malov, dev; +Cc: Thomas Monjalon, Ori Kam, Xiaoyun Li, Andrew Rybchenko

On 10/10/2021 3:39 PM, Ivan Malov wrote:
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index 89d4b33ef1..1261cb2bf3 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -188,6 +188,8 @@ API Changes
>      Also, make sure to start the actual text at the margin.
>      =======================================================
>   
> +* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
> +

Since there will be a new version, can you please add 'ethdev' update after
core libraries, for existing doc it is after 'cryptodev' changes?

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

* Re: [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-10 14:39     ` [dpdk-dev] [PATCH v3 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
  2021-10-11 18:23       ` Ori Kam
@ 2021-10-13 11:53       ` Ferruh Yigit
  1 sibling, 0 replies; 161+ messages in thread
From: Ferruh Yigit @ 2021-10-13 11:53 UTC (permalink / raw)
  To: Ivan Malov, dev; +Cc: Thomas Monjalon, Ori Kam, Ray Kinsella, Andrew Rybchenko

On 10/10/2021 3:39 PM, Ivan Malov wrote:
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -122,12 +122,6 @@ Deprecation Notices
>     is deprecated and will be removed in DPDK 21.11. Shared counters should
>     be managed using shared actions API (``rte_flow_shared_action_create`` etc).
>   
> -* ethdev: Definition of the flow API action ``RTE_FLOW_ACTION_TYPE_PORT_ID``
> -  is ambiguous and needs clarification.
> -  Structure ``rte_flow_action_port_id`` will be extended to specify
> -  traffic direction to the represented entity or ethdev port itself
> -  in DPDK 21.11.
> -
>   * ethdev: Flow API documentation is unclear if ethdev port used to create
>     a flow rule adds any implicit match criteria in the case of transfer rules.
>     The semantics will be clarified in DPDK 21.11 and it will require fixes in
> @@ -256,3 +250,6 @@ Deprecation Notices
>   * cmdline: ``cmdline`` structure will be made opaque to hide platform-specific
>     content. On Linux and FreeBSD, supported prior to DPDK 20.11,
>     original structure will be kept until DPDK 21.11.
> +
> +* ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
> +  deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.

Since there will be a new version, can you please add new 'ethdev' deprecation notices,
to the end of the 'ethdev' related deprecation notice group above?

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

* [dpdk-dev] [PATCH v4 00/12] ethdev: rework transfer flow API
  2021-10-01 13:47 ` [dpdk-dev] [PATCH v1 00/12] ethdev: rework transfer flow API Andrew Rybchenko
                     ` (13 preceding siblings ...)
  2021-10-10 14:39   ` [dpdk-dev] [PATCH v3 00/12] ethdev: rework transfer flow API Ivan Malov
@ 2021-10-13 16:42   ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 01/12] ethdev: add port representor item to " Ivan Malov
                       ` (11 more replies)
  2021-10-13 16:57   ` [dpdk-dev] [PATCH v4 00/12] ethdev: rework transfer flow API Ivan Malov
                     ` (2 subsequent siblings)
  17 siblings, 12 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam

As per RFC [1], action PORT_ID appears to be ambiguous. Its name suggests
that matching traffic be sent to the ethdev with the specified ID, that
is, to the application. However, in Open vSwitch, the action is used to
send traffic to a remote entity represented by the given port, that is,
in the opposite direction. Its interpretation across PMDs also varies.

RFC [2] attempted to define action PORT_ID semantics in vSwitch sense.
However, this solution would completely abandon the opposite meaning.

One more effort, RFC [3], was meant to declare that the use of direction
attributes in "transfer" flows assumed implicit filtering by the port ID
appearing as the first argument in rte_flow_create(). However, not all
PMDs require such filtering, so the RFC turned out rather disputable.


Since then, all of that has been given more thought:

1. One should not attempt to fix action PORT_ID. Instead, two new actions
   should be introduced. The first one should send traffic to the given
   ethdev. The second one should send it to the represented entity.

2. Similar to (1), two new items should be defined. The first one should
   match traffic going down from the given ethdev. The second one should
   match traffic going up from the entity represented by that ethdev.

3. The application always knows which packets come through which ethdevs.
   So, as per (2), the application can use the new item to match traffic
   arriving from precise entities represented by the relevant ethdev IDs.

4. New items suggested in (2) do not require the use of direction
   attributes. These items define precise directions on their own.

5. As a consequence of (3) and (4), the problem of implicit filtering
   by rte_flow_create() port ID argument and direction attributes is
   no longer a blocker. The new items allow to dispose of it.


The new items appear to be symmetrical to each other. So do the new
actions. This requires that their names reflect the symmetry. Also,
the names should respect the existing concept of port representors.
By the looks of it, terms "PORT_REPRESENTOR" and "REPRESENTED_PORT"
satisfy these requirements. However, currently, ethdevs associated
with network ports are not considered as their representors. Such
understanding is mentioned in the documentation, but it's not
expressed in the code (see enum rte_eth_representor_type).


The short of it, this patch series follows points (1-5) to rework
support for "transfer" flows accordingly. On the way, a string of
ambiguous pattern items (PF, VF, PHY_PORT) is deprecated.

The patch series also updates PMDs which support item and action PORT_ID
to add support for replacements (1-2). However, there're some exceptions:

 - Support for traffic source items in the case of net/mlx5 is really
   complicated. This series does not rework it. The PMD maintainer
   can do the job much better and test the new code accordingly;

 - Support for item REPRESENTED_PORT and both actions is not added
   to net/sfc. This will be done later on, in a separate series.


Changes in v2:
* New naming and reworked comments
* New diagrams

Changes in v3:
* Diagram improvements
* Spelling fixes

Changes in v4:
* Minor adjustments as per request by Ferruh Yigit

Andrew Rybchenko (6):
  net/bnxt: support meta flow items to match on traffic source
  net/bnxt: support meta flow actions to overrule destinations
  net/enic: support meta flow actions to overrule destinations
  net/mlx5: support represented port flow action
  net/octeontx2: support port representor flow action
  net/sfc: support port representor flow item

Ivan Malov (6):
  ethdev: add port representor item to flow API
  ethdev: add represented port item to flow API
  ethdev: add port representor action to flow API
  ethdev: add represented port action to flow API
  ethdev: deprecate hard-to-use or ambiguous items and actions
  ethdev: deprecate direction attributes in transfer flows

 app/test-pmd/cmdline_flow.c                   | 104 +++++++
 doc/guides/nics/features/bnxt.ini             |   4 +
 doc/guides/nics/features/enic.ini             |   2 +
 doc/guides/nics/features/mlx5.ini             |   1 +
 doc/guides/nics/features/octeontx2.ini        |   1 +
 doc/guides/nics/features/sfc.ini              |   1 +
 doc/guides/nics/mlx5.rst                      |   4 +-
 doc/guides/nics/octeontx2.rst                 |   5 +-
 doc/guides/nics/sfc_efx.rst                   |   4 +
 doc/guides/prog_guide/rte_flow.rst            | 270 +++++++++++++++++-
 doc/guides/rel_notes/deprecation.rst          |  18 +-
 doc/guides/rel_notes/release_21_11.rst        |   8 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst   |  19 ++
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c |  22 +-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 161 ++++++++---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  12 +-
 drivers/net/enic/enic_fm_flow.c               |  93 ++++--
 drivers/net/mlx5/mlx5_flow_dv.c               |  64 ++++-
 drivers/net/octeontx2/otx2_flow_parse.c       |  16 +-
 drivers/net/sfc/sfc_mae.c                     |  72 +++++
 lib/ethdev/rte_flow.c                         |   4 +
 lib/ethdev/rte_flow.h                         | 162 ++++++++++-
 22 files changed, 927 insertions(+), 120 deletions(-)

-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 01/12] ethdev: add port representor item to flow API
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 02/12] ethdev: add represented port " Ivan Malov
                       ` (10 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li

For use in "transfer" flows. Supposed to match traffic
entering the embedded switch from the given ethdev.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 27 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 59 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 27 ++++++++++
 6 files changed, 120 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 0b5856c7d5..5c480db91d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -306,6 +306,8 @@ enum index {
 	ITEM_POL_PORT,
 	ITEM_POL_METER,
 	ITEM_POL_POLICY,
+	ITEM_PORT_REPRESENTOR,
+	ITEM_PORT_REPRESENTOR_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -999,6 +1001,7 @@ static const enum index next_item[] = {
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
+	ITEM_PORT_REPRESENTOR,
 	END_SET,
 	ZERO,
 };
@@ -1367,6 +1370,12 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_port_representor[] = {
+	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3606,6 +3615,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
 	},
+	[ITEM_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "match traffic entering the embedded switch from the given ethdev",
+		.priv = PRIV_ITEM(PORT_REPRESENTOR,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_port_representor),
+		.call = parse_vc,
+	},
+	[ITEM_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8333,6 +8357,9 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+		mask = &rte_flow_item_ethdev_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3cb014c1fa..d194640469 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,65 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              ||
+              \/
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              ||
+              ||
+              ||
+              \/
+         .----------.
+         |  Switch  |
+         '----------'
+              :
+               :
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Incompatible with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_item_ethdev:
+
+.. table:: ``struct rte_flow_item_ethdev``
+
+   +----------+-------------+---------------------------+
+   | Field    | Subfield    | Value                     |
+   +==========+=============+===========================+
+   | ``spec`` | ``port_id`` | ethdev port ID            |
+   +----------+-------------+---------------------------+
+   | ``last`` | ``port_id`` | upper range value         |
+   +----------+-------------+---------------------------+
+   | ``mask`` | ``port_id`` | zeroed for wildcard match |
+   +----------+-------------+---------------------------+
+
+- Default ``mask`` provides exact match behaviour.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index d5c762df62..07f9d39a5b 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -252,6 +252,8 @@ API Changes
   the crypto/security operation. This field will be used to communicate
   events such as soft expiry with IPsec in lookaside mode.
 
+* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+
 
 ABI Changes
 -----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a0efb7d0b0..90765f9090 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3801,6 +3801,10 @@ This section lists supported pattern items and their attributes, if any.
 
 - ``conntrack``: match conntrack state.
 
+- ``port_representor``: match traffic entering the embedded switch from the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..5e9317c6d1 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -100,6 +100,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
+	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 5f87851f8c..1e3ef77ead 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -574,6 +574,15 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -1799,6 +1808,24 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following items:
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_item_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
+/** Default mask for items based on struct rte_flow_item_ethdev */
+#ifndef __cplusplus
+static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
+	.port_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 02/12] ethdev: add represented port item to flow API
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 01/12] ethdev: add port representor item to " Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 03/12] ethdev: add port representor action " Ivan Malov
                       ` (9 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li

For use in "transfer" flows. Supposed to match traffic entering the
embedded switch from the entity represented by the given ethdev.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Must not be combined with direction attributes.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 25 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 46 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 13 +++++-
 6 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5c480db91d..354f0fb2d7 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -308,6 +308,8 @@ enum index {
 	ITEM_POL_POLICY,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_PORT_REPRESENTOR_PORT_ID,
+	ITEM_REPRESENTED_PORT,
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1002,6 +1004,7 @@ static const enum index next_item[] = {
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
+	ITEM_REPRESENTED_PORT,
 	END_SET,
 	ZERO,
 };
@@ -1376,6 +1379,12 @@ static const enum index item_port_representor[] = {
 	ZERO,
 };
 
+static const enum index item_represented_port[] = {
+	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3630,6 +3639,21 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "match traffic entering the embedded switch from the entity represented by the given ethdev",
+		.priv = PRIV_ITEM(REPRESENTED_PORT,
+				  sizeof(struct rte_flow_item_ethdev)),
+		.next = NEXT(item_represented_port),
+		.call = parse_vc,
+	},
+	[ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -8358,6 +8382,7 @@ flow_item_default_mask(const struct rte_flow_item *item)
 		mask = &rte_flow_item_pfcp_mask;
 		break;
 	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
 	default:
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index d194640469..2da286dce8 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,52 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+Item: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches traffic entering the embedded switch from
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+              :
+               :
+         .----------.
+         |  Switch  |
+         '----------'
+              /\
+              ||
+              ||
+              ||
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              /\
+              ||
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Incompatible with `Attribute: Traffic direction`_.
+- Requires `Attribute: Transfer`_.
+
+This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 07f9d39a5b..b9f918cab8 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -252,7 +252,7 @@ API Changes
   the crypto/security operation. This field will be used to communicate
   events such as soft expiry with IPsec in lookaside mode.
 
-* ethdev: Added item ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 90765f9090..61669d1d5a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3805,6 +3805,11 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: match traffic entering the embedded switch from
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Actions list
 ^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 5e9317c6d1..d4b654a2c6 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -101,6 +101,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1e3ef77ead..b50c3d38b5 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -583,6 +583,16 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * [META]
+	 *
+	 * Matches traffic entering the embedded switch from
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_item_ethdev
+	 */
+	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -1813,7 +1823,8 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following items:
- * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_item_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 03/12] ethdev: add port representor action to flow API
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 01/12] ethdev: add port representor item to " Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 02/12] ethdev: add represented port " Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 04/12] ethdev: add represented port " Ivan Malov
                       ` (8 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li

For use in "transfer" flows. Supposed to send matching traffic to
the given ethdev (to the application), at embedded switch level.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 ++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 56 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 ++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 18 +++++++
 6 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 354f0fb2d7..1496d7a067 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -459,6 +459,8 @@ enum index {
 	ACTION_POL_G,
 	ACTION_POL_Y,
 	ACTION_POL_R,
+	ACTION_PORT_REPRESENTOR,
+	ACTION_PORT_REPRESENTOR_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1451,6 +1453,7 @@ static const enum index next_action[] = {
 	ACTION_MODIFY_FIELD,
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
+	ACTION_PORT_REPRESENTOR,
 	ZERO,
 };
 
@@ -1731,6 +1734,12 @@ static const enum index action_update_conntrack[] = {
 	ZERO,
 };
 
+static const enum index action_port_representor[] = {
+	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4810,6 +4819,23 @@ static const struct token token_list[] = {
 		.next = NEXT(action_update_conntrack),
 		.call = parse_vc_action_conntrack_update,
 	},
+	[ACTION_PORT_REPRESENTOR] = {
+		.name = "port_representor",
+		.help = "at embedded switch level, send matching traffic to the given ethdev",
+		.priv = PRIV_ACTION(PORT_REPRESENTOR,
+				    sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_port_representor),
+		.call = parse_vc,
+	},
+	[ACTION_PORT_REPRESENTOR_PORT_ID] = {
+		.name = "port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_port_representor,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2da286dce8..587ed37c2c 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1484,6 +1484,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 - Default ``mask`` provides exact match behaviour.
 
+See also `Action: PORT_REPRESENTOR`_.
+
 Item: ``REPRESENTED_PORT``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -3089,6 +3091,60 @@ which is set in the packet meta-data (i.e. struct ``rte_mbuf::sched::color``)
    | ``meter_color`` | Packet color |
    +-----------------+--------------+
 
+Action: ``PORT_REPRESENTOR``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              /\
+              ||
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              /\
+              ||
+              ||
+              ||
+         .----------.       .--------------------.
+         |  Switch  |  <==  |  Matching Traffic  |
+         '----------'       '--------------------'
+              :
+               :
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+.. _table_rte_flow_action_ethdev:
+
+.. table:: ``struct rte_flow_action_ethdev``
+
+   +-------------+----------------+
+   | Field       | Value          |
+   +=============+================+
+   | ``port_id`` | ethdev port ID |
+   +-------------+----------------+
+
+See also `Item: PORT_REPRESENTOR`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index b9f918cab8..9a0ab97914 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -252,7 +252,7 @@ API Changes
   the crypto/security operation. This field will be used to communicate
   events such as soft expiry with IPsec in lookaside mode.
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
+* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 61669d1d5a..46b7f07cbc 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4085,6 +4085,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``type {value}``: Set color type with specified value(green/yellow/red)
 
+- ``port_representor``: at embedded switch level, send matching traffic to
+  the given ethdev
+
+  - ``port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index d4b654a2c6..b074b1c77d 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -191,6 +191,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	 */
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
+	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b50c3d38b5..56fd4393e5 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2455,6 +2455,13 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_meter_color.
 	 */
 	RTE_FLOW_ACTION_TYPE_METER_COLOR,
+
+	/**
+	 * At embedded switch level, sends matching traffic to the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
 };
 
 /**
@@ -3200,6 +3207,17 @@ struct rte_flow_action_meter_color {
 	enum rte_color color; /**< Packet color. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * Provides an ethdev port ID for use with the following actions:
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ */
+struct rte_flow_action_ethdev {
+	uint16_t port_id; /**< ethdev port ID */
+};
+
 /**
  * Field IDs for MODIFY_FIELD action.
  */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 04/12] ethdev: add represented port action to flow API
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                       ` (2 preceding siblings ...)
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 03/12] ethdev: add port representor action " Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
                       ` (7 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Xiaoyun Li

For use in "transfer" flows. Supposed to send matching traffic to the
entity represented by the given ethdev, at embedded switch level.
Such an entity can be a network (via a network port), a guest
machine (via a VF) or another ethdev in the same application.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c                 | 26 +++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_21_11.rst      |  2 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +++
 lib/ethdev/rte_flow.c                       |  1 +
 lib/ethdev/rte_flow.h                       | 11 ++++-
 6 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1496d7a067..d897d0d1d4 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -461,6 +461,8 @@ enum index {
 	ACTION_POL_R,
 	ACTION_PORT_REPRESENTOR,
 	ACTION_PORT_REPRESENTOR_PORT_ID,
+	ACTION_REPRESENTED_PORT,
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1454,6 +1456,7 @@ static const enum index next_action[] = {
 	ACTION_CONNTRACK,
 	ACTION_CONNTRACK_UPDATE,
 	ACTION_PORT_REPRESENTOR,
+	ACTION_REPRESENTED_PORT,
 	ZERO,
 };
 
@@ -1740,6 +1743,12 @@ static const enum index action_port_representor[] = {
 	ZERO,
 };
 
+static const enum index action_represented_port[] = {
+	ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_set_raw_encap_decap(struct context *, const struct token *,
 				     const char *, unsigned int,
 				     void *, unsigned int);
@@ -4836,6 +4845,23 @@ static const struct token token_list[] = {
 					port_id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_REPRESENTED_PORT] = {
+		.name = "represented_port",
+		.help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev",
+		.priv = PRIV_ACTION(REPRESENTED_PORT,
+				sizeof(struct rte_flow_action_ethdev)),
+		.next = NEXT(action_represented_port),
+		.call = parse_vc,
+	},
+	[ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = {
+		.name = "ethdev_port_id",
+		.help = "ethdev port ID",
+		.next = NEXT(action_represented_port,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev,
+					port_id)),
+		.call = parse_vc_conf,
+	},
 	/* Indirect action destroy arguments. */
 	[INDIRECT_ACTION_DESTROY_ID] = {
 		.name = "action_id",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 587ed37c2c..27a17fac58 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1532,6 +1532,8 @@ at the opposite end of the "wire" leading to the ethdev.
 
 This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
+See also `Action: REPRESENTED_PORT`_.
+
 Actions
 ~~~~~~~
 
@@ -3145,6 +3147,53 @@ at the opposite end of the "wire" leading to the ethdev.
 
 See also `Item: PORT_REPRESENTOR`_.
 
+Action: ``REPRESENTED_PORT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At embedded switch level, send matching traffic to
+the entity represented by the given ethdev.
+
+Term **ethdev** and the concept of **port representor** are synonymous.
+The **represented port** is an *entity* plugged to the embedded switch
+at the opposite end of the "wire" leading to the ethdev.
+
+::
+
+    .--------------------.
+    |  PORT_REPRESENTOR  |  Ethdev (Application Port Referred to by its ID)
+    '--------------------'
+              :
+               :
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              :
+               :
+              :
+               :
+         .----------.       .--------------------.
+         |  Switch  |  <==  |  Matching Traffic  |
+         '----------'       '--------------------'
+              ||
+              ||
+              ||
+              \/
+      .----------------.
+      |  Logical Port  |
+      '----------------'
+              ||
+              \/
+    .--------------------.
+    |  REPRESENTED_PORT  |  Net / Guest / Another Ethdev (Same Application)
+    '--------------------'
+
+
+- Requires `Attribute: Transfer`_.
+
+This action is meant to use the same structure as `Action: PORT_REPRESENTOR`_.
+
+See also `Item: REPRESENTED_PORT`_.
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 9a0ab97914..6c15afc1e9 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -252,7 +252,7 @@ API Changes
   the crypto/security operation. This field will be used to communicate
   events such as soft expiry with IPsec in lookaside mode.
 
-* ethdev: Added items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` and action ``PORT_REPRESENTOR`` to flow API.
+* ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
 
 ABI Changes
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 46b7f07cbc..22ba8f0516 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4090,6 +4090,11 @@ This section lists supported actions and their attributes, if any.
 
   - ``port_id {unsigned}``: ethdev port ID
 
+- ``represented_port``: at embedded switch level, send matching traffic to
+  the entity represented by the given ethdev
+
+  - ``ethdev_port_id {unsigned}``: ethdev port ID
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index b074b1c77d..542e40e496 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -192,6 +192,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
 	MK_FLOW_ACTION(INDIRECT, 0),
 	MK_FLOW_ACTION(CONNTRACK, sizeof(struct rte_flow_action_conntrack)),
 	MK_FLOW_ACTION(PORT_REPRESENTOR, sizeof(struct rte_flow_action_ethdev)),
+	MK_FLOW_ACTION(REPRESENTED_PORT, sizeof(struct rte_flow_action_ethdev)),
 };
 
 int
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 56fd4393e5..ff32c0a5ee 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2462,6 +2462,14 @@ enum rte_flow_action_type {
 	 * @see struct rte_flow_action_ethdev
 	 */
 	RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+
+	/**
+	 * At embedded switch level, send matching traffic to
+	 * the entity represented by the given ethdev.
+	 *
+	 * @see struct rte_flow_action_ethdev
+	 */
+	RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
 };
 
 /**
@@ -3212,7 +3220,8 @@ struct rte_flow_action_meter_color {
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
  * Provides an ethdev port ID for use with the following actions:
- * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR.
+ * RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+ * RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT.
  */
 struct rte_flow_action_ethdev {
 	uint16_t port_id; /**< ethdev port ID */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                       ` (3 preceding siblings ...)
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 04/12] ethdev: add represented port " Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
                       ` (6 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ray Kinsella

PF, VF and PHY_PORT require that applications have extra
knowledge of the underlying NIC and thus are hard to use.
Also, the corresponding items depend on the direction
attribute (ingress / egress), which complicates their
use in applications and interpretation in PMDs.

The concept of PORT_ID is ambiguous as it doesn't say whether
the port in question is an ethdev or the represented entity.

Items and actions PORT_REPRESENTOR, REPRESENTED_PORT
should be used instead.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 32 +++++++++++++++
 doc/guides/rel_notes/deprecation.rst   |  9 ++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 56 ++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 27a17fac58..d7185c49df 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -504,6 +504,10 @@ Usage example, matching non-TCPv4 packets only:
 Item: ``PF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) the physical
 function of the current device.
 
@@ -531,6 +535,10 @@ the application and thus not associated with a DPDK port ID.
 Item: ``VF``
 ^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given
 virtual function of the current device.
 
@@ -562,6 +570,10 @@ separate entities, should be addressed through their own DPDK port IDs.
 Item: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a physical
 port of the underlying device.
 
@@ -596,6 +608,10 @@ associated with a port_id should be retrieved by other means.
 Item: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^
 
+This item is deprecated. Consider:
+ - `Item: PORT_REPRESENTOR`_
+ - `Item: REPRESENTED_PORT`_
+
 Matches traffic originating from (ingress) or going to (egress) a given DPDK
 port ID.
 
@@ -1950,6 +1966,10 @@ only matching traffic goes through.
 Action: ``PF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to the physical function (PF) of the current
 device.
 
@@ -1970,6 +1990,10 @@ See `Item: PF`_.
 Action: ``VF``
 ^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given virtual function of the current device.
 
 Packets matched by a VF pattern item can be redirected to their original VF
@@ -1994,6 +2018,10 @@ See `Item: VF`_.
 Action: ``PHY_PORT``
 ^^^^^^^^^^^^^^^^^^^^
 
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given physical port index of the underlying
 device.
 
@@ -2013,6 +2041,10 @@ See `Item: PHY_PORT`_.
 
 Action: ``PORT_ID``
 ^^^^^^^^^^^^^^^^^^^
+This action is deprecated. Consider:
+ - `Action: PORT_REPRESENTOR`_
+ - `Action: REPRESENTED_PORT`_
+
 Directs matching traffic to a given DPDK port ID.
 
 See `Item: PORT_ID`_.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 5853b5988d..25aec56bec 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -113,12 +113,6 @@ Deprecation Notices
   to support modifying fields larger than 64 bits.
   In addition, documentation will be updated to clarify byte order.
 
-* ethdev: Definition of the flow API action ``RTE_FLOW_ACTION_TYPE_PORT_ID``
-  is ambiguous and needs clarification.
-  Structure ``rte_flow_action_port_id`` will be extended to specify
-  traffic direction to the represented entity or ethdev port itself
-  in DPDK 21.11.
-
 * ethdev: Flow API documentation is unclear if ethdev port used to create
   a flow rule adds any implicit match criteria in the case of transfer rules.
   The semantics will be clarified in DPDK 21.11 and it will require fixes in
@@ -149,6 +143,9 @@ Deprecation Notices
   consistent with existing outer header checksum status flag naming, which
   should help in reducing confusion about its usage.
 
+* ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
+  deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
+
 * net: The structure ``rte_ipv4_hdr`` will have two unions.
   The first union is for existing ``version_ihl`` byte
   and new bitfield for version and IHL.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 6c15afc1e9..75c4f6d018 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -254,6 +254,9 @@ API Changes
 
 * ethdev: Added items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` to flow API.
 
+* ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
+  Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index ff32c0a5ee..76653105a0 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -160,6 +160,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_ANY,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress)
@@ -170,6 +174,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -180,6 +188,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -190,6 +202,10 @@ enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+	 *
 	 * [META]
 	 *
 	 * Matches traffic originating from (ingress) or going to (egress) a
@@ -640,6 +656,10 @@ static const struct rte_flow_item_any rte_flow_item_any_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_VF
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -669,6 +689,10 @@ static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PHY_PORT
  *
  * Matches traffic originating from (ingress) or going to (egress) a
@@ -700,6 +724,10 @@ static const struct rte_flow_item_phy_port rte_flow_item_phy_port_mask = {
 #endif
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ITEM_TYPE_PORT_ID
  *
  * Matches traffic originating from (ingress) or going to (egress) a given
@@ -1998,6 +2026,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_RSS,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to the physical function (PF) of the
 	 * current device.
 	 *
@@ -2006,6 +2038,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given virtual function of the
 	 * current device.
 	 *
@@ -2014,6 +2050,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_VF,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs packets to a given physical port index of the underlying
 	 * device.
 	 *
@@ -2022,6 +2062,10 @@ enum rte_flow_action_type {
 	RTE_FLOW_ACTION_TYPE_PHY_PORT,
 
 	/**
+	 * @deprecated
+	 * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+	 * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+	 *
 	 * Directs matching traffic to a given DPDK port ID.
 	 *
 	 * See struct rte_flow_action_port_id.
@@ -2648,6 +2692,10 @@ struct rte_flow_action_rss {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_VF
  *
  * Directs matching traffic to a given virtual function of the current
@@ -2666,6 +2714,10 @@ struct rte_flow_action_vf {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PHY_PORT
  *
  * Directs packets to a given physical port index of the underlying
@@ -2680,6 +2732,10 @@ struct rte_flow_action_phy_port {
 };
 
 /**
+ * @deprecated
+ * @see RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR
+ * @see RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT
+ *
  * RTE_FLOW_ACTION_TYPE_PORT_ID
  *
  * Directs matching traffic to a given DPDK port ID.
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 06/12] ethdev: deprecate direction attributes in transfer flows
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                       ` (4 preceding siblings ...)
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 05/12] ethdev: deprecate hard-to-use or ambiguous items and actions Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
                       ` (5 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko, Ray Kinsella

Attributes "ingress" and "egress" can only apply unambiguosly
to non-"transfer" flows. In "transfer" flows, the standpoint
is effectively shifted to the embedded switch. There can be
many different endpoints connected to the switch, so the
use of "ingress" / "egress" does not shed light on which
endpoints precisely can be considered as traffic sources.

Add relevant deprecation notices and suggest the use of precise
traffic source items (PORT_REPRESENTOR and REPRESENTED_PORT).

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/prog_guide/rte_flow.rst     | 28 ++++++++----------
 doc/guides/rel_notes/deprecation.rst   |  9 +++---
 doc/guides/rel_notes/release_21_11.rst |  3 ++
 lib/ethdev/rte_flow.h                  | 41 ++++++++++++++++++++------
 4 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index d7185c49df..5957b8df4f 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -9,8 +9,8 @@ Overview
 --------
 
 This API provides a generic means to configure hardware to match specific
-ingress or egress traffic, alter its fate and query related counters
-according to any number of user-defined rules.
+traffic, alter its fate and query related counters according to any
+number of user-defined rules.
 
 It is named *rte_flow* after the prefix used for all its symbols, and is
 defined in ``rte_flow.h``.
@@ -146,13 +146,10 @@ Note that support for more than a single priority level is not guaranteed.
 Attribute: Traffic direction
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Flow rule patterns apply to inbound and/or outbound traffic.
-
-In the context of this API, **ingress** and **egress** respectively stand
-for **inbound** and **outbound** based on the standpoint of the application
-creating a flow rule.
-
-There are no exceptions to this definition.
+Unless `Attribute: Transfer`_ is specified, flow rule patterns apply
+to inbound and / or outbound traffic. With this respect, ``ingress``
+and ``egress`` respectively stand for **inbound** and **outbound**
+based on the standpoint of the application creating a flow rule.
 
 Several pattern items and actions are valid and can be used in both
 directions. At least one direction must be specified.
@@ -171,12 +168,13 @@ When supported, this effectively enables an application to reroute traffic
 not necessarily intended for it (e.g. coming from or addressed to different
 physical ports, VFs or applications) at the device level.
 
-It complements the behavior of some pattern items such as `Item: PHY_PORT`_
-and is meaningless without them.
-
-When transferring flow rules, **ingress** and **egress** attributes
-(`Attribute: Traffic direction`_) keep their original meaning, as if
-processing traffic emitted or received by the application.
+In "transfer" flows, the use of `Attribute: Traffic direction`_ in the sense of
+implicitly matching packets going to or going from the ethdev used to create
+flow rules is **deprecated**. `Attribute: Transfer`_ shifts the viewpoint to
+the embedded switch. In it, `Attribute: Traffic direction`_ is ambiguous as
+the switch serves many different endpoints. The application should match
+traffic originating from precise locations. To do so, it should
+use `Item: PORT_REPRESENTOR`_ and `Item: REPRESENTED_PORT`_.
 
 Pattern item
 ~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 25aec56bec..ef2e2c1141 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -113,11 +113,6 @@ Deprecation Notices
   to support modifying fields larger than 64 bits.
   In addition, documentation will be updated to clarify byte order.
 
-* ethdev: Flow API documentation is unclear if ethdev port used to create
-  a flow rule adds any implicit match criteria in the case of transfer rules.
-  The semantics will be clarified in DPDK 21.11 and it will require fixes in
-  drivers and applications which interpret it in a different way.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header.
   Some matching pattern structures implements this by duplicating protocol header
@@ -146,6 +141,10 @@ Deprecation Notices
 * ethdev: Items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID`` are
   deprecated as hard-to-use / ambiguous and will be removed in DPDK 22.11.
 
+* ethdev: The use of attributes ``ingress`` / ``egress`` in "transfer" flows
+  is deprecated as ambiguous with respect to the embedded switch. The use of
+  these attributes will become invalid starting from DPDK 22.11.
+
 * net: The structure ``rte_ipv4_hdr`` will have two unions.
   The first union is for existing ``version_ihl`` byte
   and new bitfield for version and IHL.
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 75c4f6d018..45c019eb04 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -257,6 +257,9 @@ API Changes
 * ethdev: Deprecated items and actions ``PF``, ``VF``, ``PHY_PORT``, ``PORT_ID``.
   Suggested items and actions ``PORT_REPRESENTOR``, ``REPRESENTED_PORT`` instead.
 
+* ethdev: Deprecated the use of attributes ``ingress`` / ``egress`` combined
+  with ``transfer``. See items ``PORT_REPRESENTOR``, ``REPRESENTED_PORT``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 76653105a0..7e7b4bce5b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -67,7 +67,10 @@ extern "C" {
  * Note that support for more than a single group and priority level is not
  * guaranteed.
  *
- * Flow rules can apply to inbound and/or outbound traffic (ingress/egress).
+ * At vNIC / ethdev level, flow rules can apply to inbound and / or outbound
+ * traffic (ingress / egress), with respect to the vNIC / ethdev in question.
+ * At embedded switch level, flow rules apply to all traffic seen by it
+ * unless fitting meta items are used to set concrete traffic source(s).
  *
  * Several pattern items and actions are valid and can be used in both
  * directions. Those valid for only one direction are described as such.
@@ -80,8 +83,32 @@ extern "C" {
 struct rte_flow_attr {
 	uint32_t group; /**< Priority group. */
 	uint32_t priority; /**< Rule priority level within group. */
-	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
-	uint32_t egress:1; /**< Rule applies to egress traffic. */
+	/**
+	 * The rule in question applies to ingress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic going from within the embedded switch toward the
+	 * ethdev the flow rule being created through. This behaviour
+	 * is deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t ingress:1;
+	/**
+	 * The rule in question applies to egress traffic (non-"transfer").
+	 *
+	 * @deprecated
+	 * It has been possible to combine this attribute with "transfer".
+	 * Doing so has been assumed to restrict the scope of matching
+	 * to traffic sent by the application by virtue of the ethdev
+	 * the flow rule being created through. This behaviour is now
+	 * deprecated. During the transition period, one may still
+	 * rely on it, but PMDs and applications are encouraged to
+	 * gradually move away from this approach.
+	 */
+	uint32_t egress:1;
 	/**
 	 * Instead of simply matching the properties of traffic as it would
 	 * appear on a given DPDK port ID, enabling this attribute transfers
@@ -93,12 +120,8 @@ struct rte_flow_attr {
 	 * from or addressed to different physical ports, VFs or
 	 * applications) at the device level.
 	 *
-	 * It complements the behavior of some pattern items such as
-	 * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
-	 *
-	 * When transferring flow rules, ingress and egress attributes keep
-	 * their original meaning, as if processing traffic emitted or
-	 * received by the application.
+	 * The application should match traffic originating from precise
+	 * locations. See items PORT_REPRESENTOR and REPRESENTED_PORT.
 	 */
 	uint32_t transfer:1;
 	uint32_t reserved:29; /**< Reserved, must be zero. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 07/12] net/bnxt: support meta flow items to match on traffic source
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                       ` (5 preceding siblings ...)
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 06/12] ethdev: deprecate direction attributes in transfer flows Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 08/12] net/bnxt: support meta flow actions to overrule destinations Ivan Malov
                       ` (4 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko,
	Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for items PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for item PORT_ID.

The use of item PORT_ID depends on the specified direction attribute.
Items PORT_REPRESENTOR and REPRESENTED_PORT, in turn, define traffic
direction themselves. The former matches traffic from the driver's
vNIC. The latter matches packets from either a v-port (network) or
a VF's vNIC (if the driver's port is a VF representor).

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/features/bnxt.ini             |  2 +
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 10 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 77 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 4 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 60cc8bfa15..1b58caa4ac 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -69,6 +69,8 @@ udp                  = Y
 vf                   = Y
 vlan                 = Y
 vxlan                = Y
+port_representor     = Y
+represented_port     = Y
 
 [rte_flow actions]
 count                = Y
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index 9b165c12b5..d28dd2e587 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -266,7 +266,7 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	},
 	[RTE_FLOW_ITEM_TYPE_PORT_ID] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
-	.proto_hdr_func          = ulp_rte_port_id_hdr_handler
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	},
 	[RTE_FLOW_ITEM_TYPE_RAW] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
@@ -427,6 +427,14 @@ struct bnxt_ulp_rte_hdr_info ulp_hdr_info[] = {
 	[RTE_FLOW_ITEM_TYPE_HIGIG2] = {
 	.hdr_type                = BNXT_ULP_HDR_TYPE_NOT_SUPPORTED,
 	.proto_hdr_func          = NULL
+	},
+	[RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
+	},
+	[RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT] = {
+	.hdr_type                = BNXT_ULP_HDR_TYPE_SUPPORTED,
+	.proto_hdr_func          = ulp_rte_port_hdr_handler
 	}
 };
 
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index f1e270af8b..efda522c3e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -400,7 +400,8 @@ bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
 static int32_t
 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 			uint32_t ifindex,
-			uint16_t mask)
+			uint16_t mask,
+			enum bnxt_ulp_direction_type item_dir)
 {
 	uint16_t svif;
 	enum bnxt_ulp_direction_type dir;
@@ -429,11 +430,14 @@ ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
 	bnxt_ulp_rte_parser_direction_compute(params);
 
 	/* Get the computed direction */
-	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_INGRESS) {
+	dir = (item_dir != BNXT_ULP_DIR_INVALID) ? item_dir :
+		ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
+	if (dir == BNXT_ULP_DIR_INGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
 	} else {
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
+		    item_dir != BNXT_ULP_DIR_EGRESS)
 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
 		else
 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
@@ -474,7 +478,8 @@ ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
 	}
 
 	/* Update the SVIF details */
-	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				     BNXT_ULP_DIR_INVALID);
 	return rc;
 }
 
@@ -522,7 +527,8 @@ ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
 	}
 
 	/* Update the SVIF details */
-	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
+	return ulp_rte_parser_svif_set(params, ifindex, svif_mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow item VF Header. */
@@ -555,39 +561,72 @@ ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask,
+				       BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow item port id  Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params)
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params)
 {
-	const struct rte_flow_item_port_id *port_spec = item->spec;
-	const struct rte_flow_item_port_id *port_mask = item->mask;
+	enum bnxt_ulp_direction_type item_dir;
+	uint16_t ethdev_id;
 	uint16_t mask = 0;
 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
 	uint32_t ifindex;
 
-	if (!port_spec) {
-		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
+	if (!item->spec) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port spec is not valid\n");
 		return rc;
 	}
-	if (!port_mask) {
-		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
+	if (!item->mask) {
+		BNXT_TF_DBG(ERR, "ParseErr:Port mask is not valid\n");
+		return rc;
+	}
+
+	switch (item->type) {
+	case RTE_FLOW_ITEM_TYPE_PORT_ID: {
+		const struct rte_flow_item_port_id *port_spec = item->spec;
+		const struct rte_flow_item_port_id *port_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INVALID;
+		ethdev_id = port_spec->id;
+		mask = port_mask->id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_INGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: {
+		const struct rte_flow_item_ethdev *ethdev_spec = item->spec;
+		const struct rte_flow_item_ethdev *ethdev_mask = item->mask;
+
+		item_dir = BNXT_ULP_DIR_EGRESS;
+		ethdev_id = ethdev_spec->port_id;
+		mask = ethdev_mask->port_id;
+		break;
+	}
+	default:
+		BNXT_TF_DBG(ERR, "ParseErr:Unexpected item\n");
 		return rc;
 	}
-	mask = port_mask->id;
 
 	/* perform the conversion from dpdk port to bnxt ifindex */
 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
-					      port_spec->id,
+					      ethdev_id,
 					      &ifindex)) {
 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
 		return rc;
 	}
 	/* Update the SVIF details */
-	return ulp_rte_parser_svif_set(params, ifindex, mask);
+	return ulp_rte_parser_svif_set(params, ifindex, mask, item_dir);
 }
 
 /* Function to handle the parsing of RTE Flow item phy port Header. */
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index e14f86278a..0acb93946b 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -90,10 +90,10 @@ int32_t
 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
 		       struct ulp_rte_parser_params *params);
 
-/* Function to handle the parsing of RTE Flow item port id Header. */
+/* Parse items PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
-			    struct ulp_rte_parser_params *params);
+ulp_rte_port_hdr_handler(const struct rte_flow_item *item,
+			 struct ulp_rte_parser_params *params);
 
 /* Function to handle the parsing of RTE Flow item port Header. */
 int32_t
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 08/12] net/bnxt: support meta flow actions to overrule destinations
  2021-10-13 16:42   ` [dpdk-dev] [PATCH v4 " Ivan Malov
                       ` (6 preceding siblings ...)
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 07/12] net/bnxt: support meta flow items to match on traffic source Ivan Malov
@ 2021-10-13 16:42     ` Ivan Malov
  2021-10-13 16:42     ` [dpdk-dev] [PATCH v4 09/12] net/enic: " Ivan Malov
                       ` (3 subsequent siblings)
  11 siblings, 0 replies; 161+ messages in thread
From: Ivan Malov @ 2021-10-13 16:42 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Thomas Monjalon, Ori Kam, Andrew Rybchenko,
	Ajit Khaparde, Somnath Kotur

From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
based on the existing support for action PORT_ID.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/features/bnxt.ini             |  2 +
 drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c | 12 ++-
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c      | 84 ++++++++++++++-----
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.h      |  6 +-
 4 files changed, 79 insertions(+), 25 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 1b58caa4ac..0a85249155 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -94,3 +94,5 @@ set_tp_src           = Y
 vf                   = Y
 vxlan_decap          = Y
 vxlan_encap          = Y
+port_representor     = Y
+represented_port     = Y
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
index d28dd2e587..e9337ecd2c 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_handler_tbl.c
@@ -67,7 +67,7 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	},
 	[RTE_FLOW_ACTION_TYPE_PORT_ID] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
-	.proto_act_func          = ulp_rte_port_id_act_handler
+	.proto_act_func          = ulp_rte_port_act_handler
 	},
 	[RTE_FLOW_ACTION_TYPE_METER] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_NOT_SUPPORTED,
@@ -212,7 +212,15 @@ struct bnxt_ulp_rte_act_info ulp_act_info[] = {
 	[RTE_FLOW_ACTION_TYPE_SAMPLE] = {
 	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
 	.proto_act_func          = ulp_rte_sample_act_handler
-	}
+	},
+	[RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
+	[RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT] = {
+	.act_type                = BNXT_ULP_ACT_TYPE_SUPPORTED,
+	.proto_act_func          = ulp_rte_port_act_handler
+	},
 };
 
 struct bnxt_ulp_rte_act_info ulp_vendor_act_info[] = {
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index efda522c3e..40da953f06 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -496,10 +496,11 @@ ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
 		return BNXT_TF_RC_SUCCESS;
 	}
 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
+	action_item.type = RTE_FLOW_ACTION_TYPE_PORT_ID;
 	action_item.conf = &port_id;
 
 	/* Update the action port based on incoming port */
-	ulp_rte_port_id_act_handler(&action_item, params);
+	ulp_rte_port_act_handler(&action_item, params);
 
 	/* Reset the action port set bit */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
@@ -2163,7 +2164,8 @@ ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
 /* Function to handle the parsing of action ports. */
 static int32_t
 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
-			    uint32_t ifindex)
+			    uint32_t ifindex,
+			    enum bnxt_ulp_direction_type act_dir)
 {
 	enum bnxt_ulp_direction_type dir;
 	uint16_t pid_s;
@@ -2173,8 +2175,13 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 	uint32_t vnic_type;
 
 	/* Get the direction */
-	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
-	if (dir == BNXT_ULP_DIR_EGRESS) {
+	/* If action implicitly specifies direction, use the specification. */
+	dir = (act_dir == BNXT_ULP_DIR_INVALID) ?
+		ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION) :
+		act_dir;
+	port_type = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
+	if (dir == BNXT_ULP_DIR_EGRESS &&
+	    port_type != BNXT_ULP_INTF_TYPE_VF_REP) {
 		/* For egress direction, fill vport */
 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
 			return BNXT_TF_RC_ERROR;
@@ -2185,9 +2192,17 @@ ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
 	} else {
 		/* For ingress direction, fill vnic */
-		port_type = ULP_COMP_FLD_IDX_RD(param,
-						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
-		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
+		/*
+		 * Action		Destination
+		 * ------------------------------------
+		 * PORT_REPRESENTOR	Driver Function
+		 * ------------------------------------
+		 * REPRESENTED_PORT	VF
+		 * ------------------------------------
+		 * PORT_ID		VF
+		 */
+		if (act_dir != BNXT_ULP_DIR_INGRESS &&
+		    port_type == BNXT_ULP_INTF_TYPE_VF_REP)
 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
 		else
 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
@@ -2234,7 +2249,8 @@ ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
 	}
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
 /* Function to handle the parsing of RTE Flow action VF. */
@@ -2285,31 +2301,59 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 
 	/* Update the action properties */
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
-	return ulp_rte_parser_act_port_set(params, ifindex);
+	return ulp_rte_parser_act_port_set(params, ifindex,
+					   BNXT_ULP_DIR_INVALID);
 }
 
-/* Function to handle the parsing of RTE Flow action port_id. */
+/* Parse actions PORT_ID, PORT_REPRESENTOR and REPRESENTED_PORT. */
 int32_t
-ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
-			    struct ulp_rte_parser_params *param)
+ulp_rte_port_act_handler(const struct rte_flow_action *act_item,
+			 struct ulp_rte_parser_params *param)
 {
-	const struct rte_flow_action_port_id *port_id = act_item->conf;
+	uint32_t ethdev_id;
 	uint32_t ifindex;
 	enum bnxt_ulp_intf_type intf_type;
+	enum bnxt_ulp_direction_type act_dir;
 
-	if (!port_id) {
+	if (!act_item->conf) {
 		BNXT_TF_DBG(ERR,
 			    "ParseErr: Invalid Argument\n");
 		return BNXT_TF_RC_PARSE_ERR;
 	}
-	if (port_id->original) {
-		BNXT_TF_DBG(ERR,
-			    "ParseErr:Portid Original not supported\n");
-		return BNXT_TF_RC_PARSE_ERR;
+	switch (act_item->type) {
+	case RTE_FLOW_ACTION_TYPE_PORT_ID: {
+		const struct rte_flow_action_port_id *port_id = act_item->conf;
+
+		if (port_id->original) {
+			BNXT_TF_DBG(ERR,
+				    "ParseEr