Commit 033354d5 authored by Hadar Hen Zion's avatar Hadar Hen Zion Committed by Saeed Mahameed

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: default avatarHadar Hen Zion <hadarh@mellanox.com>
Reviewed-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 0b67a38f
...@@ -1223,6 +1223,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, ...@@ -1223,6 +1223,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
struct flowi4 fl4 = {}; struct flowi4 fl4 = {};
char *encap_header; char *encap_header;
int ttl, err; int ttl, err;
u8 nud_state;
if (max_encap_size < ipv4_encap_size) { if (max_encap_size < ipv4_encap_size) {
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n", 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, ...@@ -1252,7 +1253,12 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
if (err) if (err)
goto out; goto out;
if (!(n->nud_state & NUD_VALID)) { read_lock_bh(&n->lock);
nud_state = n->nud_state;
ether_addr_copy(e->h_dest, n->ha);
read_unlock_bh(&n->lock);
if (!(nud_state & NUD_VALID)) {
pr_warn("%s: can't offload, neighbour to %pI4 invalid\n", __func__, &fl4.daddr); pr_warn("%s: can't offload, neighbour to %pI4 invalid\n", __func__, &fl4.daddr);
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
...@@ -1261,8 +1267,6 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, ...@@ -1261,8 +1267,6 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
e->n = n; e->n = n;
e->out_dev = out_dev; e->out_dev = out_dev;
neigh_ha_snapshot(e->h_dest, n, out_dev);
switch (e->tunnel_type) { switch (e->tunnel_type) {
case MLX5_HEADER_TYPE_VXLAN: case MLX5_HEADER_TYPE_VXLAN:
gen_vxlan_header_ipv4(out_dev, encap_header, gen_vxlan_header_ipv4(out_dev, encap_header,
...@@ -1297,6 +1301,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, ...@@ -1297,6 +1301,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
struct flowi6 fl6 = {}; struct flowi6 fl6 = {};
char *encap_header; char *encap_header;
int err, ttl = 0; int err, ttl = 0;
u8 nud_state;
if (max_encap_size < ipv6_encap_size) { if (max_encap_size < ipv6_encap_size) {
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n", 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, ...@@ -1327,7 +1332,12 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
if (err) if (err)
goto out; goto out;
if (!(n->nud_state & NUD_VALID)) { read_lock_bh(&n->lock);
nud_state = n->nud_state;
ether_addr_copy(e->h_dest, n->ha);
read_unlock_bh(&n->lock);
if (!(nud_state & NUD_VALID)) {
pr_warn("%s: can't offload, neighbour to %pI6 invalid\n", __func__, &fl6.daddr); pr_warn("%s: can't offload, neighbour to %pI6 invalid\n", __func__, &fl6.daddr);
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
...@@ -1336,8 +1346,6 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, ...@@ -1336,8 +1346,6 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
e->n = n; e->n = n;
e->out_dev = out_dev; e->out_dev = out_dev;
neigh_ha_snapshot(e->h_dest, n, out_dev);
switch (e->tunnel_type) { switch (e->tunnel_type) {
case MLX5_HEADER_TYPE_VXLAN: case MLX5_HEADER_TYPE_VXLAN:
gen_vxlan_header_ipv6(out_dev, encap_header, gen_vxlan_header_ipv6(out_dev, encap_header,
......
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