Skip to content

Commit

Permalink
net/mlx5: DR, Fix STEv1 incorrect L3 decapsulation padding
Browse files Browse the repository at this point in the history
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: c349b41 ("net/mlx5: DR, Add STEv1 modify header logic")
Reviewed-by: Erez Shitrit <[email protected]>
Reviewed-by: Yevgeny Kliteynik <[email protected]>
Signed-off-by: Alex Vesker <[email protected]>
Signed-off-by: Saeed Mahameed <[email protected]>
  • Loading branch information
alexvesker authored and Saeed Mahameed committed Jun 16, 2021
1 parent c7d6c19 commit 65fb7d1
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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++;
Expand Down

0 comments on commit 65fb7d1

Please sign in to comment.