Hi Ferruh,

Can you please review my patch?

Thanks,
Ori

> -----Original Message-----
> From: Ori Kam <or...@nvidia.com>
> Sent: Sunday, January 28, 2024 11:40 AM
> To: Dariusz Sosnowski <dsosnow...@nvidia.com>; ferruh.yi...@amd.com;
> 
> During the encapsulation of a packet, it is expected to calculate the
> hash value which is based on the original packet (the outer values,
> which will become the inner values).
> 
> The tunnel protocol defines which tunnel field should hold this hash,
> but it doesn't define the hash calculation algorithm.
> 
> An application that uses flow offloads gets the first few packets
> and then decides to offload the flow. As a result, there are two
> different paths that a packet from a given flow may take.
> SW for the first few packets or HW for the rest.
> When the packet goes through the SW, the SW encapsulates the packet
> and must use the same hash calculation as the HW will do for
> the rest of the packets in this flow.
> 
> This patch gives the SW a way to query the hash value
> for a given packet as if the packet was passed through the HW.
> 
> Signed-off-by: Ori Kam <or...@nvidia.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst     | 22 ++++++++++++
>  doc/guides/rel_notes/release_24_03.rst |  4 +++
>  lib/ethdev/rte_flow.c                  | 25 +++++++++++++
>  lib/ethdev/rte_flow.h                  | 50 ++++++++++++++++++++++++++
>  lib/ethdev/rte_flow_driver.h           |  5 +++
>  lib/ethdev/version.map                 |  1 +
>  6 files changed, 107 insertions(+)
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index 900fdaefb6..0435dda3c7 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -4211,6 +4211,28 @@ as it would be calculated in the HW.
>                              uint8_t pattern_template_index,
>                                          uint32_t *hash, struct rte_flow_error
> *error);
> 
> +Calculate encap hash
> +~~~~~~~~~~~~~~~~~~~~
> +
> +Calculating hash of a packet in SW as it would be calculated in HW for the
> encap action
> +
> +When the HW execute an encapsulation action, it may calculate an hash
> value which is based
> +on the original packet. This hash is stored depending on the encapsulation
> protocol, in one
> +of the outer fields.
> +
> +This function allows the application to calculate the hash for a given packet
> as if the
> +encapsulation was done in HW.
> +
> +.. code-block:: c
> +
> +   int
> +   rte_flow_calc_encap_hash(uint16_t port_id,
> +                            const struct rte_flow_item pattern[],
> +                                        enum rte_flow_encap_hash_field
> dest_field,
> +                            uint8_t hash_len,
> +                            uint8_t *hash,
> +                                        struct rte_flow_error *error);
> +
>  .. _flow_isolated_mode:
> 
>  Flow isolated mode
> diff --git a/doc/guides/rel_notes/release_24_03.rst
> b/doc/guides/rel_notes/release_24_03.rst
> index 5e545da867..80af380172 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -75,6 +75,10 @@ New Features
>    * Added support for VXLAN-GPE matching in HW Steering flow engine
>      (``dv_flow_en`` = 2).
> 
> +* **Added ability to calculate the encap hash as done by HW.**
> +
> +  * Added function that calculates the encap hash, as the HW calculates it:
> +    ``rte_flow_calc_encap_hash()``
> 
>  Removed Items
>  -------------
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 3f58d792f9..7fce754be1 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -2482,3 +2482,28 @@ rte_flow_calc_table_hash(uint16_t port_id, const
> struct rte_flow_template_table
>                                       hash, error);
>       return flow_err(port_id, ret, error);
>  }
> +
> +int
> +rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item
> pattern[],
> +                      enum rte_flow_encap_hash_field dest_field, uint8_t
> hash_len,
> +                      uint8_t *hash, struct rte_flow_error *error)
> +{
> +     int ret;
> +     struct rte_eth_dev *dev;
> +     const struct rte_flow_ops *ops;
> +
> +     RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +     ops = rte_flow_ops_get(port_id, error);
> +     if (!ops || !ops->flow_calc_encap_hash)
> +             return rte_flow_error_set(error, ENOTSUP,
> +
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> +                                       "calc encap hash is not supported");
> +     if ((dest_field == RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT &&
> hash_len != 2) ||
> +         (dest_field == RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID
> && hash_len != 1))
> +             return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> +                                       "hash len doesn't match the
> requested field len");
> +     dev = &rte_eth_devices[port_id];
> +     ret = ops->flow_calc_encap_hash(dev, pattern, dest_field, hash,
> error);
> +     return flow_err(port_id, ret, error);
> +}
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index 1267c146e5..ffbde58245 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -6783,6 +6783,56 @@ rte_flow_calc_table_hash(uint16_t port_id, const
> struct rte_flow_template_table
>                        const struct rte_flow_item pattern[], uint8_t
> pattern_template_index,
>                        uint32_t *hash, struct rte_flow_error *error);
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Destination field type for the hash calculation, when encap action is 
> used.
> + *
> + * @see function rte_flow_calc_encap_hash
> + */
> +enum rte_flow_encap_hash_field {
> +     /* Calculate hash placed in UDP source port field. */
> +     RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT,
> +     /* Calculate hash placed in NVGRE flow ID field. */
> +     RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID,
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Simulates HW hash calculation that is done when encap action is being
> used.
> + *
> + * @param[in] port_id
> + *   Port identifier of Ethernet device.
> + * @param[in] pattern
> + *   The values to be used in the hash calculation.
> + * @param[in] dest_field
> + *   Type of destination field for hash calculation.
> + * @param[in] hash_len
> + *   The length of the hash pointer in bytes. Should be according to
> encap_hash_field.
> + * @param[out] hash
> + *   Used to return the calculated hash. It will be written in network order,
> + *   so hash[0] is the MSB.
> + *   The number of bytes is based on the destination field type.
> + * @param[out] error
> + *   Perform verbose error reporting if not NULL.
> + *   PMDs initialize this structure in case of error only.
> + *
> + * @return
> + *   - (0) if success.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-ENOTSUP) if underlying device does not support this functionality.
> + *   - (-EINVAL) if *pattern* doesn't hold enough information to calculate 
> the
> hash
> + *               or the dest is not supported.
> + */
> +__rte_experimental
> +int
> +rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item
> pattern[],
> +                      enum rte_flow_encap_hash_field dest_field, uint8_t
> hash_len,
> +                      uint8_t *hash, struct rte_flow_error *error);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
> index f35f659503..447163655a 100644
> --- a/lib/ethdev/rte_flow_driver.h
> +++ b/lib/ethdev/rte_flow_driver.h
> @@ -370,6 +370,11 @@ struct rte_flow_ops {
>               (struct rte_eth_dev *dev, const struct
> rte_flow_template_table *table,
>                const struct rte_flow_item pattern[], uint8_t
> pattern_template_index,
>                uint32_t *hash, struct rte_flow_error *error);
> +     /** @see rte_flow_calc_encap_hash() */
> +     int (*flow_calc_encap_hash)
> +             (struct rte_eth_dev *dev, const struct rte_flow_item
> pattern[],
> +              enum rte_flow_encap_hash_field dest_field, uint8_t *hash,
> +              struct rte_flow_error *error);
>  };
> 
>  /**
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index a050baab0f..360898d067 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -319,6 +319,7 @@ EXPERIMENTAL {
> 
>       # added in 24.03
>       rte_eth_find_rss_algo;
> +     rte_flow_calc_encap_hash;
>  };
> 
>  INTERNAL {
> --
> 2.34.1

Reply via email to