Skip to content

Commit 0c101a2

Browse files
w1ldptrkuba-moo
authored andcommitted
net/mlx5e: Fix pedit endianness
Referenced commit addressed endianness issue in mlx5 pedit implementation in ad hoc manner instead of systematically treating integer values according to their types which left pedit fields of sizes not equal to 4 and where the bytes being modified are not least significant ones broken on big endian machines since wrong bits will be consumed during parsing which leads to following example error when applying pedit to source and destination MAC addresses: [Wed Oct 18 12:52:42 2023] mlx5_core 0001:00:00.1 p1v3_r: attempt to offload an unsupported field (cmd 0) [Wed Oct 18 12:52:42 2023] mask: 00000000330c5b68: 00 00 00 00 ff ff 00 00 00 00 ff ff 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 0000000017d22fd9: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 000000008186d717: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 0000000029eb6149: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 000000007ed103e4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 00000000db8101a6: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [Wed Oct 18 12:52:42 2023] mask: 00000000ec3c08a9: 00 00 00 00 00 00 00 00 00 00 00 00 ............ Treat masks and values of pedit and filter match as network byte order, refactor pointers to them to void pointers instead of confusing u32 pointers and only cast to pointer-to-integer when reading a value from them. Treat pedit mlx5_fields->field_mask as host byte order according to its type u32, change the constants in fields array accordingly. Fixes: 82198d8 ("net/mlx5e: Fix endianness when calculating pedit mask first bit") Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Gal Pressman <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3a4aa3c commit 0c101a2

File tree

1 file changed

+32
-28
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+32
-28
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,7 +3147,7 @@ static struct mlx5_fields fields[] = {
31473147
OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0,
31483148
dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]),
31493149
OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit),
3150-
OFFLOAD(IP_DSCP, 16, 0xc00f, ip6, 0, ip_dscp),
3150+
OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp),
31513151

31523152
OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport),
31533153
OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport),
@@ -3158,21 +3158,31 @@ static struct mlx5_fields fields[] = {
31583158
OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport),
31593159
};
31603160

3161-
static unsigned long mask_to_le(unsigned long mask, int size)
3161+
static u32 mask_field_get(void *mask, struct mlx5_fields *f)
31623162
{
3163-
__be32 mask_be32;
3164-
__be16 mask_be16;
3165-
3166-
if (size == 32) {
3167-
mask_be32 = (__force __be32)(mask);
3168-
mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32));
3169-
} else if (size == 16) {
3170-
mask_be32 = (__force __be32)(mask);
3171-
mask_be16 = *(__be16 *)&mask_be32;
3172-
mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16));
3163+
switch (f->field_bsize) {
3164+
case 32:
3165+
return be32_to_cpu(*(__be32 *)mask) & f->field_mask;
3166+
case 16:
3167+
return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask;
3168+
default:
3169+
return *(u8 *)mask & (u8)f->field_mask;
31733170
}
3171+
}
31743172

3175-
return mask;
3173+
static void mask_field_clear(void *mask, struct mlx5_fields *f)
3174+
{
3175+
switch (f->field_bsize) {
3176+
case 32:
3177+
*(__be32 *)mask &= ~cpu_to_be32(f->field_mask);
3178+
break;
3179+
case 16:
3180+
*(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask);
3181+
break;
3182+
default:
3183+
*(u8 *)mask &= ~(u8)f->field_mask;
3184+
break;
3185+
}
31763186
}
31773187

31783188
static int offload_pedit_fields(struct mlx5e_priv *priv,
@@ -3184,11 +3194,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
31843194
struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals;
31853195
struct pedit_headers_action *hdrs = parse_attr->hdrs;
31863196
void *headers_c, *headers_v, *action, *vals_p;
3187-
u32 *s_masks_p, *a_masks_p, s_mask, a_mask;
31883197
struct mlx5e_tc_mod_hdr_acts *mod_acts;
3189-
unsigned long mask, field_mask;
3198+
void *s_masks_p, *a_masks_p;
31903199
int i, first, last, next_z;
31913200
struct mlx5_fields *f;
3201+
unsigned long mask;
3202+
u32 s_mask, a_mask;
31923203
u8 cmd;
31933204

31943205
mod_acts = &parse_attr->mod_hdr_acts;
@@ -3204,15 +3215,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
32043215
bool skip;
32053216

32063217
f = &fields[i];
3207-
/* avoid seeing bits set from previous iterations */
3208-
s_mask = 0;
3209-
a_mask = 0;
3210-
32113218
s_masks_p = (void *)set_masks + f->offset;
32123219
a_masks_p = (void *)add_masks + f->offset;
32133220

3214-
s_mask = *s_masks_p & f->field_mask;
3215-
a_mask = *a_masks_p & f->field_mask;
3221+
s_mask = mask_field_get(s_masks_p, f);
3222+
a_mask = mask_field_get(a_masks_p, f);
32163223

32173224
if (!s_mask && !a_mask) /* nothing to offload here */
32183225
continue;
@@ -3239,22 +3246,20 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
32393246
match_mask, f->field_bsize))
32403247
skip = true;
32413248
/* clear to denote we consumed this field */
3242-
*s_masks_p &= ~f->field_mask;
3249+
mask_field_clear(s_masks_p, f);
32433250
} else {
32443251
cmd = MLX5_ACTION_TYPE_ADD;
32453252
mask = a_mask;
32463253
vals_p = (void *)add_vals + f->offset;
32473254
/* add 0 is no change */
3248-
if ((*(u32 *)vals_p & f->field_mask) == 0)
3255+
if (!mask_field_get(vals_p, f))
32493256
skip = true;
32503257
/* clear to denote we consumed this field */
3251-
*a_masks_p &= ~f->field_mask;
3258+
mask_field_clear(a_masks_p, f);
32523259
}
32533260
if (skip)
32543261
continue;
32553262

3256-
mask = mask_to_le(mask, f->field_bsize);
3257-
32583263
first = find_first_bit(&mask, f->field_bsize);
32593264
next_z = find_next_zero_bit(&mask, f->field_bsize, first);
32603265
last = find_last_bit(&mask, f->field_bsize);
@@ -3281,10 +3286,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv,
32813286
MLX5_SET(set_action_in, action, field, f->field);
32823287

32833288
if (cmd == MLX5_ACTION_TYPE_SET) {
3289+
unsigned long field_mask = f->field_mask;
32843290
int start;
32853291

3286-
field_mask = mask_to_le(f->field_mask, f->field_bsize);
3287-
32883292
/* if field is bit sized it can start not from first bit */
32893293
start = find_first_bit(&field_mask, f->field_bsize);
32903294

0 commit comments

Comments
 (0)