Implementing the VxLAN last reserved byte modification.
Following the RFC, the field is only 1 byte and needs to
use the field_length as 8 instead of the real dst_field->size.

Signed-off-by: Rongwei Liu <rongw...@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnow...@nvidia.com>
---
 doc/guides/nics/mlx5.rst        |  5 +++++
 drivers/net/mlx5/mlx5_flow_dv.c | 12 ++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c |  5 +++++
 3 files changed, 22 insertions(+)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index dcc1beb812..afa35bf1e6 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -685,6 +685,11 @@ Limitations
     - Second tunnel fields are not supported.
 
   - Encapsulation levels greater than ``2`` are not supported.
+  - Modification of the VXLAN header is supported with below limitations:
+
+    - Only in HW steering (``dv_flow_en=2``).
+    - Support VNI and rsvd1 modifications for traffic with default 
VXLAN/VXLAN-GPE/VXLAN-GBP
+      UDP destination port.
 
 - Age action:
 
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index f9c56af86c..7645369533 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1439,6 +1439,8 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
        case RTE_FLOW_FIELD_VXLAN_VNI:
        case RTE_FLOW_FIELD_GENEVE_VNI:
                return 24;
+       case RTE_FLOW_FIELD_VXLAN_RSVD1:
+               return 8;
        case RTE_FLOW_FIELD_GTP_TEID:
        case RTE_FLOW_FIELD_MPLS:
        case RTE_FLOW_FIELD_TAG:
@@ -2038,6 +2040,16 @@ mlx5_flow_field_id_to_modify_info
                else
                        info[idx].offset = off_be;
                break;
+       case RTE_FLOW_FIELD_VXLAN_RSVD1:
+               MLX5_ASSERT(data->offset + width <= 8);
+               /* Last_rsvd is on bits 7-0 of TUNNEL_HDR_DW_1. */
+               off_be = 8 - (data->offset + width);
+               info[idx] = (struct field_modify_info){1, 0, 
MLX5_MODI_TUNNEL_HDR_DW_1};
+               if (mask)
+                       mask[idx] = flow_modify_info_mask_8(width, off_be);
+               else
+                       info[idx].offset = off_be;
+               break;
        case RTE_FLOW_FIELD_GENEVE_OPT_TYPE:
                MLX5_ASSERT(data->offset + width <= 8);
                modi_id = flow_geneve_opt_modi_field_get(priv, data);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 80efcf44fa..e2d41707c8 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -1363,6 +1363,10 @@ flow_hw_modify_field_compile(struct rte_eth_dev *dev,
                        value = *(const uint8_t *)item.spec;
                        value = rte_cpu_to_be_32(value << 8);
                        item.spec = &value;
+               } else if (conf->dst.field == RTE_FLOW_FIELD_VXLAN_RSVD1) {
+                       value = *(const uint8_t *)item.spec << 24;
+                       value = rte_cpu_to_be_32(value);
+                       item.spec = &value;
                }
        } else {
                type = conf->operation == RTE_FLOW_MODIFY_SET ?
@@ -5494,6 +5498,7 @@ flow_hw_validate_modify_field_level(const struct 
rte_flow_field_data *data,
        case RTE_FLOW_FIELD_ESP_SPI:
        case RTE_FLOW_FIELD_ESP_SEQ_NUM:
        case RTE_FLOW_FIELD_VXLAN_VNI:
+       case RTE_FLOW_FIELD_VXLAN_RSVD1:
        case RTE_FLOW_FIELD_GENEVE_VNI:
        case RTE_FLOW_FIELD_GENEVE_OPT_TYPE:
        case RTE_FLOW_FIELD_GENEVE_OPT_CLASS:
-- 
2.27.0

Reply via email to