Commit 65fb7d10 authored by Alex Vesker's avatar Alex Vesker Committed by Saeed Mahameed

net/mlx5: DR, Fix STEv1 incorrect L3 decapsulation padding

Decapsulation L3 on small inner packets which are less than
64 Bytes was done incorrectly. In small packets there is an
extra padding added in L2 which should not be included in L3
length. The issue was that after decapL3 the extra L2 padding
caused an update on the L3 length.

To avoid this issue the new header is pushed to the beginning
of the packet (offset 0) which should not cause a HW reparse
and update the L3 length.

Fixes: c349b413 ("net/mlx5: DR, Add STEv1 modify header logic")
Reviewed-by: default avatarErez Shitrit <erezsh@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: default avatarAlex Vesker <valex@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c7d6c19b
......@@ -694,7 +694,11 @@ static int dr_ste_v1_set_action_decap_l3_list(void *data,
if (hw_action_sz / DR_STE_ACTION_DOUBLE_SZ < DR_STE_DECAP_L3_ACTION_NUM)
return -EINVAL;
memcpy(padded_data, data, data_sz);
inline_data_sz =
MLX5_FLD_SZ_BYTES(ste_double_action_insert_with_inline_v1, inline_data);
/* Add an alignment padding */
memcpy(padded_data + data_sz % inline_data_sz, data, data_sz);
/* Remove L2L3 outer headers */
MLX5_SET(ste_single_action_remove_header_v1, hw_action, action_id,
......@@ -706,32 +710,34 @@ static int dr_ste_v1_set_action_decap_l3_list(void *data,
hw_action += DR_STE_ACTION_DOUBLE_SZ;
used_actions++; /* Remove and NOP are a single double action */
inline_data_sz =
MLX5_FLD_SZ_BYTES(ste_double_action_insert_with_inline_v1, inline_data);
/* Point to the last dword of the header */
data_ptr += (data_sz / inline_data_sz) * inline_data_sz;
/* Add the new header inline + 2 extra bytes */
/* Add the new header using inline action 4Byte at a time, the header
* is added in reversed order to the beginning of the packet to avoid
* incorrect parsing by the HW. Since header is 14B or 18B an extra
* two bytes are padded and later removed.
*/
for (i = 0; i < data_sz / inline_data_sz + 1; i++) {
void *addr_inline;
MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, action_id,
DR_STE_V1_ACTION_ID_INSERT_INLINE);
/* The hardware expects here offset to words (2 bytes) */
MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, start_offset,
i * 2);
MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, start_offset, 0);
/* Copy bytes one by one to avoid endianness problem */
addr_inline = MLX5_ADDR_OF(ste_double_action_insert_with_inline_v1,
hw_action, inline_data);
memcpy(addr_inline, data_ptr, inline_data_sz);
memcpy(addr_inline, data_ptr - i * inline_data_sz, inline_data_sz);
hw_action += DR_STE_ACTION_DOUBLE_SZ;
data_ptr += inline_data_sz;
used_actions++;
}
/* Remove 2 extra bytes */
/* Remove first 2 extra bytes */
MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE);
MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, start_offset, data_sz / 2);
MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, start_offset, 0);
/* The hardware expects here size in words (2 bytes) */
MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, remove_size, 1);
used_actions++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment