DPDK patches and discussions
 help / color / mirror / Atom feed
* [RFC] ethdev: add template table insertion and matching types
@ 2022-12-14  2:21 Alexander Kozyrev
  2023-01-08 14:22 ` Ori Kam
                   ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2022-12-14  2:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Bring more flexibility and control over both flow rule insertion
and packet matching mechanisms. Introduce 2 new flow table types:

1. Allow a user to specify the insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion to an already existing index is undefined and
depends on PMD implementation. An old rule must be destroyed first.
The index cannot be bigger than the size of the table.

2. Allow a user to specify the hash calculation function used in template
tables. The hash calculation type is responsible for the calculation of
the flow rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst | 20 +++++++
 lib/ethdev/rte_flow.c              | 24 ++++++++
 lib/ethdev/rte_flow.h              | 96 ++++++++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h       | 11 ++++
 lib/ethdev/version.map             |  3 +
 5 files changed, 154 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..7d05acb2db 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3669,6 +3669,26 @@ Enqueueing a flow rule creation operation is similar to simple creation.
 A valid handle in case of success is returned. It must be destroyed later
 by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
 
+Enqueue creation by index operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Enqueueing a flow rule creation operation to insert the rule at a table index.
+
+.. code-block:: c
+
+   struct rte_flow *
+   rte_flow_async_create(uint16_t port_id,
+                         uint32_t queue_id,
+                         const struct rte_flow_op_attr *op_attr,
+                         struct rte_flow_template_table *template_table,
+                         uint32_t rule_index,
+                         const struct rte_flow_action actions[],
+                         uint8_t actions_template_index,
+                         void *user_data,
+                         struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
 Enqueue destruction operation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..013eb355ca 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
 	return flow;
 }
 
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       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);
+	struct rte_flow *flow;
+
+	flow = ops->async_create_by_index(dev, queue_id,
+					  op_attr, template_table, rule_index,
+					  actions, actions_template_index,
+					  user_data, error);
+	if (flow == NULL)
+		flow_err(port_id, -rte_errno, error);
+	return flow;
+}
+
 int
 rte_flow_async_destroy(uint16_t port_id,
 		       uint32_t queue_id,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..858992893c 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_HASH_RESULT,	/**< Hash result. */
 };
 
 /**
@@ -5187,6 +5188,48 @@ rte_flow_actions_template_destroy(uint16_t port_id,
  */
 struct rte_flow_template_table;
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table flow rules insertion type.
+ */
+enum rte_flow_table_insertion_type {
+	/**
+	 * Pattern-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
+	/**
+	 * Index-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table hash index calculation function.
+ */
+enum rte_flow_table_hash_func {
+	/**
+	 * Default hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_DEFAULT,
+	/**
+	 * Linear hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_LINEAR,
+	/*
+	 * 32-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC32,
+	/*
+	 * 16-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC16,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5202,6 +5245,14 @@ struct rte_flow_template_table_attr {
 	 * Maximum number of flow rules that this table holds.
 	 */
 	uint32_t nb_flows;
+	/**
+	 * Insertion type for flow rules.
+	 */
+	enum rte_flow_table_insertion_type insertion_type;
+	/**
+	 * Hash calculation function for the packet matching.
+	 */
+	enum rte_flow_table_hash_func hash_func;
 };
 
 /**
@@ -5336,6 +5387,51 @@ rte_flow_async_create(uint16_t port_id,
 		      void *user_data,
 		      struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] op_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] rule_index
+ *   Rule index in the table.
+ *   Inserting a rule to already occupied index results in undefined behavior.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index c7d0699c91..b5b597dd28 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -221,6 +221,17 @@ struct rte_flow_ops {
 		 uint8_t actions_template_index,
 		 void *user_data,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create_by_index() */
+	struct rte_flow *(*async_create_by_index)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 struct rte_flow_template_table *template_table,
+		 uint32_t rule_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
 	/** See rte_flow_async_destroy() */
 	int (*async_destroy)
 		(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17201fbe0f..dbc2bffe64 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -298,6 +298,9 @@ EXPERIMENTAL {
 	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
+
+	# added in 23.03
+	rte_flow_async_create_by_index;
 };
 
 INTERNAL {
-- 
2.18.2


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

* RE: [RFC] ethdev: add template table insertion and matching types
  2022-12-14  2:21 [RFC] ethdev: add template table insertion and matching types Alexander Kozyrev
@ 2023-01-08 14:22 ` Ori Kam
  2023-01-18  8:50 ` Thomas Monjalon
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
  2 siblings, 0 replies; 31+ messages in thread
From: Ori Kam @ 2023-01-08 14:22 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), ferruh.yigit, andrew.rybchenko

Hi Alexander,

> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Wednesday, 14 December 2022 4:21
> 
> Bring more flexibility and control over both flow rule insertion
> and packet matching mechanisms. Introduce 2 new flow table types:
> 
> 1. Allow a user to specify the insertion type used in template tables.
> The insertion type is responsible for choosing the appropriate key
> value used to map inserted flow rules into a template table.
> 
> Flow rules can be inserted by calculating the hash value for
> the pattern or inserted by index via the new create_by_index() API.
> The idea of the index-based insertion is to avoid additional matches
> and simply execute predefined actions after jumping to the index.
> 
> The insertion to an already existing index is undefined and
> depends on PMD implementation. An old rule must be destroyed first.
> The index cannot be bigger than the size of the table.
> 
> 2. Allow a user to specify the hash calculation function used in template
> tables. The hash calculation type is responsible for the calculation of
> the flow rule index a packet would hit upon arrival at the table.
> 
> Control over this is useful for applications with custom RSS algorithms,
> for example. An application can select various packet fields to serve as
> a hash calculation source and jump to the appropriate flow rule location.
> The RSS hash result will be used as the index in the table. For the linear
> hash function, the mapping is one-to-one and the hash result is the index.
> For other hash functions, the index is the hash result module table size.
> The RSS hash result can be retrieved via modify_field API: HASH_RESULT.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
> ---

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

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

* Re: [RFC] ethdev: add template table insertion and matching types
  2022-12-14  2:21 [RFC] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-01-08 14:22 ` Ori Kam
@ 2023-01-18  8:50 ` Thomas Monjalon
  2023-01-20 23:06   ` Alexander Kozyrev
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
  2 siblings, 1 reply; 31+ messages in thread
From: Thomas Monjalon @ 2023-01-18  8:50 UTC (permalink / raw)
  To: Alexander Kozyrev; +Cc: dev, ferruh.yigit, andrew.rybchenko, orika

14/12/2022 03:21, Alexander Kozyrev:
> Bring more flexibility and control over both flow rule insertion
> and packet matching mechanisms. Introduce 2 new flow table types:
> 
> 1. Allow a user to specify the insertion type used in template tables.
> The insertion type is responsible for choosing the appropriate key
> value used to map inserted flow rules into a template table.
> 
> Flow rules can be inserted by calculating the hash value for
> the pattern or inserted by index via the new create_by_index() API.
> The idea of the index-based insertion is to avoid additional matches
> and simply execute predefined actions after jumping to the index.

I don't understand the idea.
Why is it avoiding additional matches?

> The insertion to an already existing index is undefined and

Why is it undefined?

> depends on PMD implementation. An old rule must be destroyed first.
> The index cannot be bigger than the size of the table.
> 
> 2. Allow a user to specify the hash calculation function used in template
> tables. The hash calculation type is responsible for the calculation of
> the flow rule index a packet would hit upon arrival at the table.
> 
> Control over this is useful for applications with custom RSS algorithms,
> for example. An application can select various packet fields to serve as
> a hash calculation source and jump to the appropriate flow rule location.
> The RSS hash result will be used as the index in the table. For the linear
> hash function, the mapping is one-to-one and the hash result is the index.
> For other hash functions, the index is the hash result module table size.
> The RSS hash result can be retrieved via modify_field API: HASH_RESULT.
> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst | 20 +++++++
>  lib/ethdev/rte_flow.c              | 24 ++++++++
>  lib/ethdev/rte_flow.h              | 96 ++++++++++++++++++++++++++++++
>  lib/ethdev/rte_flow_driver.h       | 11 ++++
>  lib/ethdev/version.map             |  3 +
>  5 files changed, 154 insertions(+)

Is there a PMD implementation available on the mailing list?
This is required to accept a new API.



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

* RE: [RFC] ethdev: add template table insertion and matching types
  2023-01-18  8:50 ` Thomas Monjalon
@ 2023-01-20 23:06   ` Alexander Kozyrev
  2023-01-22 20:55     ` Thomas Monjalon
  0 siblings, 1 reply; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-20 23:06 UTC (permalink / raw)
  To: NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: dev, ferruh.yigit, andrew.rybchenko, Ori Kam

> 14/12/2022 03:21, Alexander Kozyrev:
> > Bring more flexibility and control over both flow rule insertion
> > and packet matching mechanisms. Introduce 2 new flow table types:
> >
> > 1. Allow a user to specify the insertion type used in template tables.
> > The insertion type is responsible for choosing the appropriate key
> > value used to map inserted flow rules into a template table.
> >
> > Flow rules can be inserted by calculating the hash value for
> > the pattern or inserted by index via the new create_by_index() API.
> > The idea of the index-based insertion is to avoid additional matches
> > and simply execute predefined actions after jumping to the index.
> 
> I don't understand the idea.
> Why is it avoiding additional matches?

If you jump directly to an index in a table, you don't need to match anything.
For the regular pattern-based table you must calculate the hash and match on it.

> > The insertion to an already existing index is undefined and
> 
> Why is it undefined?

The behavior is up to a PMD to decide. It is free to replace the rule or throw an error.

> > depends on PMD implementation. An old rule must be destroyed first.
> > The index cannot be bigger than the size of the table.
> >
> > 2. Allow a user to specify the hash calculation function used in template
> > tables. The hash calculation type is responsible for the calculation of
> > the flow rule index a packet would hit upon arrival at the table.
> >
> > Control over this is useful for applications with custom RSS algorithms,
> > for example. An application can select various packet fields to serve as
> > a hash calculation source and jump to the appropriate flow rule location.
> > The RSS hash result will be used as the index in the table. For the linear
> > hash function, the mapping is one-to-one and the hash result is the index.
> > For other hash functions, the index is the hash result module table size.
> > The RSS hash result can be retrieved via modify_field API: HASH_RESULT.
> >
> > Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
> > ---
> >  doc/guides/prog_guide/rte_flow.rst | 20 +++++++
> >  lib/ethdev/rte_flow.c              | 24 ++++++++
> >  lib/ethdev/rte_flow.h              | 96 ++++++++++++++++++++++++++++++
> >  lib/ethdev/rte_flow_driver.h       | 11 ++++
> >  lib/ethdev/version.map             |  3 +
> >  5 files changed, 154 insertions(+)
> 
> Is there a PMD implementation available on the mailing list?
> This is required to accept a new API.

This is RFC. PMD implementation will follow in a v1 patches shortly.


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

* [PATCH 0/4] ethdev: add template table insertion and matching types
  2022-12-14  2:21 [RFC] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-01-08 14:22 ` Ori Kam
  2023-01-18  8:50 ` Thomas Monjalon
@ 2023-01-21  5:21 ` Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 1/4] ethdev: add template table insertion type Alexander Kozyrev
                     ` (4 more replies)
  2 siblings, 5 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-21  5:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Bring more flexibility and control over both flow rule insertion
and packet matching mechanisms. Introduce 2 new flow table types:

1. Allow a user to specify the insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion to an already existing index is undefined and
depends on PMD implementation. An old rule must be destroyed first.
The index cannot be bigger than the size of the table.

2. Allow a user to specify the hash calculation function used in template
tables. The hash calculation type is responsible for the calculation of
the flow rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

RFC: https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-akozyrev@nvidia.com/
PMD implementation will follow shortly.

Alexander Kozyrev (4):
  ethdev: add template table insertion type
  ethdev: add template table hash calculation function
  app/testpmd: add template table insertion type
  app/testpmd: add template table hash calculation function

 app/test-pmd/cmdline_flow.c            | 166 +++++++++++++++++++++++--
 app/test-pmd/config.c                  |  10 +-
 app/test-pmd/testpmd.h                 |   2 +-
 doc/guides/prog_guide/rte_flow.rst     |  20 +++
 doc/guides/rel_notes/release_23_03.rst |  11 ++
 lib/ethdev/rte_flow.c                  |  24 ++++
 lib/ethdev/rte_flow.h                  |  96 ++++++++++++++
 lib/ethdev/rte_flow_driver.h           |  11 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 332 insertions(+), 11 deletions(-)

-- 
2.18.2


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

* [PATCH 1/4] ethdev: add template table insertion type
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
@ 2023-01-21  5:21   ` Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-21  5:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify insertion type used in template tables.
The insertion type is responsible for choosing appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via new create_by_index() API.
The idea of the index-based insertion is to avoid additional match
and simply execute predefined actions after jumping to the index.

The insertion to already existing index is undefined and
depends on PMD implementation. Old rule must be destroyed first.
Index cannot be bigger than the size of the table.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     | 20 ++++++++
 doc/guides/rel_notes/release_23_03.rst |  7 +++
 lib/ethdev/rte_flow.c                  | 24 ++++++++++
 lib/ethdev/rte_flow.h                  | 66 ++++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h           | 11 +++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 131 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..7d05acb2db 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3669,6 +3669,26 @@ Enqueueing a flow rule creation operation is similar to simple creation.
 A valid handle in case of success is returned. It must be destroyed later
 by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
 
+Enqueue creation by index operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Enqueueing a flow rule creation operation to insert the rule at a table index.
+
+.. code-block:: c
+
+   struct rte_flow *
+   rte_flow_async_create(uint16_t port_id,
+                         uint32_t queue_id,
+                         const struct rte_flow_op_attr *op_attr,
+                         struct rte_flow_template_table *template_table,
+                         uint32_t rule_index,
+                         const struct rte_flow_action actions[],
+                         uint8_t actions_template_index,
+                         void *user_data,
+                         struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
 Enqueue destruction operation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..13dd368f2e 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -56,6 +56,13 @@ New Features
      =======================================================
 
 
+* **Added index-based rules insertion in flow API.**
+
+  Added ``rte_flow_table_insertion_type`` to allow the creation
+  of index-based template tables in addition to pattern-based tables.
+  Introduced new function ``rte_flow_async_create_by_index()``
+  to insert rules by index into index-based template tables.
+
 Removed Items
 -------------
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..013eb355ca 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
 	return flow;
 }
 
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       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);
+	struct rte_flow *flow;
+
+	flow = ops->async_create_by_index(dev, queue_id,
+					  op_attr, template_table, rule_index,
+					  actions, actions_template_index,
+					  user_data, error);
+	if (flow == NULL)
+		flow_err(port_id, -rte_errno, error);
+	return flow;
+}
+
 int
 rte_flow_async_destroy(uint16_t port_id,
 		       uint32_t queue_id,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..88d0c6a724 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t port_id,
  */
 struct rte_flow_template_table;
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table flow rules insertion type.
+ */
+enum rte_flow_table_insertion_type {
+	/**
+	 * Pattern-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
+	/**
+	 * Index-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
 	 * Maximum number of flow rules that this table holds.
 	 */
 	uint32_t nb_flows;
+	/**
+	 * Insertion type for flow rules.
+	 */
+	enum rte_flow_table_insertion_type insertion_type;
 };
 
 /**
@@ -5336,6 +5357,51 @@ rte_flow_async_create(uint16_t port_id,
 		      void *user_data,
 		      struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] op_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] rule_index
+ *   Rule index in the table.
+ *   Inserting a rule to already occupied index results in undefined behavior.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index c7d0699c91..b5b597dd28 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -221,6 +221,17 @@ struct rte_flow_ops {
 		 uint8_t actions_template_index,
 		 void *user_data,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create_by_index() */
+	struct rte_flow *(*async_create_by_index)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 struct rte_flow_template_table *template_table,
+		 uint32_t rule_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
 	/** See rte_flow_async_destroy() */
 	int (*async_destroy)
 		(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17201fbe0f..dbc2bffe64 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -298,6 +298,9 @@ EXPERIMENTAL {
 	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
+
+	# added in 23.03
+	rte_flow_async_create_by_index;
 };
 
 INTERNAL {
-- 
2.18.2


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

* [PATCH 2/4] ethdev: add template table hash calculation function
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 1/4] ethdev: add template table insertion type Alexander Kozyrev
@ 2023-01-21  5:21   ` Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-21  5:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify hash calculation function used in template tables.
The hash calculation type is responsible for the calculation of the flow
rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_23_03.rst |  4 ++++
 lib/ethdev/rte_flow.h                  | 30 ++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index 13dd368f2e..0535205c8b 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -63,6 +63,10 @@ New Features
   Introduced new function ``rte_flow_async_create_by_index()``
   to insert rules by index into index-based template tables.
 
+* **Added index-based rules insertion in flow API.**
+  Added hash calculation function used in template tables
+  to allow control over the calculation of the rule index for a packet.
+
 Removed Items
 -------------
 
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 88d0c6a724..0c793bce8a 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_HASH_RESULT,	/**< Hash result. */
 };
 
 /**
@@ -5204,6 +5205,31 @@ enum rte_flow_table_insertion_type {
 	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table hash index calculation function.
+ */
+enum rte_flow_table_hash_func {
+	/**
+	 * Default hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_DEFAULT,
+	/**
+	 * Linear hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_LINEAR,
+	/**
+	 * 32-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC32,
+	/**
+	 * 16-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC16,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5223,6 +5249,10 @@ struct rte_flow_template_table_attr {
 	 * Insertion type for flow rules.
 	 */
 	enum rte_flow_table_insertion_type insertion_type;
+	/**
+	 * Hash calculation function for the packet matching.
+	 */
+	enum rte_flow_table_hash_func hash_func;
 };
 
 /**
-- 
2.18.2


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

* [PATCH 3/4] app/testpmd: add template table insertion type
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 1/4] ethdev: add template table insertion type Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
@ 2023-01-21  5:21   ` Alexander Kozyrev
  2023-01-21  5:21   ` [PATCH 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-21  5:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for specifying a template table insertion type.
Available types are: pattern and index.
flow template_table 0 create table_id 0 insertion_type index ...
Allow specifying the rule index instead of the pattern template index:
flow queue 0 create 0 template_table 0 rule_index 5 actions_template 0 ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 97 ++++++++++++++++++++++++++++++++++---
 app/test-pmd/config.c       | 10 ++--
 app/test-pmd/testpmd.h      |  2 +-
 3 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..f1d6813baa 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -133,12 +133,11 @@ enum index {
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
-	QUEUE_CREATE_ID,
 	QUEUE_CREATE_POSTPONE,
 	QUEUE_TEMPLATE_TABLE,
 	QUEUE_PATTERN_TEMPLATE,
 	QUEUE_ACTIONS_TEMPLATE,
-	QUEUE_SPEC,
+	QUEUE_RULE_ID,
 
 	/* Queue destroy arguments. */
 	QUEUE_DESTROY_ID,
@@ -179,6 +178,8 @@ enum index {
 	TABLE_DESTROY,
 	TABLE_CREATE_ID,
 	TABLE_DESTROY_ID,
+	TABLE_INSERTION_TYPE,
+	TABLE_INSERTION_TYPE_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -814,6 +815,12 @@ static const char *const meter_colors[] = {
 	"green", "yellow", "red", "all", NULL
 };
 
+static const char *const table_insertion_types[] = {
+	"pattern", "index", NULL
+};
+
+#define RAW_IPSEC_CONFS_MAX_NUM 8
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -1015,6 +1022,7 @@ struct buffer {
 		struct {
 			uint32_t table_id;
 			uint32_t pat_templ_id;
+			uint32_t rule_id;
 			uint32_t act_templ_id;
 			struct rte_flow_attr attr;
 			struct tunnel_ops tunnel_ops;
@@ -1154,6 +1162,7 @@ static const enum index next_table_subcmd[] = {
 static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
+	TABLE_INSERTION_TYPE,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -1287,6 +1296,12 @@ static const enum index next_ia_destroy_attr[] = {
 	ZERO,
 };
 
+static const enum index next_async_insert_subcmd[] = {
+	QUEUE_PATTERN_TEMPLATE,
+	QUEUE_RULE_ID,
+	ZERO,
+};
+
 static const enum index item_param[] = {
 	ITEM_PARAM_IS,
 	ITEM_PARAM_SPEC,
@@ -2399,6 +2414,9 @@ static int parse_meter_policy_id2ptr(struct context *ctx,
 static int parse_meter_color(struct context *ctx, const struct token *token,
 			     const char *str, unsigned int len, void *buf,
 			     unsigned int size);
+static int parse_insertion_table_type(struct context *ctx, const struct token *token,
+				      const char *str, unsigned int len, void *buf,
+				      unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2431,6 +2449,8 @@ static int comp_queue_id(struct context *, const struct token *,
 			 unsigned int, char *, unsigned int);
 static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
+static int comp_insertion_table_type(struct context *, const struct token *,
+				     unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2901,6 +2921,20 @@ static const struct token token_list[] = {
 					    args.table_destroy.table_id)),
 		.call = parse_table_destroy,
 	},
+	[TABLE_INSERTION_TYPE] = {
+		.name = "insertion_type",
+		.help = "specify insertion type",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.insertion_type)),
+	},
+	[TABLE_INSERTION_TYPE_NAME] = {
+		.name = "insertion_type_name",
+		.help = "insertion type name",
+		.call = parse_insertion_table_type,
+		.comp = comp_insertion_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -3002,7 +3036,7 @@ static const struct token token_list[] = {
 	[QUEUE_TEMPLATE_TABLE] = {
 		.name = "template_table",
 		.help = "specify table id",
-		.next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE),
+		.next = NEXT(next_async_insert_subcmd,
 			     NEXT_ENTRY(COMMON_TABLE_ID)),
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.vc.table_id)),
@@ -3026,6 +3060,15 @@ static const struct token token_list[] = {
 					args.vc.act_templ_id)),
 		.call = parse_qo,
 	},
+	[QUEUE_RULE_ID] = {
+		.name = "rule_index",
+		.help = "specify flow rule index",
+		.next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE),
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.vc.rule_id)),
+		.call = parse_qo,
+	},
 	[QUEUE_CREATE_POSTPONE] = {
 		.name = "postpone",
 		.help = "postpone create operation",
@@ -9069,11 +9112,13 @@ parse_qo(struct context *ctx, const struct token *token,
 		ctx->objdata = 0;
 		ctx->object = out;
 		ctx->objmask = NULL;
+		out->args.vc.rule_id = UINT32_MAX;
 		return len;
 	case QUEUE_TEMPLATE_TABLE:
 	case QUEUE_PATTERN_TEMPLATE:
 	case QUEUE_ACTIONS_TEMPLATE:
 	case QUEUE_CREATE_POSTPONE:
+	case QUEUE_RULE_ID:
 		return len;
 	case ITEM_PATTERN:
 		out->args.vc.pattern =
@@ -10052,6 +10097,32 @@ parse_meter_color(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse Insertion Table Type name */
+static int
+parse_insertion_table_type(struct context *ctx, const struct token *token,
+			   const char *str, unsigned int len, void *buf,
+			   unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_insertion_types[i]; ++i)
+		if (!strcmp_partial(table_insertion_types[i], str, len))
+			break;
+	if (!table_insertion_types[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10357,6 +10428,20 @@ comp_meter_color(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Insertion Table types. */
+static int
+comp_insertion_table_type(struct context *ctx, const struct token *token,
+			  unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_insertion_types);
+	if (ent < RTE_DIM(table_insertion_types) - 1)
+		return rte_strscpy(buf, table_insertion_types[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
@@ -10670,9 +10755,9 @@ cmd_flow_parsed(const struct buffer *in)
 		break;
 	case QUEUE_CREATE:
 		port_queue_flow_create(in->port, in->queue, in->postpone,
-				       in->args.vc.table_id, in->args.vc.pat_templ_id,
-				       in->args.vc.act_templ_id, in->args.vc.pattern,
-				       in->args.vc.actions);
+			in->args.vc.table_id, in->args.vc.rule_id,
+			in->args.vc.pat_templ_id, in->args.vc.act_templ_id,
+			in->args.vc.pattern, in->args.vc.actions);
 		break;
 	case QUEUE_DESTROY:
 		port_queue_flow_destroy(in->port, in->queue, in->postpone,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index acccb6b035..41484c3dde 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2609,7 +2609,7 @@ port_flow_template_table_flush(portid_t port_id)
 /** Enqueue create flow rule operation. */
 int
 port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-		       bool postpone, uint32_t table_id,
+		       bool postpone, uint32_t table_id, uint32_t rule_idx,
 		       uint32_t pattern_idx, uint32_t actions_idx,
 		       const struct rte_flow_item *pattern,
 		       const struct rte_flow_action *actions)
@@ -2685,8 +2685,12 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
 	}
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
-	flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
-		pattern, pattern_idx, actions, actions_idx, job, &error);
+	if (rule_idx == UINT32_MAX)
+		flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
+			pattern, pattern_idx, actions, actions_idx, job, &error);
+	else
+		flow = rte_flow_async_create_by_index(port_id, queue_id, &op_attr, pt->table,
+			rule_idx, actions, actions_idx, job, &error);
 	if (!flow) {
 		uint32_t flow_id = pf->id;
 		port_queue_flow_destroy(port_id, queue_id, true, 1, &flow_id);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 7d24d25970..22d02a742c 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -930,7 +930,7 @@ int port_flow_template_table_destroy(portid_t port_id,
 			    uint32_t n, const uint32_t *table);
 int port_flow_template_table_flush(portid_t port_id);
 int port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-			   bool postpone, uint32_t table_id,
+			   bool postpone, uint32_t table_id, uint32_t rule_idx,
 			   uint32_t pattern_idx, uint32_t actions_idx,
 			   const struct rte_flow_item *pattern,
 			   const struct rte_flow_action *actions);
-- 
2.18.2


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

* [PATCH 4/4] app/testpmd: add template table hash calculation function
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
                     ` (2 preceding siblings ...)
  2023-01-21  5:21   ` [PATCH 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
@ 2023-01-21  5:21   ` Alexander Kozyrev
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-21  5:21 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for a template table hash function.
Available types are: default, linear, crc32 and crc16.
flow template_table 0 create table_id 0 hash_func linear ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 69 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f1d6813baa..007d31c5cf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -180,6 +180,8 @@ enum index {
 	TABLE_DESTROY_ID,
 	TABLE_INSERTION_TYPE,
 	TABLE_INSERTION_TYPE_NAME,
+	TABLE_HASH_FUNC,
+	TABLE_HASH_FUNC_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -808,7 +810,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"hash_result", NULL
 };
 
 static const char *const meter_colors[] = {
@@ -819,6 +822,10 @@ static const char *const table_insertion_types[] = {
 	"pattern", "index", NULL
 };
 
+static const char *const table_hash_funcs[] = {
+	"default", "linear", "crc32", "crc16", NULL
+};
+
 #define RAW_IPSEC_CONFS_MAX_NUM 8
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1163,6 +1170,7 @@ static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
 	TABLE_INSERTION_TYPE,
+	TABLE_HASH_FUNC,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -2417,6 +2425,9 @@ static int parse_meter_color(struct context *ctx, const struct token *token,
 static int parse_insertion_table_type(struct context *ctx, const struct token *token,
 				      const char *str, unsigned int len, void *buf,
 				      unsigned int size);
+static int parse_hash_table_type(struct context *ctx, const struct token *token,
+				 const char *str, unsigned int len, void *buf,
+				 unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2451,6 +2462,8 @@ static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
 static int comp_insertion_table_type(struct context *, const struct token *,
 				     unsigned int, char *, unsigned int);
+static int comp_hash_table_type(struct context *, const struct token *,
+				unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2935,6 +2948,20 @@ static const struct token token_list[] = {
 		.call = parse_insertion_table_type,
 		.comp = comp_insertion_table_type,
 	},
+	[TABLE_HASH_FUNC] = {
+		.name = "hash_func",
+		.help = "specify hash calculation function",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_HASH_FUNC_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.hash_func)),
+	},
+	[TABLE_HASH_FUNC_NAME] = {
+		.name = "hash_func_name",
+		.help = "hash calculation function name",
+		.call = parse_hash_table_type,
+		.comp = comp_hash_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -10123,6 +10150,32 @@ parse_insertion_table_type(struct context *ctx, const struct token *token,
 	return ret > 0 ? (int)len : ret;
 }
 
+/** Parse Hash Calculation Table Type name */
+static int
+parse_hash_table_type(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len, void *buf,
+		      unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_hash_funcs[i]; ++i)
+		if (!strcmp_partial(table_hash_funcs[i], str, len))
+			break;
+	if (!table_hash_funcs[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10442,6 +10495,20 @@ comp_insertion_table_type(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Hash Calculation Table types. */
+static int
+comp_hash_table_type(struct context *ctx, const struct token *token,
+		     unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_hash_funcs);
+	if (ent < RTE_DIM(table_hash_funcs) - 1)
+		return rte_strscpy(buf, table_hash_funcs[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
-- 
2.18.2


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

* Re: [RFC] ethdev: add template table insertion and matching types
  2023-01-20 23:06   ` Alexander Kozyrev
@ 2023-01-22 20:55     ` Thomas Monjalon
  2023-01-23 22:02       ` Alexander Kozyrev
  0 siblings, 1 reply; 31+ messages in thread
From: Thomas Monjalon @ 2023-01-22 20:55 UTC (permalink / raw)
  To: Alexander Kozyrev; +Cc: dev, ferruh.yigit, andrew.rybchenko, Ori Kam

21/01/2023 00:06, Alexander Kozyrev:
> > 14/12/2022 03:21, Alexander Kozyrev:
> > > Bring more flexibility and control over both flow rule insertion
> > > and packet matching mechanisms. Introduce 2 new flow table types:
> > >
> > > 1. Allow a user to specify the insertion type used in template tables.
> > > The insertion type is responsible for choosing the appropriate key
> > > value used to map inserted flow rules into a template table.
> > >
> > > Flow rules can be inserted by calculating the hash value for
> > > the pattern or inserted by index via the new create_by_index() API.
> > > The idea of the index-based insertion is to avoid additional matches
> > > and simply execute predefined actions after jumping to the index.
> > 
> > I don't understand the idea.
> > Why is it avoiding additional matches?
> 
> If you jump directly to an index in a table, you don't need to match anything.
> For the regular pattern-based table you must calculate the hash and match on it.

I don't get it. I think it would be simpler with an example.

> > > The insertion to an already existing index is undefined and
> > 
> > Why is it undefined?
> 
> The behavior is up to a PMD to decide. It is free to replace the rule or throw an error.

An undefined behavior of an API makes applications not portable.
Why not deciding of a behavior? You are not sure what is best?




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

* RE: [RFC] ethdev: add template table insertion and matching types
  2023-01-22 20:55     ` Thomas Monjalon
@ 2023-01-23 22:02       ` Alexander Kozyrev
  2023-01-30 14:47         ` Thomas Monjalon
  0 siblings, 1 reply; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-23 22:02 UTC (permalink / raw)
  To: NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: dev, ferruh.yigit, andrew.rybchenko, Ori Kam

> 21/01/2023 00:06, Alexander Kozyrev:
> > > 14/12/2022 03:21, Alexander Kozyrev:
> > > > Bring more flexibility and control over both flow rule insertion
> > > > and packet matching mechanisms. Introduce 2 new flow table types:
> > > >
> > > > 1. Allow a user to specify the insertion type used in template tables.
> > > > The insertion type is responsible for choosing the appropriate key
> > > > value used to map inserted flow rules into a template table.
> > > >
> > > > Flow rules can be inserted by calculating the hash value for
> > > > the pattern or inserted by index via the new create_by_index() API.
> > > > The idea of the index-based insertion is to avoid additional matches
> > > > and simply execute predefined actions after jumping to the index.
> > >
> > > I don't understand the idea.
> > > Why is it avoiding additional matches?
> >
> > If you jump directly to an index in a table, you don't need to match
> anything.
> > For the regular pattern-based table you must calculate the hash and match
> on it.
> 
> I don't get it. I think it would be simpler with an example.

This is how the regular pattern-based table works:
you calculate hash on 5-tuple, go to the table entry with the corresponding hash,
check if there is a collision and search for the proper entry if so, execute actions.
Index-based table:
take an index value from a specified field, go to this index, and execute actions.

> > > > The insertion to an already existing index is undefined and
> > >
> > > Why is it undefined?
> >
> > The behavior is up to a PMD to decide. It is free to replace the rule or throw
> an error.
> 
> An undefined behavior of an API makes applications not portable.
> Why not deciding of a behavior? You are not sure what is best?

We don't want to restrict a PMD behavior here. 
Personally, I would prefer throwing an error in this case.
Do you think returning EEXIST is better?


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

* [PATCH v2 0/4] ethdev: add template table insertion and matching types
  2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
                     ` (3 preceding siblings ...)
  2023-01-21  5:21   ` [PATCH 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
@ 2023-01-26 23:27   ` Alexander Kozyrev
  2023-01-26 23:27     ` [PATCH v2 1/4] ethdev: add template table insertion type Alexander Kozyrev
                       ` (5 more replies)
  4 siblings, 6 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-26 23:27 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Bring more flexibility and control over both flow rule insertion
and packet matching mechanisms. Introduce 2 new flow table types:

1. Allow a user to specify the insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

2. Allow a user to specify the hash calculation function used in template
tables. The hash calculation type is responsible for the calculation of
the flow rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

RFC: https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-akozyrev@nvidia.com/
v2: changed the behavior in case of insertion into the same index.
 
Alexander Kozyrev (4):
  ethdev: add template table insertion type
  ethdev: add template table hash calculation function
  app/testpmd: add template table insertion type
  app/testpmd: add template table hash calculation function

 app/test-pmd/cmdline_flow.c            | 166 +++++++++++++++++++++++--
 app/test-pmd/config.c                  |  10 +-
 app/test-pmd/testpmd.h                 |   2 +-
 doc/guides/prog_guide/rte_flow.rst     |  20 +++
 doc/guides/rel_notes/release_23_03.rst |  10 ++
 lib/ethdev/rte_flow.c                  |  24 ++++
 lib/ethdev/rte_flow.h                  |  95 ++++++++++++++
 lib/ethdev/rte_flow_driver.h           |  11 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 330 insertions(+), 11 deletions(-)

-- 
2.18.2


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

* [PATCH v2 1/4] ethdev: add template table insertion type
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
@ 2023-01-26 23:27     ` Alexander Kozyrev
  2023-02-02 10:57       ` Andrew Rybchenko
  2023-01-26 23:28     ` [PATCH v2 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-26 23:27 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     | 20 ++++++++
 doc/guides/rel_notes/release_23_03.rst |  6 +++
 lib/ethdev/rte_flow.c                  | 24 ++++++++++
 lib/ethdev/rte_flow.h                  | 65 ++++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h           | 11 +++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 129 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..fbed7da9d8 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3669,6 +3669,26 @@ Enqueueing a flow rule creation operation is similar to simple creation.
 A valid handle in case of success is returned. It must be destroyed later
 by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
 
+Enqueue creation by index operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Enqueueing a flow rule creation operation to insert a rule at a table index.
+
+.. code-block:: c
+
+   struct rte_flow *
+   rte_flow_async_create_by_index(uint16_t port_id,
+                                  uint32_t queue_id,
+                                  const struct rte_flow_op_attr *op_attr,
+                                  struct rte_flow_template_table *template_table,
+                                  uint32_t rule_index,
+                                  const struct rte_flow_action actions[],
+                                  uint8_t actions_template_index,
+                                  void *user_data,
+                                  struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
 Enqueue destruction operation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..fa9391de2b 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,12 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added index-based rules insertion in flow API.**
+
+  Added ``rte_flow_table_insertion_type`` to allow the creation
+  of index-based template tables in addition to pattern-based tables.
+  Introduced new function ``rte_flow_async_create_by_index()``
+  to insert rules by index into index-based template tables.
 
 Removed Items
 -------------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..013eb355ca 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
 	return flow;
 }
 
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       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);
+	struct rte_flow *flow;
+
+	flow = ops->async_create_by_index(dev, queue_id,
+					  op_attr, template_table, rule_index,
+					  actions, actions_template_index,
+					  user_data, error);
+	if (flow == NULL)
+		flow_err(port_id, -rte_errno, error);
+	return flow;
+}
+
 int
 rte_flow_async_destroy(uint16_t port_id,
 		       uint32_t queue_id,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..2ba616eeb1 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t port_id,
  */
 struct rte_flow_template_table;
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table flow rules insertion type.
+ */
+enum rte_flow_table_insertion_type {
+	/**
+	 * Pattern-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
+	/**
+	 * Index-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
 	 * Maximum number of flow rules that this table holds.
 	 */
 	uint32_t nb_flows;
+	/**
+	 * Insertion type for flow rules.
+	 */
+	enum rte_flow_table_insertion_type insertion_type;
 };
 
 /**
@@ -5336,6 +5357,50 @@ rte_flow_async_create(uint16_t port_id,
 		      void *user_data,
 		      struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] op_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] rule_index
+ *   Rule index in the table.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index c7d0699c91..b5b597dd28 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -221,6 +221,17 @@ struct rte_flow_ops {
 		 uint8_t actions_template_index,
 		 void *user_data,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create_by_index() */
+	struct rte_flow *(*async_create_by_index)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 struct rte_flow_template_table *template_table,
+		 uint32_t rule_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
 	/** See rte_flow_async_destroy() */
 	int (*async_destroy)
 		(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17201fbe0f..dbc2bffe64 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -298,6 +298,9 @@ EXPERIMENTAL {
 	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
+
+	# added in 23.03
+	rte_flow_async_create_by_index;
 };
 
 INTERNAL {
-- 
2.18.2


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

* [PATCH v2 2/4] ethdev: add template table hash calculation function
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-01-26 23:27     ` [PATCH v2 1/4] ethdev: add template table insertion type Alexander Kozyrev
@ 2023-01-26 23:28     ` Alexander Kozyrev
  2023-01-26 23:28     ` [PATCH v2 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-26 23:28 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify hash calculation function used in template tables.
The hash calculation type is responsible for the calculation of the flow
rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_23_03.rst |  4 ++++
 lib/ethdev/rte_flow.h                  | 30 ++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index fa9391de2b..6f7c38ec66 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -76,6 +76,10 @@ New Features
   Introduced new function ``rte_flow_async_create_by_index()``
   to insert rules by index into index-based template tables.
 
+* **Added index-based rules insertion in flow API.**
+  Added hash calculation function used in template tables
+  to allow control over the calculation of the rule index for a packet.
+
 Removed Items
 -------------
 
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 2ba616eeb1..6ce61e3f53 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_HASH_RESULT,	/**< Hash result. */
 };
 
 /**
@@ -5204,6 +5205,31 @@ enum rte_flow_table_insertion_type {
 	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table hash index calculation function.
+ */
+enum rte_flow_table_hash_func {
+	/**
+	 * Default hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_DEFAULT,
+	/**
+	 * Linear hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_LINEAR,
+	/**
+	 * 32-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC32,
+	/**
+	 * 16-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC16,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5223,6 +5249,10 @@ struct rte_flow_template_table_attr {
 	 * Insertion type for flow rules.
 	 */
 	enum rte_flow_table_insertion_type insertion_type;
+	/**
+	 * Hash calculation function for the packet matching.
+	 */
+	enum rte_flow_table_hash_func hash_func;
 };
 
 /**
-- 
2.18.2


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

* [PATCH v2 3/4] app/testpmd: add template table insertion type
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-01-26 23:27     ` [PATCH v2 1/4] ethdev: add template table insertion type Alexander Kozyrev
  2023-01-26 23:28     ` [PATCH v2 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
@ 2023-01-26 23:28     ` Alexander Kozyrev
  2023-01-26 23:28     ` [PATCH v2 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-26 23:28 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for specifying a template table insertion type.
Available types are: pattern and index.
flow template_table 0 create table_id 0 insertion_type index ...
Allow specifying the rule index instead of the pattern template index:
flow queue 0 create 0 template_table 0 rule_index 5 actions_template 0 ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 97 ++++++++++++++++++++++++++++++++++---
 app/test-pmd/config.c       | 10 ++--
 app/test-pmd/testpmd.h      |  2 +-
 3 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..f1d6813baa 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -133,12 +133,11 @@ enum index {
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
-	QUEUE_CREATE_ID,
 	QUEUE_CREATE_POSTPONE,
 	QUEUE_TEMPLATE_TABLE,
 	QUEUE_PATTERN_TEMPLATE,
 	QUEUE_ACTIONS_TEMPLATE,
-	QUEUE_SPEC,
+	QUEUE_RULE_ID,
 
 	/* Queue destroy arguments. */
 	QUEUE_DESTROY_ID,
@@ -179,6 +178,8 @@ enum index {
 	TABLE_DESTROY,
 	TABLE_CREATE_ID,
 	TABLE_DESTROY_ID,
+	TABLE_INSERTION_TYPE,
+	TABLE_INSERTION_TYPE_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -814,6 +815,12 @@ static const char *const meter_colors[] = {
 	"green", "yellow", "red", "all", NULL
 };
 
+static const char *const table_insertion_types[] = {
+	"pattern", "index", NULL
+};
+
+#define RAW_IPSEC_CONFS_MAX_NUM 8
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -1015,6 +1022,7 @@ struct buffer {
 		struct {
 			uint32_t table_id;
 			uint32_t pat_templ_id;
+			uint32_t rule_id;
 			uint32_t act_templ_id;
 			struct rte_flow_attr attr;
 			struct tunnel_ops tunnel_ops;
@@ -1154,6 +1162,7 @@ static const enum index next_table_subcmd[] = {
 static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
+	TABLE_INSERTION_TYPE,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -1287,6 +1296,12 @@ static const enum index next_ia_destroy_attr[] = {
 	ZERO,
 };
 
+static const enum index next_async_insert_subcmd[] = {
+	QUEUE_PATTERN_TEMPLATE,
+	QUEUE_RULE_ID,
+	ZERO,
+};
+
 static const enum index item_param[] = {
 	ITEM_PARAM_IS,
 	ITEM_PARAM_SPEC,
@@ -2399,6 +2414,9 @@ static int parse_meter_policy_id2ptr(struct context *ctx,
 static int parse_meter_color(struct context *ctx, const struct token *token,
 			     const char *str, unsigned int len, void *buf,
 			     unsigned int size);
+static int parse_insertion_table_type(struct context *ctx, const struct token *token,
+				      const char *str, unsigned int len, void *buf,
+				      unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2431,6 +2449,8 @@ static int comp_queue_id(struct context *, const struct token *,
 			 unsigned int, char *, unsigned int);
 static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
+static int comp_insertion_table_type(struct context *, const struct token *,
+				     unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2901,6 +2921,20 @@ static const struct token token_list[] = {
 					    args.table_destroy.table_id)),
 		.call = parse_table_destroy,
 	},
+	[TABLE_INSERTION_TYPE] = {
+		.name = "insertion_type",
+		.help = "specify insertion type",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.insertion_type)),
+	},
+	[TABLE_INSERTION_TYPE_NAME] = {
+		.name = "insertion_type_name",
+		.help = "insertion type name",
+		.call = parse_insertion_table_type,
+		.comp = comp_insertion_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -3002,7 +3036,7 @@ static const struct token token_list[] = {
 	[QUEUE_TEMPLATE_TABLE] = {
 		.name = "template_table",
 		.help = "specify table id",
-		.next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE),
+		.next = NEXT(next_async_insert_subcmd,
 			     NEXT_ENTRY(COMMON_TABLE_ID)),
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.vc.table_id)),
@@ -3026,6 +3060,15 @@ static const struct token token_list[] = {
 					args.vc.act_templ_id)),
 		.call = parse_qo,
 	},
+	[QUEUE_RULE_ID] = {
+		.name = "rule_index",
+		.help = "specify flow rule index",
+		.next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE),
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.vc.rule_id)),
+		.call = parse_qo,
+	},
 	[QUEUE_CREATE_POSTPONE] = {
 		.name = "postpone",
 		.help = "postpone create operation",
@@ -9069,11 +9112,13 @@ parse_qo(struct context *ctx, const struct token *token,
 		ctx->objdata = 0;
 		ctx->object = out;
 		ctx->objmask = NULL;
+		out->args.vc.rule_id = UINT32_MAX;
 		return len;
 	case QUEUE_TEMPLATE_TABLE:
 	case QUEUE_PATTERN_TEMPLATE:
 	case QUEUE_ACTIONS_TEMPLATE:
 	case QUEUE_CREATE_POSTPONE:
+	case QUEUE_RULE_ID:
 		return len;
 	case ITEM_PATTERN:
 		out->args.vc.pattern =
@@ -10052,6 +10097,32 @@ parse_meter_color(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse Insertion Table Type name */
+static int
+parse_insertion_table_type(struct context *ctx, const struct token *token,
+			   const char *str, unsigned int len, void *buf,
+			   unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_insertion_types[i]; ++i)
+		if (!strcmp_partial(table_insertion_types[i], str, len))
+			break;
+	if (!table_insertion_types[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10357,6 +10428,20 @@ comp_meter_color(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Insertion Table types. */
+static int
+comp_insertion_table_type(struct context *ctx, const struct token *token,
+			  unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_insertion_types);
+	if (ent < RTE_DIM(table_insertion_types) - 1)
+		return rte_strscpy(buf, table_insertion_types[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
@@ -10670,9 +10755,9 @@ cmd_flow_parsed(const struct buffer *in)
 		break;
 	case QUEUE_CREATE:
 		port_queue_flow_create(in->port, in->queue, in->postpone,
-				       in->args.vc.table_id, in->args.vc.pat_templ_id,
-				       in->args.vc.act_templ_id, in->args.vc.pattern,
-				       in->args.vc.actions);
+			in->args.vc.table_id, in->args.vc.rule_id,
+			in->args.vc.pat_templ_id, in->args.vc.act_templ_id,
+			in->args.vc.pattern, in->args.vc.actions);
 		break;
 	case QUEUE_DESTROY:
 		port_queue_flow_destroy(in->port, in->queue, in->postpone,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index acccb6b035..41484c3dde 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2609,7 +2609,7 @@ port_flow_template_table_flush(portid_t port_id)
 /** Enqueue create flow rule operation. */
 int
 port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-		       bool postpone, uint32_t table_id,
+		       bool postpone, uint32_t table_id, uint32_t rule_idx,
 		       uint32_t pattern_idx, uint32_t actions_idx,
 		       const struct rte_flow_item *pattern,
 		       const struct rte_flow_action *actions)
@@ -2685,8 +2685,12 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
 	}
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
-	flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
-		pattern, pattern_idx, actions, actions_idx, job, &error);
+	if (rule_idx == UINT32_MAX)
+		flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
+			pattern, pattern_idx, actions, actions_idx, job, &error);
+	else
+		flow = rte_flow_async_create_by_index(port_id, queue_id, &op_attr, pt->table,
+			rule_idx, actions, actions_idx, job, &error);
 	if (!flow) {
 		uint32_t flow_id = pf->id;
 		port_queue_flow_destroy(port_id, queue_id, true, 1, &flow_id);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 7d24d25970..22d02a742c 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -930,7 +930,7 @@ int port_flow_template_table_destroy(portid_t port_id,
 			    uint32_t n, const uint32_t *table);
 int port_flow_template_table_flush(portid_t port_id);
 int port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-			   bool postpone, uint32_t table_id,
+			   bool postpone, uint32_t table_id, uint32_t rule_idx,
 			   uint32_t pattern_idx, uint32_t actions_idx,
 			   const struct rte_flow_item *pattern,
 			   const struct rte_flow_action *actions);
-- 
2.18.2


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

* [PATCH v2 4/4] app/testpmd: add template table hash calculation function
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
                       ` (2 preceding siblings ...)
  2023-01-26 23:28     ` [PATCH v2 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
@ 2023-01-26 23:28     ` Alexander Kozyrev
  2023-02-01 16:09     ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Ori Kam
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
  5 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-01-26 23:28 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for a template table hash function.
Available types are: default, linear, crc32 and crc16.
flow template_table 0 create table_id 0 hash_func linear ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 69 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f1d6813baa..007d31c5cf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -180,6 +180,8 @@ enum index {
 	TABLE_DESTROY_ID,
 	TABLE_INSERTION_TYPE,
 	TABLE_INSERTION_TYPE_NAME,
+	TABLE_HASH_FUNC,
+	TABLE_HASH_FUNC_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -808,7 +810,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"hash_result", NULL
 };
 
 static const char *const meter_colors[] = {
@@ -819,6 +822,10 @@ static const char *const table_insertion_types[] = {
 	"pattern", "index", NULL
 };
 
+static const char *const table_hash_funcs[] = {
+	"default", "linear", "crc32", "crc16", NULL
+};
+
 #define RAW_IPSEC_CONFS_MAX_NUM 8
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1163,6 +1170,7 @@ static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
 	TABLE_INSERTION_TYPE,
+	TABLE_HASH_FUNC,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -2417,6 +2425,9 @@ static int parse_meter_color(struct context *ctx, const struct token *token,
 static int parse_insertion_table_type(struct context *ctx, const struct token *token,
 				      const char *str, unsigned int len, void *buf,
 				      unsigned int size);
+static int parse_hash_table_type(struct context *ctx, const struct token *token,
+				 const char *str, unsigned int len, void *buf,
+				 unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2451,6 +2462,8 @@ static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
 static int comp_insertion_table_type(struct context *, const struct token *,
 				     unsigned int, char *, unsigned int);
+static int comp_hash_table_type(struct context *, const struct token *,
+				unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2935,6 +2948,20 @@ static const struct token token_list[] = {
 		.call = parse_insertion_table_type,
 		.comp = comp_insertion_table_type,
 	},
+	[TABLE_HASH_FUNC] = {
+		.name = "hash_func",
+		.help = "specify hash calculation function",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_HASH_FUNC_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.hash_func)),
+	},
+	[TABLE_HASH_FUNC_NAME] = {
+		.name = "hash_func_name",
+		.help = "hash calculation function name",
+		.call = parse_hash_table_type,
+		.comp = comp_hash_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -10123,6 +10150,32 @@ parse_insertion_table_type(struct context *ctx, const struct token *token,
 	return ret > 0 ? (int)len : ret;
 }
 
+/** Parse Hash Calculation Table Type name */
+static int
+parse_hash_table_type(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len, void *buf,
+		      unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_hash_funcs[i]; ++i)
+		if (!strcmp_partial(table_hash_funcs[i], str, len))
+			break;
+	if (!table_hash_funcs[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10442,6 +10495,20 @@ comp_insertion_table_type(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Hash Calculation Table types. */
+static int
+comp_hash_table_type(struct context *ctx, const struct token *token,
+		     unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_hash_funcs);
+	if (ent < RTE_DIM(table_hash_funcs) - 1)
+		return rte_strscpy(buf, table_hash_funcs[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
-- 
2.18.2


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

* Re: [RFC] ethdev: add template table insertion and matching types
  2023-01-23 22:02       ` Alexander Kozyrev
@ 2023-01-30 14:47         ` Thomas Monjalon
  0 siblings, 0 replies; 31+ messages in thread
From: Thomas Monjalon @ 2023-01-30 14:47 UTC (permalink / raw)
  To: Alexander Kozyrev; +Cc: dev, ferruh.yigit, andrew.rybchenko, Ori Kam

23/01/2023 23:02, Alexander Kozyrev:
> > 21/01/2023 00:06, Alexander Kozyrev:
> > > > 14/12/2022 03:21, Alexander Kozyrev:
> > > > > Bring more flexibility and control over both flow rule insertion
> > > > > and packet matching mechanisms. Introduce 2 new flow table types:
> > > > >
> > > > > 1. Allow a user to specify the insertion type used in template tables.
> > > > > The insertion type is responsible for choosing the appropriate key
> > > > > value used to map inserted flow rules into a template table.
> > > > >
> > > > > Flow rules can be inserted by calculating the hash value for
> > > > > the pattern or inserted by index via the new create_by_index() API.
> > > > > The idea of the index-based insertion is to avoid additional matches
> > > > > and simply execute predefined actions after jumping to the index.
> > > >
> > > > I don't understand the idea.
> > > > Why is it avoiding additional matches?
> > >
> > > If you jump directly to an index in a table, you don't need to match
> > anything.
> > > For the regular pattern-based table you must calculate the hash and match
> > on it.
> > 
> > I don't get it. I think it would be simpler with an example.
> 
> This is how the regular pattern-based table works:
> you calculate hash on 5-tuple, go to the table entry with the corresponding hash,
> check if there is a collision and search for the proper entry if so, execute actions.
> Index-based table:
> take an index value from a specified field, go to this index, and execute actions.

OK, please make sure the explanation is clear in the patch.


> > > > > The insertion to an already existing index is undefined and
> > > >
> > > > Why is it undefined?
> > >
> > > The behavior is up to a PMD to decide. It is free to replace the rule or throw
> > an error.
> > 
> > An undefined behavior of an API makes applications not portable.
> > Why not deciding of a behavior? You are not sure what is best?
> 
> We don't want to restrict a PMD behavior here. 
> Personally, I would prefer throwing an error in this case.
> Do you think returning EEXIST is better?

I don't know what is best.
At least you can define an error EEXIST if the PMD forbids it,
and no error if the PMD replaces the rule.




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

* RE: [PATCH v2 0/4] ethdev: add template table insertion and matching types
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
                       ` (3 preceding siblings ...)
  2023-01-26 23:28     ` [PATCH v2 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
@ 2023-02-01 16:09     ` Ori Kam
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
  5 siblings, 0 replies; 31+ messages in thread
From: Ori Kam @ 2023-02-01 16:09 UTC (permalink / raw)
  To: Alexander Kozyrev, dev
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), ferruh.yigit, andrew.rybchenko

Hi Alex,


> -----Original Message-----
> From: Alexander Kozyrev <akozyrev@nvidia.com>
> Sent: Friday, 27 January 2023 1:28
> To: dev@dpdk.org
> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> ferruh.yigit@amd.com; andrew.rybchenko@oktetlabs.ru; Ori Kam
> <orika@nvidia.com>
> Subject: [PATCH v2 0/4] ethdev: add template table insertion and matching
> types
> 
> Bring more flexibility and control over both flow rule insertion
> and packet matching mechanisms. Introduce 2 new flow table types:
> 
> 1. Allow a user to specify the insertion type used in template tables.
> The insertion type is responsible for choosing the appropriate key
> value used to map inserted flow rules into a template table.
> 
> Flow rules can be inserted by calculating the hash value for
> the pattern or inserted by index via the new create_by_index() API.
> The idea of the index-based insertion is to avoid additional matches
> and simply execute predefined actions after jumping to the index.
> 
> The insertion into an already occupied index results in an error.
> The old rule must be destroyed first. An index cannot be bigger than
> the size of the table, otherwise, the rule is rejected as well.
> 
> 2. Allow a user to specify the hash calculation function used in template
> tables. The hash calculation type is responsible for the calculation of
> the flow rule index a packet would hit upon arrival at the table.
> 
> Control over this is useful for applications with custom RSS algorithms,
> for example. An application can select various packet fields to serve as
> a hash calculation source and jump to the appropriate flow rule location.
> The RSS hash result will be used as the index in the table. For the linear
> hash function, the mapping is one-to-one and the hash result is the index.
> For other hash functions, the index is the hash result module table size.
> The RSS hash result can be retrieved via modify_field API: HASH_RESULT.
> 
> RFC:
> https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-
> akozyrev@nvidia.com/
> v2: changed the behavior in case of insertion into the same index.
> 
> Alexander Kozyrev (4):
>   ethdev: add template table insertion type
>   ethdev: add template table hash calculation function
>   app/testpmd: add template table insertion type
>   app/testpmd: add template table hash calculation function
> 
>  app/test-pmd/cmdline_flow.c            | 166 +++++++++++++++++++++++--
>  app/test-pmd/config.c                  |  10 +-
>  app/test-pmd/testpmd.h                 |   2 +-
>  doc/guides/prog_guide/rte_flow.rst     |  20 +++
>  doc/guides/rel_notes/release_23_03.rst |  10 ++
>  lib/ethdev/rte_flow.c                  |  24 ++++
>  lib/ethdev/rte_flow.h                  |  95 ++++++++++++++
>  lib/ethdev/rte_flow_driver.h           |  11 ++
>  lib/ethdev/version.map                 |   3 +
>  9 files changed, 330 insertions(+), 11 deletions(-)
> 
> --
> 2.18.2

Series-acked-by:  Ori Kam <orika@nvidia.com>
Best,
Ori


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

* Re: [PATCH v2 1/4] ethdev: add template table insertion type
  2023-01-26 23:27     ` [PATCH v2 1/4] ethdev: add template table insertion type Alexander Kozyrev
@ 2023-02-02 10:57       ` Andrew Rybchenko
  2023-02-07 15:06         ` Alexander Kozyrev
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Rybchenko @ 2023-02-02 10:57 UTC (permalink / raw)
  To: Alexander Kozyrev, dev; +Cc: thomas, ferruh.yigit, orika

On 1/27/23 02:27, Alexander Kozyrev wrote:
> Allow user to specify insertion type used in template tables.
> The insertion type is responsible for choosing the appropriate key
> value used to map inserted flow rules into a template table.
> 
> Flow rules can be inserted by calculating the hash value for
> the pattern or inserted by index via the new create_by_index() API.
> The idea of the index-based insertion is to avoid additional matches
> and simply execute predefined actions after jumping to the index.
> 
> The insertion into an already occupied index results in an error.
> The old rule must be destroyed first. An index cannot be bigger than
> the size of the table, otherwise, the rule is rejected as well.

I'm sorry, but all my attempts to understand what happens here
are unsuccessful. Unfortunately the structure is unclear.
It sounds like your insert something by index into the template
table, but I don't understand the idea why it makes sense and
why it is needed.

> 
> Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>

[snip]

> diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
> index c15f6fbb9f..fa9391de2b 100644
> --- a/doc/guides/rel_notes/release_23_03.rst
> +++ b/doc/guides/rel_notes/release_23_03.rst
> @@ -69,6 +69,12 @@ New Features
>       ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
>       required for eth_rx, eth_tx, crypto and timer eventdev adapters.
>   
> +* **Added index-based rules insertion in flow API.**
> +
> +  Added ``rte_flow_table_insertion_type`` to allow the creation
> +  of index-based template tables in addition to pattern-based tables.
> +  Introduced new function ``rte_flow_async_create_by_index()``
> +  to insert rules by index into index-based template tables.

One more empty line here please, to have two before the next
section.

>   
>   Removed Items
>   -------------
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 7d0c24366c..013eb355ca 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
>   	return flow;
>   }
>   
> +struct rte_flow *
> +rte_flow_async_create_by_index(uint16_t port_id,
> +			       uint32_t queue_id,
> +			       const struct rte_flow_op_attr *op_attr,
> +			       struct rte_flow_template_table *template_table,
> +			       uint32_t rule_index,
> +			       const struct rte_flow_action actions[],
> +			       uint8_t actions_template_index,
> +			       void *user_data,
> +			       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);
> +	struct rte_flow *flow;

All generic checks of arguments must be done here.
I guess template_table cannot be NULL.  Anything else?
Can we check queue_id?

ops must be checked vs NULL, callback must be checked vs NULL.

> +
> +	flow = ops->async_create_by_index(dev, queue_id,
> +					  op_attr, template_table, rule_index,
> +					  actions, actions_template_index,
> +					  user_data, error);
> +	if (flow == NULL)
> +		flow_err(port_id, -rte_errno, error);
> +	return flow;
> +}
> +
>   int
>   rte_flow_async_destroy(uint16_t port_id,
>   		       uint32_t queue_id,
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index b60987db4b..2ba616eeb1 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t port_id,
>    */
>   struct rte_flow_template_table;
>   
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Template table flow rules insertion type.
> + */
> +enum rte_flow_table_insertion_type {
> +	/**
> +	 * Pattern-based insertion.
> +	 */
> +	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
> +	/**
> +	 * Index-based insertion.
> +	 */
> +	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
> +};
> +
>   /**
>    * @warning
>    * @b EXPERIMENTAL: this API may change without prior notice.
> @@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
>   	 * Maximum number of flow rules that this table holds.
>   	 */
>   	uint32_t nb_flows;
> +	/**
> +	 * Insertion type for flow rules.
> +	 */
> +	enum rte_flow_table_insertion_type insertion_type;
>   };
>   
>   /**
> @@ -5336,6 +5357,50 @@ rte_flow_async_create(uint16_t port_id,
>   		      void *user_data,
>   		      struct rte_flow_error *error);
>   
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Enqueue rule creation operation.
> + *
> + * @param port_id
> + *   Port identifier of Ethernet device.
> + * @param queue_id
> + *   Flow queue used to insert the rule.
> + * @param[in] op_attr
> + *   Rule creation operation attributes.

May be NULL?

> + * @param[in] template_table
> + *   Template table to select templates from.
> + * @param[in] rule_index
> + *   Rule index in the table.
> + * @param[in] actions
> + *   List of actions to be used.
> + *   The list order should match the order in the actions template.

Should we mention that it should be terminated with END?

> + * @param[in] actions_template_index
> + *   Actions template index in the table.
> + * @param[in] user_data
> + *   The user data that will be returned on the completion events.

May be NULL?

> + * @param[out] error
> + *   Perform verbose error reporting if not NULL.
> + *   PMDs initialize this structure in case of error only.
> + *
> + * @return
> + *   Handle on success, NULL otherwise and rte_errno is set.
> + *   The rule handle doesn't mean that the rule has been populated.
> + *   Only completion result indicates that if there was success or failure.
> + */
> +__rte_experimental
> +struct rte_flow *
> +rte_flow_async_create_by_index(uint16_t port_id,
> +			       uint32_t queue_id,
> +			       const struct rte_flow_op_attr *op_attr,
> +			       struct rte_flow_template_table *template_table,
> +			       uint32_t rule_index,
> +			       const struct rte_flow_action actions[],
> +			       uint8_t actions_template_index,
> +			       void *user_data,
> +			       struct rte_flow_error *error);
> +
>   /**
>    * @warning
>    * @b EXPERIMENTAL: this API may change without prior notice.

[snip]



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

* RE: [PATCH v2 1/4] ethdev: add template table insertion type
  2023-02-02 10:57       ` Andrew Rybchenko
@ 2023-02-07 15:06         ` Alexander Kozyrev
  0 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-07 15:06 UTC (permalink / raw)
  To: Andrew Rybchenko, dev
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), ferruh.yigit, Ori Kam

> > Allow user to specify insertion type used in template tables.
> > The insertion type is responsible for choosing the appropriate key
> > value used to map inserted flow rules into a template table.
> >
> > Flow rules can be inserted by calculating the hash value for
> > the pattern or inserted by index via the new create_by_index() API.
> > The idea of the index-based insertion is to avoid additional matches
> > and simply execute predefined actions after jumping to the index.
> >
> > The insertion into an already occupied index results in an error.
> > The old rule must be destroyed first. An index cannot be bigger than
> > the size of the table, otherwise, the rule is rejected as well.
> 
> I'm sorry, but all my attempts to understand what happens here
> are unsuccessful. Unfortunately the structure is unclear.
> It sounds like your insert something by index into the template
> table, but I don't understand the idea why it makes sense and
> why it is needed.

Sorry, Andrew, for the confusion. Looks like I need to include this explanation from the RFC:
This is how the regular pattern-based table works:
you calculate hash on 5-tuple, go to the table entry with the corresponding hash,
check if there is a collision and search for the proper entry if so, execute actions.
Index-based table:
 take an index value from a specified field, go to this index, and execute actions.
The whole idea is to skip any lookups for the packet if an user know exactly what should be executed.

> [snip]
> 
> > diff --git a/doc/guides/rel_notes/release_23_03.rst
> b/doc/guides/rel_notes/release_23_03.rst
> > index c15f6fbb9f..fa9391de2b 100644
> > --- a/doc/guides/rel_notes/release_23_03.rst
> > +++ b/doc/guides/rel_notes/release_23_03.rst
> > @@ -69,6 +69,12 @@ New Features
> >       ``rte_event_dev_config::nb_single_link_event_port_queues``
> parameter
> >       required for eth_rx, eth_tx, crypto and timer eventdev adapters.
> >
> > +* **Added index-based rules insertion in flow API.**
> > +
> > +  Added ``rte_flow_table_insertion_type`` to allow the creation
> > +  of index-based template tables in addition to pattern-based tables.
> > +  Introduced new function ``rte_flow_async_create_by_index()``
> > +  to insert rules by index into index-based template tables.
> 
> One more empty line here please, to have two before the next
> section.

No problem.

> >   Removed Items
> >   -------------
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> > index 7d0c24366c..013eb355ca 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
> >   	return flow;
> >   }
> >
> > +struct rte_flow *
> > +rte_flow_async_create_by_index(uint16_t port_id,
> > +			       uint32_t queue_id,
> > +			       const struct rte_flow_op_attr *op_attr,
> > +			       struct rte_flow_template_table *template_table,
> > +			       uint32_t rule_index,
> > +			       const struct rte_flow_action actions[],
> > +			       uint8_t actions_template_index,
> > +			       void *user_data,
> > +			       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);
> > +	struct rte_flow *flow;
> 
> All generic checks of arguments must be done here.
> I guess template_table cannot be NULL.  Anything else?
> Can we check queue_id?
> 
> ops must be checked vs NULL, callback must be checked vs NULL.

We are following the convention about asynchronous API.
No NULL checks are performed in any async Flow API for the sake of performance.
You can see this behaviour in any other async functions there.

> > +
> > +	flow = ops->async_create_by_index(dev, queue_id,
> > +					  op_attr, template_table,
> rule_index,
> > +					  actions, actions_template_index,
> > +					  user_data, error);
> > +	if (flow == NULL)
> > +		flow_err(port_id, -rte_errno, error);
> > +	return flow;
> > +}
> > +
> >   int
> >   rte_flow_async_destroy(uint16_t port_id,
> >   		       uint32_t queue_id,
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> > index b60987db4b..2ba616eeb1 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t
> port_id,
> >    */
> >   struct rte_flow_template_table;
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice.
> > + *
> > + * Template table flow rules insertion type.
> > + */
> > +enum rte_flow_table_insertion_type {
> > +	/**
> > +	 * Pattern-based insertion.
> > +	 */
> > +	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
> > +	/**
> > +	 * Index-based insertion.
> > +	 */
> > +	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
> > +};
> > +
> >   /**
> >    * @warning
> >    * @b EXPERIMENTAL: this API may change without prior notice.
> > @@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
> >   	 * Maximum number of flow rules that this table holds.
> >   	 */
> >   	uint32_t nb_flows;
> > +	/**
> > +	 * Insertion type for flow rules.
> > +	 */
> > +	enum rte_flow_table_insertion_type insertion_type;
> >   };
> >
> >   /**
> > @@ -5336,6 +5357,50 @@ rte_flow_async_create(uint16_t port_id,
> >   		      void *user_data,
> >   		      struct rte_flow_error *error);
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice.
> > + *
> > + * Enqueue rule creation operation.
> > + *
> > + * @param port_id
> > + *   Port identifier of Ethernet device.
> > + * @param queue_id
> > + *   Flow queue used to insert the rule.
> > + * @param[in] op_attr
> > + *   Rule creation operation attributes.
> 
> May be NULL?
No.

> > + * @param[in] template_table
> > + *   Template table to select templates from.
> > + * @param[in] rule_index
> > + *   Rule index in the table.
> > + * @param[in] actions
> > + *   List of actions to be used.
> > + *   The list order should match the order in the actions template.
> 
> Should we mention that it should be terminated with END?
Isn't redundant? Flow API assumes that pattern and actions always end with END.

> > + * @param[in] actions_template_index
> > + *   Actions template index in the table.
> > + * @param[in] user_data
> > + *   The user data that will be returned on the completion events.
> 
> May be NULL?
Yes, it may be NULL if the user doesn’t want any data associated with the flow.

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

* [PATCH v3 0/4] ethdev: add template table insertion and matching types
  2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
                       ` (4 preceding siblings ...)
  2023-02-01 16:09     ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Ori Kam
@ 2023-02-08  2:47     ` Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 1/4] ethdev: add template table insertion type Alexander Kozyrev
                         ` (4 more replies)
  5 siblings, 5 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  2:47 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Bring more flexibility and control over both flow rule insertion
and packet matching mechanisms. Introduce 2 new flow table types:

1. Allow a user to specify the insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

2. Allow a user to specify the hash calculation function used in template
tables. The hash calculation type is responsible for the calculation of
the flow rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

RFC: https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-akozyrev@nvidia.com/
v2: changed the behavior in case of insertion into the same index.
v3: refined commit message to highlight index-based table advantage.

Series-acked-by:  Ori Kam <orika@nvidia.com>

Alexander Kozyrev (4):
  ethdev: add template table insertion type
  ethdev: add template table hash calculation function
  app/testpmd: add template table insertion type
  app/testpmd: add template table hash calculation function

 app/test-pmd/cmdline_flow.c            | 166 +++++++++++++++++++++++--
 app/test-pmd/config.c                  |  10 +-
 app/test-pmd/testpmd.h                 |   2 +-
 doc/guides/prog_guide/rte_flow.rst     |  20 +++
 doc/guides/rel_notes/release_23_03.rst |   9 ++
 lib/ethdev/rte_flow.c                  |  24 ++++
 lib/ethdev/rte_flow.h                  |  95 ++++++++++++++
 lib/ethdev/rte_flow_driver.h           |  11 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 329 insertions(+), 11 deletions(-)

-- 
2.18.2


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

* [PATCH v3 1/4] ethdev: add template table insertion type
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
@ 2023-02-08  2:47       ` Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  2:47 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

This is how the regular pattern-based table works:
1. The hash is calclulated on a 5-tuple of a packet.
2. The corresponding entry in the table is checked for collisions.
3. Actions are executed once the final entry is found.
The index-based table skips any lookups for the packet:
1. The index value is taken from a specified field.
2. Actions are executed at the specified index in the table.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     | 20 ++++++++
 doc/guides/rel_notes/release_23_03.rst |  7 +++
 lib/ethdev/rte_flow.c                  | 24 ++++++++++
 lib/ethdev/rte_flow.h                  | 65 ++++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h           | 11 +++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 130 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..fbed7da9d8 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3669,6 +3669,26 @@ Enqueueing a flow rule creation operation is similar to simple creation.
 A valid handle in case of success is returned. It must be destroyed later
 by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
 
+Enqueue creation by index operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Enqueueing a flow rule creation operation to insert a rule at a table index.
+
+.. code-block:: c
+
+   struct rte_flow *
+   rte_flow_async_create_by_index(uint16_t port_id,
+                                  uint32_t queue_id,
+                                  const struct rte_flow_op_attr *op_attr,
+                                  struct rte_flow_template_table *template_table,
+                                  uint32_t rule_index,
+                                  const struct rte_flow_action actions[],
+                                  uint8_t actions_template_index,
+                                  void *user_data,
+                                  struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
 Enqueue destruction operation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..d3bddfb0f5 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,13 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added index-based rules insertion in flow API.**
+
+  * Added ``rte_flow_table_insertion_type`` to allow the creation
+    of index-based template tables in addition to pattern-based tables.
+  * Introduced new function ``rte_flow_async_create_by_index()``
+    to insert rules by index into index-based template tables.
+
 
 Removed Items
 -------------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..013eb355ca 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
 	return flow;
 }
 
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       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);
+	struct rte_flow *flow;
+
+	flow = ops->async_create_by_index(dev, queue_id,
+					  op_attr, template_table, rule_index,
+					  actions, actions_template_index,
+					  user_data, error);
+	if (flow == NULL)
+		flow_err(port_id, -rte_errno, error);
+	return flow;
+}
+
 int
 rte_flow_async_destroy(uint16_t port_id,
 		       uint32_t queue_id,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..2ba616eeb1 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t port_id,
  */
 struct rte_flow_template_table;
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table flow rules insertion type.
+ */
+enum rte_flow_table_insertion_type {
+	/**
+	 * Pattern-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
+	/**
+	 * Index-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
 	 * Maximum number of flow rules that this table holds.
 	 */
 	uint32_t nb_flows;
+	/**
+	 * Insertion type for flow rules.
+	 */
+	enum rte_flow_table_insertion_type insertion_type;
 };
 
 /**
@@ -5336,6 +5357,50 @@ rte_flow_async_create(uint16_t port_id,
 		      void *user_data,
 		      struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] op_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] rule_index
+ *   Rule index in the table.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index c7d0699c91..b5b597dd28 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -221,6 +221,17 @@ struct rte_flow_ops {
 		 uint8_t actions_template_index,
 		 void *user_data,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create_by_index() */
+	struct rte_flow *(*async_create_by_index)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 struct rte_flow_template_table *template_table,
+		 uint32_t rule_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
 	/** See rte_flow_async_destroy() */
 	int (*async_destroy)
 		(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17201fbe0f..dbc2bffe64 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -298,6 +298,9 @@ EXPERIMENTAL {
 	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
+
+	# added in 23.03
+	rte_flow_async_create_by_index;
 };
 
 INTERNAL {
-- 
2.18.2


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

* [PATCH v3 2/4] ethdev: add template table hash calculation function
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 1/4] ethdev: add template table insertion type Alexander Kozyrev
@ 2023-02-08  2:47       ` Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  2:47 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify hash calculation function used in template tables.
The hash calculation type is responsible for the calculation of the flow
rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_23_03.rst |  2 ++
 lib/ethdev/rte_flow.h                  | 30 ++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index d3bddfb0f5..5228e0f405 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -75,6 +75,8 @@ New Features
     of index-based template tables in addition to pattern-based tables.
   * Introduced new function ``rte_flow_async_create_by_index()``
     to insert rules by index into index-based template tables.
+  * Added hash calculation function used in template tables
+    to allow control over the calculation of the rule index for a packet.
 
 
 Removed Items
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 2ba616eeb1..6ce61e3f53 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_HASH_RESULT,	/**< Hash result. */
 };
 
 /**
@@ -5204,6 +5205,31 @@ enum rte_flow_table_insertion_type {
 	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table hash index calculation function.
+ */
+enum rte_flow_table_hash_func {
+	/**
+	 * Default hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_DEFAULT,
+	/**
+	 * Linear hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_LINEAR,
+	/**
+	 * 32-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC32,
+	/**
+	 * 16-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC16,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5223,6 +5249,10 @@ struct rte_flow_template_table_attr {
 	 * Insertion type for flow rules.
 	 */
 	enum rte_flow_table_insertion_type insertion_type;
+	/**
+	 * Hash calculation function for the packet matching.
+	 */
+	enum rte_flow_table_hash_func hash_func;
 };
 
 /**
-- 
2.18.2


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

* [PATCH v3 3/4] app/testpmd: add template table insertion type
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 1/4] ethdev: add template table insertion type Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
@ 2023-02-08  2:47       ` Alexander Kozyrev
  2023-02-08  2:47       ` [PATCH v3 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  2:47 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for specifying a template table insertion type.
Available types are: pattern and index.
flow template_table 0 create table_id 0 insertion_type index ...
Allow specifying the rule index instead of the pattern template index:
flow queue 0 create 0 template_table 0 rule_index 5 actions_template 0 ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 97 ++++++++++++++++++++++++++++++++++---
 app/test-pmd/config.c       | 10 ++--
 app/test-pmd/testpmd.h      |  2 +-
 3 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..f1d6813baa 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -133,12 +133,11 @@ enum index {
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
-	QUEUE_CREATE_ID,
 	QUEUE_CREATE_POSTPONE,
 	QUEUE_TEMPLATE_TABLE,
 	QUEUE_PATTERN_TEMPLATE,
 	QUEUE_ACTIONS_TEMPLATE,
-	QUEUE_SPEC,
+	QUEUE_RULE_ID,
 
 	/* Queue destroy arguments. */
 	QUEUE_DESTROY_ID,
@@ -179,6 +178,8 @@ enum index {
 	TABLE_DESTROY,
 	TABLE_CREATE_ID,
 	TABLE_DESTROY_ID,
+	TABLE_INSERTION_TYPE,
+	TABLE_INSERTION_TYPE_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -814,6 +815,12 @@ static const char *const meter_colors[] = {
 	"green", "yellow", "red", "all", NULL
 };
 
+static const char *const table_insertion_types[] = {
+	"pattern", "index", NULL
+};
+
+#define RAW_IPSEC_CONFS_MAX_NUM 8
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -1015,6 +1022,7 @@ struct buffer {
 		struct {
 			uint32_t table_id;
 			uint32_t pat_templ_id;
+			uint32_t rule_id;
 			uint32_t act_templ_id;
 			struct rte_flow_attr attr;
 			struct tunnel_ops tunnel_ops;
@@ -1154,6 +1162,7 @@ static const enum index next_table_subcmd[] = {
 static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
+	TABLE_INSERTION_TYPE,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -1287,6 +1296,12 @@ static const enum index next_ia_destroy_attr[] = {
 	ZERO,
 };
 
+static const enum index next_async_insert_subcmd[] = {
+	QUEUE_PATTERN_TEMPLATE,
+	QUEUE_RULE_ID,
+	ZERO,
+};
+
 static const enum index item_param[] = {
 	ITEM_PARAM_IS,
 	ITEM_PARAM_SPEC,
@@ -2399,6 +2414,9 @@ static int parse_meter_policy_id2ptr(struct context *ctx,
 static int parse_meter_color(struct context *ctx, const struct token *token,
 			     const char *str, unsigned int len, void *buf,
 			     unsigned int size);
+static int parse_insertion_table_type(struct context *ctx, const struct token *token,
+				      const char *str, unsigned int len, void *buf,
+				      unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2431,6 +2449,8 @@ static int comp_queue_id(struct context *, const struct token *,
 			 unsigned int, char *, unsigned int);
 static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
+static int comp_insertion_table_type(struct context *, const struct token *,
+				     unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2901,6 +2921,20 @@ static const struct token token_list[] = {
 					    args.table_destroy.table_id)),
 		.call = parse_table_destroy,
 	},
+	[TABLE_INSERTION_TYPE] = {
+		.name = "insertion_type",
+		.help = "specify insertion type",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.insertion_type)),
+	},
+	[TABLE_INSERTION_TYPE_NAME] = {
+		.name = "insertion_type_name",
+		.help = "insertion type name",
+		.call = parse_insertion_table_type,
+		.comp = comp_insertion_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -3002,7 +3036,7 @@ static const struct token token_list[] = {
 	[QUEUE_TEMPLATE_TABLE] = {
 		.name = "template_table",
 		.help = "specify table id",
-		.next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE),
+		.next = NEXT(next_async_insert_subcmd,
 			     NEXT_ENTRY(COMMON_TABLE_ID)),
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.vc.table_id)),
@@ -3026,6 +3060,15 @@ static const struct token token_list[] = {
 					args.vc.act_templ_id)),
 		.call = parse_qo,
 	},
+	[QUEUE_RULE_ID] = {
+		.name = "rule_index",
+		.help = "specify flow rule index",
+		.next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE),
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.vc.rule_id)),
+		.call = parse_qo,
+	},
 	[QUEUE_CREATE_POSTPONE] = {
 		.name = "postpone",
 		.help = "postpone create operation",
@@ -9069,11 +9112,13 @@ parse_qo(struct context *ctx, const struct token *token,
 		ctx->objdata = 0;
 		ctx->object = out;
 		ctx->objmask = NULL;
+		out->args.vc.rule_id = UINT32_MAX;
 		return len;
 	case QUEUE_TEMPLATE_TABLE:
 	case QUEUE_PATTERN_TEMPLATE:
 	case QUEUE_ACTIONS_TEMPLATE:
 	case QUEUE_CREATE_POSTPONE:
+	case QUEUE_RULE_ID:
 		return len;
 	case ITEM_PATTERN:
 		out->args.vc.pattern =
@@ -10052,6 +10097,32 @@ parse_meter_color(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse Insertion Table Type name */
+static int
+parse_insertion_table_type(struct context *ctx, const struct token *token,
+			   const char *str, unsigned int len, void *buf,
+			   unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_insertion_types[i]; ++i)
+		if (!strcmp_partial(table_insertion_types[i], str, len))
+			break;
+	if (!table_insertion_types[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10357,6 +10428,20 @@ comp_meter_color(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Insertion Table types. */
+static int
+comp_insertion_table_type(struct context *ctx, const struct token *token,
+			  unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_insertion_types);
+	if (ent < RTE_DIM(table_insertion_types) - 1)
+		return rte_strscpy(buf, table_insertion_types[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
@@ -10670,9 +10755,9 @@ cmd_flow_parsed(const struct buffer *in)
 		break;
 	case QUEUE_CREATE:
 		port_queue_flow_create(in->port, in->queue, in->postpone,
-				       in->args.vc.table_id, in->args.vc.pat_templ_id,
-				       in->args.vc.act_templ_id, in->args.vc.pattern,
-				       in->args.vc.actions);
+			in->args.vc.table_id, in->args.vc.rule_id,
+			in->args.vc.pat_templ_id, in->args.vc.act_templ_id,
+			in->args.vc.pattern, in->args.vc.actions);
 		break;
 	case QUEUE_DESTROY:
 		port_queue_flow_destroy(in->port, in->queue, in->postpone,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index acccb6b035..41484c3dde 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2609,7 +2609,7 @@ port_flow_template_table_flush(portid_t port_id)
 /** Enqueue create flow rule operation. */
 int
 port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-		       bool postpone, uint32_t table_id,
+		       bool postpone, uint32_t table_id, uint32_t rule_idx,
 		       uint32_t pattern_idx, uint32_t actions_idx,
 		       const struct rte_flow_item *pattern,
 		       const struct rte_flow_action *actions)
@@ -2685,8 +2685,12 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
 	}
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
-	flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
-		pattern, pattern_idx, actions, actions_idx, job, &error);
+	if (rule_idx == UINT32_MAX)
+		flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
+			pattern, pattern_idx, actions, actions_idx, job, &error);
+	else
+		flow = rte_flow_async_create_by_index(port_id, queue_id, &op_attr, pt->table,
+			rule_idx, actions, actions_idx, job, &error);
 	if (!flow) {
 		uint32_t flow_id = pf->id;
 		port_queue_flow_destroy(port_id, queue_id, true, 1, &flow_id);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 7d24d25970..22d02a742c 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -930,7 +930,7 @@ int port_flow_template_table_destroy(portid_t port_id,
 			    uint32_t n, const uint32_t *table);
 int port_flow_template_table_flush(portid_t port_id);
 int port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-			   bool postpone, uint32_t table_id,
+			   bool postpone, uint32_t table_id, uint32_t rule_idx,
 			   uint32_t pattern_idx, uint32_t actions_idx,
 			   const struct rte_flow_item *pattern,
 			   const struct rte_flow_action *actions);
-- 
2.18.2


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

* [PATCH v3 4/4] app/testpmd: add template table hash calculation function
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
                         ` (2 preceding siblings ...)
  2023-02-08  2:47       ` [PATCH v3 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
@ 2023-02-08  2:47       ` Alexander Kozyrev
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  2:47 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for a template table hash function.
Available types are: default, linear, crc32 and crc16.
flow template_table 0 create table_id 0 hash_func linear ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 69 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f1d6813baa..007d31c5cf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -180,6 +180,8 @@ enum index {
 	TABLE_DESTROY_ID,
 	TABLE_INSERTION_TYPE,
 	TABLE_INSERTION_TYPE_NAME,
+	TABLE_HASH_FUNC,
+	TABLE_HASH_FUNC_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -808,7 +810,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"hash_result", NULL
 };
 
 static const char *const meter_colors[] = {
@@ -819,6 +822,10 @@ static const char *const table_insertion_types[] = {
 	"pattern", "index", NULL
 };
 
+static const char *const table_hash_funcs[] = {
+	"default", "linear", "crc32", "crc16", NULL
+};
+
 #define RAW_IPSEC_CONFS_MAX_NUM 8
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1163,6 +1170,7 @@ static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
 	TABLE_INSERTION_TYPE,
+	TABLE_HASH_FUNC,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -2417,6 +2425,9 @@ static int parse_meter_color(struct context *ctx, const struct token *token,
 static int parse_insertion_table_type(struct context *ctx, const struct token *token,
 				      const char *str, unsigned int len, void *buf,
 				      unsigned int size);
+static int parse_hash_table_type(struct context *ctx, const struct token *token,
+				 const char *str, unsigned int len, void *buf,
+				 unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2451,6 +2462,8 @@ static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
 static int comp_insertion_table_type(struct context *, const struct token *,
 				     unsigned int, char *, unsigned int);
+static int comp_hash_table_type(struct context *, const struct token *,
+				unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2935,6 +2948,20 @@ static const struct token token_list[] = {
 		.call = parse_insertion_table_type,
 		.comp = comp_insertion_table_type,
 	},
+	[TABLE_HASH_FUNC] = {
+		.name = "hash_func",
+		.help = "specify hash calculation function",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_HASH_FUNC_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.hash_func)),
+	},
+	[TABLE_HASH_FUNC_NAME] = {
+		.name = "hash_func_name",
+		.help = "hash calculation function name",
+		.call = parse_hash_table_type,
+		.comp = comp_hash_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -10123,6 +10150,32 @@ parse_insertion_table_type(struct context *ctx, const struct token *token,
 	return ret > 0 ? (int)len : ret;
 }
 
+/** Parse Hash Calculation Table Type name */
+static int
+parse_hash_table_type(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len, void *buf,
+		      unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_hash_funcs[i]; ++i)
+		if (!strcmp_partial(table_hash_funcs[i], str, len))
+			break;
+	if (!table_hash_funcs[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10442,6 +10495,20 @@ comp_insertion_table_type(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Hash Calculation Table types. */
+static int
+comp_hash_table_type(struct context *ctx, const struct token *token,
+		     unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_hash_funcs);
+	if (ent < RTE_DIM(table_hash_funcs) - 1)
+		return rte_strscpy(buf, table_hash_funcs[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
-- 
2.18.2


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

* [PATCH v4 0/4] ethdev: add template table insertion and matching types
  2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
                         ` (3 preceding siblings ...)
  2023-02-08  2:47       ` [PATCH v3 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
@ 2023-02-08  3:06       ` Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 1/4] ethdev: add template table insertion type Alexander Kozyrev
                           ` (4 more replies)
  4 siblings, 5 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  3:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Bring more flexibility and control over both flow rule insertion
and packet matching mechanisms. Introduce 2 new flow table types:

1. Allow a user to specify the insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

2. Allow a user to specify the hash calculation function used in template
tables. The hash calculation type is responsible for the calculation of
the flow rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

RFC: https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-akozyrev@nvidia.com/
v2: changed the behavior in case of insertion into the same index.
v3: refined the commit message to highlight index-based table advantage.
v4: fixed a typo in the commit message.

Series-acked-by:  Ori Kam <orika@nvidia.com>

Alexander Kozyrev (4):
  ethdev: add template table insertion type
  ethdev: add template table hash calculation function
  app/testpmd: add template table insertion type
  app/testpmd: add template table hash calculation function

 app/test-pmd/cmdline_flow.c            | 166 +++++++++++++++++++++++--
 app/test-pmd/config.c                  |  10 +-
 app/test-pmd/testpmd.h                 |   2 +-
 doc/guides/prog_guide/rte_flow.rst     |  20 +++
 doc/guides/rel_notes/release_23_03.rst |   9 ++
 lib/ethdev/rte_flow.c                  |  24 ++++
 lib/ethdev/rte_flow.h                  |  95 ++++++++++++++
 lib/ethdev/rte_flow_driver.h           |  11 ++
 lib/ethdev/version.map                 |   3 +
 9 files changed, 329 insertions(+), 11 deletions(-)

-- 
2.18.2


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

* [PATCH v4 1/4] ethdev: add template table insertion type
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
@ 2023-02-08  3:06         ` Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  3:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify insertion type used in template tables.
The insertion type is responsible for choosing the appropriate key
value used to map inserted flow rules into a template table.

Flow rules can be inserted by calculating the hash value for
the pattern or inserted by index via the new create_by_index() API.
The idea of the index-based insertion is to avoid additional matches
and simply execute predefined actions after jumping to the index.

This is how the regular pattern-based table works:
1. The hash is calculated on a 5-tuple of a packet.
2. The corresponding entry in the table is checked for collisions.
3. Actions are executed once the final entry is found.
The index-based table skips any lookups for the packet:
1. The index value is taken from a specified field.
2. Actions are executed at the specified index in the table.

The insertion into an already occupied index results in an error.
The old rule must be destroyed first. An index cannot be bigger than
the size of the table, otherwise, the rule is rejected as well.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst     | 20 ++++++++
 doc/guides/rel_notes/release_23_03.rst |  7 +++
 lib/ethdev/rte_flow.c                  | 24 ++++++++++
 lib/ethdev/rte_flow.h                  | 65 ++++++++++++++++++++++++++
 lib/ethdev/rte_flow_driver.h           | 11 +++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 130 insertions(+)

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..fbed7da9d8 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3669,6 +3669,26 @@ Enqueueing a flow rule creation operation is similar to simple creation.
 A valid handle in case of success is returned. It must be destroyed later
 by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
 
+Enqueue creation by index operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Enqueueing a flow rule creation operation to insert a rule at a table index.
+
+.. code-block:: c
+
+   struct rte_flow *
+   rte_flow_async_create_by_index(uint16_t port_id,
+                                  uint32_t queue_id,
+                                  const struct rte_flow_op_attr *op_attr,
+                                  struct rte_flow_template_table *template_table,
+                                  uint32_t rule_index,
+                                  const struct rte_flow_action actions[],
+                                  uint8_t actions_template_index,
+                                  void *user_data,
+                                  struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
 Enqueue destruction operation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index c15f6fbb9f..d3bddfb0f5 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -69,6 +69,13 @@ New Features
     ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter
     required for eth_rx, eth_tx, crypto and timer eventdev adapters.
 
+* **Added index-based rules insertion in flow API.**
+
+  * Added ``rte_flow_table_insertion_type`` to allow the creation
+    of index-based template tables in addition to pattern-based tables.
+  * Introduced new function ``rte_flow_async_create_by_index()``
+    to insert rules by index into index-based template tables.
+
 
 Removed Items
 -------------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..013eb355ca 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1765,6 +1765,30 @@ rte_flow_async_create(uint16_t port_id,
 	return flow;
 }
 
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       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);
+	struct rte_flow *flow;
+
+	flow = ops->async_create_by_index(dev, queue_id,
+					  op_attr, template_table, rule_index,
+					  actions, actions_template_index,
+					  user_data, error);
+	if (flow == NULL)
+		flow_err(port_id, -rte_errno, error);
+	return flow;
+}
+
 int
 rte_flow_async_destroy(uint16_t port_id,
 		       uint32_t queue_id,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..2ba616eeb1 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5187,6 +5187,23 @@ rte_flow_actions_template_destroy(uint16_t port_id,
  */
 struct rte_flow_template_table;
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table flow rules insertion type.
+ */
+enum rte_flow_table_insertion_type {
+	/**
+	 * Pattern-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_PATTERN,
+	/**
+	 * Index-based insertion.
+	 */
+	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5202,6 +5219,10 @@ struct rte_flow_template_table_attr {
 	 * Maximum number of flow rules that this table holds.
 	 */
 	uint32_t nb_flows;
+	/**
+	 * Insertion type for flow rules.
+	 */
+	enum rte_flow_table_insertion_type insertion_type;
 };
 
 /**
@@ -5336,6 +5357,50 @@ rte_flow_async_create(uint16_t port_id,
 		      void *user_data,
 		      struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] op_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] rule_index
+ *   Rule index in the table.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create_by_index(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_op_attr *op_attr,
+			       struct rte_flow_template_table *template_table,
+			       uint32_t rule_index,
+			       const struct rte_flow_action actions[],
+			       uint8_t actions_template_index,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index c7d0699c91..b5b597dd28 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -221,6 +221,17 @@ struct rte_flow_ops {
 		 uint8_t actions_template_index,
 		 void *user_data,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create_by_index() */
+	struct rte_flow *(*async_create_by_index)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 struct rte_flow_template_table *template_table,
+		 uint32_t rule_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
 	/** See rte_flow_async_destroy() */
 	int (*async_destroy)
 		(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17201fbe0f..dbc2bffe64 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -298,6 +298,9 @@ EXPERIMENTAL {
 	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
+
+	# added in 23.03
+	rte_flow_async_create_by_index;
 };
 
 INTERNAL {
-- 
2.18.2


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

* [PATCH v4 2/4] ethdev: add template table hash calculation function
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 1/4] ethdev: add template table insertion type Alexander Kozyrev
@ 2023-02-08  3:06         ` Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  3:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Allow user to specify hash calculation function used in template tables.
The hash calculation type is responsible for the calculation of the flow
rule index a packet would hit upon arrival at the table.

Control over this is useful for applications with custom RSS algorithms,
for example. An application can select various packet fields to serve as
a hash calculation source and jump to the appropriate flow rule location.
The RSS hash result will be used as the index in the table. For the linear
hash function, the mapping is one-to-one and the hash result is the index.
For other hash functions, the index is the hash result module table size.
The RSS hash result can be retrieved via modify_field API: HASH_RESULT.

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 doc/guides/rel_notes/release_23_03.rst |  2 ++
 lib/ethdev/rte_flow.h                  | 30 ++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index d3bddfb0f5..5228e0f405 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -75,6 +75,8 @@ New Features
     of index-based template tables in addition to pattern-based tables.
   * Introduced new function ``rte_flow_async_create_by_index()``
     to insert rules by index into index-based template tables.
+  * Added hash calculation function used in template tables
+    to allow control over the calculation of the rule index for a packet.
 
 
 Removed Items
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 2ba616eeb1..6ce61e3f53 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_HASH_RESULT,	/**< Hash result. */
 };
 
 /**
@@ -5204,6 +5205,31 @@ enum rte_flow_table_insertion_type {
 	RTE_FLOW_TABLE_INSERTION_TYPE_INDEX,
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Template table hash index calculation function.
+ */
+enum rte_flow_table_hash_func {
+	/**
+	 * Default hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_DEFAULT,
+	/**
+	 * Linear hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_LINEAR,
+	/**
+	 * 32-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC32,
+	/**
+	 * 16-bit checksum hash calculation.
+	 */
+	RTE_FLOW_TABLE_HASH_FUNC_CRC16,
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -5223,6 +5249,10 @@ struct rte_flow_template_table_attr {
 	 * Insertion type for flow rules.
 	 */
 	enum rte_flow_table_insertion_type insertion_type;
+	/**
+	 * Hash calculation function for the packet matching.
+	 */
+	enum rte_flow_table_hash_func hash_func;
 };
 
 /**
-- 
2.18.2


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

* [PATCH v4 3/4] app/testpmd: add template table insertion type
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 1/4] ethdev: add template table insertion type Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
@ 2023-02-08  3:06         ` Alexander Kozyrev
  2023-02-08  3:06         ` [PATCH v4 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
  2023-02-10 17:42         ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Ferruh Yigit
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  3:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for specifying a template table insertion type.
Available types are: pattern and index.
flow template_table 0 create table_id 0 insertion_type index ...
Allow specifying the rule index instead of the pattern template index:
flow queue 0 create 0 template_table 0 rule_index 5 actions_template 0 ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 97 ++++++++++++++++++++++++++++++++++---
 app/test-pmd/config.c       | 10 ++--
 app/test-pmd/testpmd.h      |  2 +-
 3 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..f1d6813baa 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -133,12 +133,11 @@ enum index {
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
-	QUEUE_CREATE_ID,
 	QUEUE_CREATE_POSTPONE,
 	QUEUE_TEMPLATE_TABLE,
 	QUEUE_PATTERN_TEMPLATE,
 	QUEUE_ACTIONS_TEMPLATE,
-	QUEUE_SPEC,
+	QUEUE_RULE_ID,
 
 	/* Queue destroy arguments. */
 	QUEUE_DESTROY_ID,
@@ -179,6 +178,8 @@ enum index {
 	TABLE_DESTROY,
 	TABLE_CREATE_ID,
 	TABLE_DESTROY_ID,
+	TABLE_INSERTION_TYPE,
+	TABLE_INSERTION_TYPE_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -814,6 +815,12 @@ static const char *const meter_colors[] = {
 	"green", "yellow", "red", "all", NULL
 };
 
+static const char *const table_insertion_types[] = {
+	"pattern", "index", NULL
+};
+
+#define RAW_IPSEC_CONFS_MAX_NUM 8
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -1015,6 +1022,7 @@ struct buffer {
 		struct {
 			uint32_t table_id;
 			uint32_t pat_templ_id;
+			uint32_t rule_id;
 			uint32_t act_templ_id;
 			struct rte_flow_attr attr;
 			struct tunnel_ops tunnel_ops;
@@ -1154,6 +1162,7 @@ static const enum index next_table_subcmd[] = {
 static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
+	TABLE_INSERTION_TYPE,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -1287,6 +1296,12 @@ static const enum index next_ia_destroy_attr[] = {
 	ZERO,
 };
 
+static const enum index next_async_insert_subcmd[] = {
+	QUEUE_PATTERN_TEMPLATE,
+	QUEUE_RULE_ID,
+	ZERO,
+};
+
 static const enum index item_param[] = {
 	ITEM_PARAM_IS,
 	ITEM_PARAM_SPEC,
@@ -2399,6 +2414,9 @@ static int parse_meter_policy_id2ptr(struct context *ctx,
 static int parse_meter_color(struct context *ctx, const struct token *token,
 			     const char *str, unsigned int len, void *buf,
 			     unsigned int size);
+static int parse_insertion_table_type(struct context *ctx, const struct token *token,
+				      const char *str, unsigned int len, void *buf,
+				      unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2431,6 +2449,8 @@ static int comp_queue_id(struct context *, const struct token *,
 			 unsigned int, char *, unsigned int);
 static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
+static int comp_insertion_table_type(struct context *, const struct token *,
+				     unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2901,6 +2921,20 @@ static const struct token token_list[] = {
 					    args.table_destroy.table_id)),
 		.call = parse_table_destroy,
 	},
+	[TABLE_INSERTION_TYPE] = {
+		.name = "insertion_type",
+		.help = "specify insertion type",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.insertion_type)),
+	},
+	[TABLE_INSERTION_TYPE_NAME] = {
+		.name = "insertion_type_name",
+		.help = "insertion type name",
+		.call = parse_insertion_table_type,
+		.comp = comp_insertion_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -3002,7 +3036,7 @@ static const struct token token_list[] = {
 	[QUEUE_TEMPLATE_TABLE] = {
 		.name = "template_table",
 		.help = "specify table id",
-		.next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE),
+		.next = NEXT(next_async_insert_subcmd,
 			     NEXT_ENTRY(COMMON_TABLE_ID)),
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.vc.table_id)),
@@ -3026,6 +3060,15 @@ static const struct token token_list[] = {
 					args.vc.act_templ_id)),
 		.call = parse_qo,
 	},
+	[QUEUE_RULE_ID] = {
+		.name = "rule_index",
+		.help = "specify flow rule index",
+		.next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE),
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.vc.rule_id)),
+		.call = parse_qo,
+	},
 	[QUEUE_CREATE_POSTPONE] = {
 		.name = "postpone",
 		.help = "postpone create operation",
@@ -9069,11 +9112,13 @@ parse_qo(struct context *ctx, const struct token *token,
 		ctx->objdata = 0;
 		ctx->object = out;
 		ctx->objmask = NULL;
+		out->args.vc.rule_id = UINT32_MAX;
 		return len;
 	case QUEUE_TEMPLATE_TABLE:
 	case QUEUE_PATTERN_TEMPLATE:
 	case QUEUE_ACTIONS_TEMPLATE:
 	case QUEUE_CREATE_POSTPONE:
+	case QUEUE_RULE_ID:
 		return len;
 	case ITEM_PATTERN:
 		out->args.vc.pattern =
@@ -10052,6 +10097,32 @@ parse_meter_color(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse Insertion Table Type name */
+static int
+parse_insertion_table_type(struct context *ctx, const struct token *token,
+			   const char *str, unsigned int len, void *buf,
+			   unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_insertion_types[i]; ++i)
+		if (!strcmp_partial(table_insertion_types[i], str, len))
+			break;
+	if (!table_insertion_types[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10357,6 +10428,20 @@ comp_meter_color(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Insertion Table types. */
+static int
+comp_insertion_table_type(struct context *ctx, const struct token *token,
+			  unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_insertion_types);
+	if (ent < RTE_DIM(table_insertion_types) - 1)
+		return rte_strscpy(buf, table_insertion_types[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
@@ -10670,9 +10755,9 @@ cmd_flow_parsed(const struct buffer *in)
 		break;
 	case QUEUE_CREATE:
 		port_queue_flow_create(in->port, in->queue, in->postpone,
-				       in->args.vc.table_id, in->args.vc.pat_templ_id,
-				       in->args.vc.act_templ_id, in->args.vc.pattern,
-				       in->args.vc.actions);
+			in->args.vc.table_id, in->args.vc.rule_id,
+			in->args.vc.pat_templ_id, in->args.vc.act_templ_id,
+			in->args.vc.pattern, in->args.vc.actions);
 		break;
 	case QUEUE_DESTROY:
 		port_queue_flow_destroy(in->port, in->queue, in->postpone,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index acccb6b035..41484c3dde 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2609,7 +2609,7 @@ port_flow_template_table_flush(portid_t port_id)
 /** Enqueue create flow rule operation. */
 int
 port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-		       bool postpone, uint32_t table_id,
+		       bool postpone, uint32_t table_id, uint32_t rule_idx,
 		       uint32_t pattern_idx, uint32_t actions_idx,
 		       const struct rte_flow_item *pattern,
 		       const struct rte_flow_action *actions)
@@ -2685,8 +2685,12 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
 	}
 	/* Poisoning to make sure PMDs update it in case of error. */
 	memset(&error, 0x11, sizeof(error));
-	flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
-		pattern, pattern_idx, actions, actions_idx, job, &error);
+	if (rule_idx == UINT32_MAX)
+		flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
+			pattern, pattern_idx, actions, actions_idx, job, &error);
+	else
+		flow = rte_flow_async_create_by_index(port_id, queue_id, &op_attr, pt->table,
+			rule_idx, actions, actions_idx, job, &error);
 	if (!flow) {
 		uint32_t flow_id = pf->id;
 		port_queue_flow_destroy(port_id, queue_id, true, 1, &flow_id);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 7d24d25970..22d02a742c 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -930,7 +930,7 @@ int port_flow_template_table_destroy(portid_t port_id,
 			    uint32_t n, const uint32_t *table);
 int port_flow_template_table_flush(portid_t port_id);
 int port_queue_flow_create(portid_t port_id, queueid_t queue_id,
-			   bool postpone, uint32_t table_id,
+			   bool postpone, uint32_t table_id, uint32_t rule_idx,
 			   uint32_t pattern_idx, uint32_t actions_idx,
 			   const struct rte_flow_item *pattern,
 			   const struct rte_flow_action *actions);
-- 
2.18.2


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

* [PATCH v4 4/4] app/testpmd: add template table hash calculation function
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
                           ` (2 preceding siblings ...)
  2023-02-08  3:06         ` [PATCH v4 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
@ 2023-02-08  3:06         ` Alexander Kozyrev
  2023-02-10 17:42         ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Ferruh Yigit
  4 siblings, 0 replies; 31+ messages in thread
From: Alexander Kozyrev @ 2023-02-08  3:06 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko, orika

Add testpmd CLI interface for a template table hash function.
Available types are: default, linear, crc32 and crc16.
flow template_table 0 create table_id 0 hash_func linear ...

Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 69 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f1d6813baa..007d31c5cf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -180,6 +180,8 @@ enum index {
 	TABLE_DESTROY_ID,
 	TABLE_INSERTION_TYPE,
 	TABLE_INSERTION_TYPE_NAME,
+	TABLE_HASH_FUNC,
+	TABLE_HASH_FUNC_NAME,
 	TABLE_GROUP,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
@@ -808,7 +810,8 @@ static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"hash_result", NULL
 };
 
 static const char *const meter_colors[] = {
@@ -819,6 +822,10 @@ static const char *const table_insertion_types[] = {
 	"pattern", "index", NULL
 };
 
+static const char *const table_hash_funcs[] = {
+	"default", "linear", "crc32", "crc16", NULL
+};
+
 #define RAW_IPSEC_CONFS_MAX_NUM 8
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1163,6 +1170,7 @@ static const enum index next_table_attr[] = {
 	TABLE_CREATE_ID,
 	TABLE_GROUP,
 	TABLE_INSERTION_TYPE,
+	TABLE_HASH_FUNC,
 	TABLE_PRIORITY,
 	TABLE_INGRESS,
 	TABLE_EGRESS,
@@ -2417,6 +2425,9 @@ static int parse_meter_color(struct context *ctx, const struct token *token,
 static int parse_insertion_table_type(struct context *ctx, const struct token *token,
 				      const char *str, unsigned int len, void *buf,
 				      unsigned int size);
+static int parse_hash_table_type(struct context *ctx, const struct token *token,
+				 const char *str, unsigned int len, void *buf,
+				 unsigned int size);
 static int comp_none(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_boolean(struct context *, const struct token *,
@@ -2451,6 +2462,8 @@ static int comp_meter_color(struct context *, const struct token *,
 			    unsigned int, char *, unsigned int);
 static int comp_insertion_table_type(struct context *, const struct token *,
 				     unsigned int, char *, unsigned int);
+static int comp_hash_table_type(struct context *, const struct token *,
+				unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -2935,6 +2948,20 @@ static const struct token token_list[] = {
 		.call = parse_insertion_table_type,
 		.comp = comp_insertion_table_type,
 	},
+	[TABLE_HASH_FUNC] = {
+		.name = "hash_func",
+		.help = "specify hash calculation function",
+		.next = NEXT(next_table_attr,
+			     NEXT_ENTRY(TABLE_HASH_FUNC_NAME)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.table.attr.hash_func)),
+	},
+	[TABLE_HASH_FUNC_NAME] = {
+		.name = "hash_func_name",
+		.help = "hash calculation function name",
+		.call = parse_hash_table_type,
+		.comp = comp_hash_table_type,
+	},
 	[TABLE_GROUP] = {
 		.name = "group",
 		.help = "specify a group",
@@ -10123,6 +10150,32 @@ parse_insertion_table_type(struct context *ctx, const struct token *token,
 	return ret > 0 ? (int)len : ret;
 }
 
+/** Parse Hash Calculation Table Type name */
+static int
+parse_hash_table_type(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len, void *buf,
+		      unsigned int size)
+{
+	const struct arg *arg = pop_args(ctx);
+	unsigned int i;
+	char tmp[2];
+	int ret;
+
+	(void)size;
+	/* Argument is expected. */
+	if (!arg)
+		return -1;
+	for (i = 0; table_hash_funcs[i]; ++i)
+		if (!strcmp_partial(table_hash_funcs[i], str, len))
+			break;
+	if (!table_hash_funcs[i])
+		return -1;
+	push_args(ctx, arg);
+	snprintf(tmp, sizeof(tmp), "%u", i);
+	ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i));
+	return ret > 0 ? (int)len : ret;
+}
+
 /** No completion. */
 static int
 comp_none(struct context *ctx, const struct token *token,
@@ -10442,6 +10495,20 @@ comp_insertion_table_type(struct context *ctx, const struct token *token,
 	return -1;
 }
 
+/** Complete available Hash Calculation Table types. */
+static int
+comp_hash_table_type(struct context *ctx, const struct token *token,
+		     unsigned int ent, char *buf, unsigned int size)
+{
+	RTE_SET_USED(ctx);
+	RTE_SET_USED(token);
+	if (!buf)
+		return RTE_DIM(table_hash_funcs);
+	if (ent < RTE_DIM(table_hash_funcs) - 1)
+		return rte_strscpy(buf, table_hash_funcs[ent], size);
+	return -1;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
-- 
2.18.2


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

* Re: [PATCH v4 0/4] ethdev: add template table insertion and matching types
  2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
                           ` (3 preceding siblings ...)
  2023-02-08  3:06         ` [PATCH v4 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
@ 2023-02-10 17:42         ` Ferruh Yigit
  4 siblings, 0 replies; 31+ messages in thread
From: Ferruh Yigit @ 2023-02-10 17:42 UTC (permalink / raw)
  To: Alexander Kozyrev, dev; +Cc: thomas, andrew.rybchenko, orika

On 2/8/2023 3:06 AM, Alexander Kozyrev wrote:
> Bring more flexibility and control over both flow rule insertion
> and packet matching mechanisms. Introduce 2 new flow table types:
> 
> 1. Allow a user to specify the insertion type used in template tables.
> The insertion type is responsible for choosing the appropriate key
> value used to map inserted flow rules into a template table.
> 
> Flow rules can be inserted by calculating the hash value for
> the pattern or inserted by index via the new create_by_index() API.
> The idea of the index-based insertion is to avoid additional matches
> and simply execute predefined actions after jumping to the index.
> 
> The insertion into an already occupied index results in an error.
> The old rule must be destroyed first. An index cannot be bigger than
> the size of the table, otherwise, the rule is rejected as well.
> 
> 2. Allow a user to specify the hash calculation function used in template
> tables. The hash calculation type is responsible for the calculation of
> the flow rule index a packet would hit upon arrival at the table.
> 
> Control over this is useful for applications with custom RSS algorithms,
> for example. An application can select various packet fields to serve as
> a hash calculation source and jump to the appropriate flow rule location.
> The RSS hash result will be used as the index in the table. For the linear
> hash function, the mapping is one-to-one and the hash result is the index.
> For other hash functions, the index is the hash result module table size.
> The RSS hash result can be retrieved via modify_field API: HASH_RESULT.
> 
> RFC: https://patchwork.dpdk.org/project/dpdk/patch/20221214022110.393410-1-akozyrev@nvidia.com/
> v2: changed the behavior in case of insertion into the same index.
> v3: refined the commit message to highlight index-based table advantage.
> v4: fixed a typo in the commit message.
> 
> 
> Alexander Kozyrev (4):
>   ethdev: add template table insertion type
>   ethdev: add template table hash calculation function
>   app/testpmd: add template table insertion type
>   app/testpmd: add template table hash calculation function
>
> Series-acked-by:  Ori Kam <orika@nvidia.com>
>


Series applied to dpdk-next-net/main, thanks.

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

end of thread, other threads:[~2023-02-10 17:42 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-14  2:21 [RFC] ethdev: add template table insertion and matching types Alexander Kozyrev
2023-01-08 14:22 ` Ori Kam
2023-01-18  8:50 ` Thomas Monjalon
2023-01-20 23:06   ` Alexander Kozyrev
2023-01-22 20:55     ` Thomas Monjalon
2023-01-23 22:02       ` Alexander Kozyrev
2023-01-30 14:47         ` Thomas Monjalon
2023-01-21  5:21 ` [PATCH 0/4] " Alexander Kozyrev
2023-01-21  5:21   ` [PATCH 1/4] ethdev: add template table insertion type Alexander Kozyrev
2023-01-21  5:21   ` [PATCH 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
2023-01-21  5:21   ` [PATCH 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
2023-01-21  5:21   ` [PATCH 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
2023-01-26 23:27   ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
2023-01-26 23:27     ` [PATCH v2 1/4] ethdev: add template table insertion type Alexander Kozyrev
2023-02-02 10:57       ` Andrew Rybchenko
2023-02-07 15:06         ` Alexander Kozyrev
2023-01-26 23:28     ` [PATCH v2 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
2023-01-26 23:28     ` [PATCH v2 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
2023-01-26 23:28     ` [PATCH v2 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
2023-02-01 16:09     ` [PATCH v2 0/4] ethdev: add template table insertion and matching types Ori Kam
2023-02-08  2:47     ` [PATCH v3 " Alexander Kozyrev
2023-02-08  2:47       ` [PATCH v3 1/4] ethdev: add template table insertion type Alexander Kozyrev
2023-02-08  2:47       ` [PATCH v3 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
2023-02-08  2:47       ` [PATCH v3 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
2023-02-08  2:47       ` [PATCH v3 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
2023-02-08  3:06       ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Alexander Kozyrev
2023-02-08  3:06         ` [PATCH v4 1/4] ethdev: add template table insertion type Alexander Kozyrev
2023-02-08  3:06         ` [PATCH v4 2/4] ethdev: add template table hash calculation function Alexander Kozyrev
2023-02-08  3:06         ` [PATCH v4 3/4] app/testpmd: add template table insertion type Alexander Kozyrev
2023-02-08  3:06         ` [PATCH v4 4/4] app/testpmd: add template table hash calculation function Alexander Kozyrev
2023-02-10 17:42         ` [PATCH v4 0/4] ethdev: add template table insertion and matching types Ferruh Yigit

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