Skip to content

Commit 033354d

Browse files
hadarhenzionSaeed Mahameed
authored andcommitted
net/mlx5e: Read neigh parameters with proper locking
The nud_state and hardware address fields are protected by the neighbour lock, we should acquire it before accessing those parameters. Use this lock to avoid inconsistency between the neighbour validity state and it's hardware address. Signed-off-by: Hadar Hen Zion <[email protected]> Reviewed-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 0b67a38 commit 033354d

File tree

1 file changed

+14
-6
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+14
-6
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
12231223
struct flowi4 fl4 = {};
12241224
char *encap_header;
12251225
int ttl, err;
1226+
u8 nud_state;
12261227

12271228
if (max_encap_size < ipv4_encap_size) {
12281229
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
@@ -1252,7 +1253,12 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
12521253
if (err)
12531254
goto out;
12541255

1255-
if (!(n->nud_state & NUD_VALID)) {
1256+
read_lock_bh(&n->lock);
1257+
nud_state = n->nud_state;
1258+
ether_addr_copy(e->h_dest, n->ha);
1259+
read_unlock_bh(&n->lock);
1260+
1261+
if (!(nud_state & NUD_VALID)) {
12561262
pr_warn("%s: can't offload, neighbour to %pI4 invalid\n", __func__, &fl4.daddr);
12571263
err = -EOPNOTSUPP;
12581264
goto out;
@@ -1261,8 +1267,6 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
12611267
e->n = n;
12621268
e->out_dev = out_dev;
12631269

1264-
neigh_ha_snapshot(e->h_dest, n, out_dev);
1265-
12661270
switch (e->tunnel_type) {
12671271
case MLX5_HEADER_TYPE_VXLAN:
12681272
gen_vxlan_header_ipv4(out_dev, encap_header,
@@ -1297,6 +1301,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
12971301
struct flowi6 fl6 = {};
12981302
char *encap_header;
12991303
int err, ttl = 0;
1304+
u8 nud_state;
13001305

13011306
if (max_encap_size < ipv6_encap_size) {
13021307
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
@@ -1327,7 +1332,12 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
13271332
if (err)
13281333
goto out;
13291334

1330-
if (!(n->nud_state & NUD_VALID)) {
1335+
read_lock_bh(&n->lock);
1336+
nud_state = n->nud_state;
1337+
ether_addr_copy(e->h_dest, n->ha);
1338+
read_unlock_bh(&n->lock);
1339+
1340+
if (!(nud_state & NUD_VALID)) {
13311341
pr_warn("%s: can't offload, neighbour to %pI6 invalid\n", __func__, &fl6.daddr);
13321342
err = -EOPNOTSUPP;
13331343
goto out;
@@ -1336,8 +1346,6 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
13361346
e->n = n;
13371347
e->out_dev = out_dev;
13381348

1339-
neigh_ha_snapshot(e->h_dest, n, out_dev);
1340-
13411349
switch (e->tunnel_type) {
13421350
case MLX5_HEADER_TYPE_VXLAN:
13431351
gen_vxlan_header_ipv6(out_dev, encap_header,

0 commit comments

Comments
 (0)