net/mlx5e: Fix erroneous freeing of encap header buffer

In case the neighbour for the tunnel destination isn't valid,
we send a neighbour update request but we free the encap
header buffer. This is wrong, because we still need it for
allocating a HW encap entry once the neighbour is available.

Fix that by skipping freeing it if we wait for neighbour.

Fixes: 232c001398 ('net/mlx5e: Add support to neighbour update flow')
Signed-off-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
Paul Blakey 2017-09-05 15:05:51 +03:00 committed by Saeed Mahameed
parent 16f1c5bb3e
commit ace743214e

View File

@ -1564,7 +1564,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
break; break;
default: default:
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto free_encap;
} }
fl4.flowi4_tos = tun_key->tos; fl4.flowi4_tos = tun_key->tos;
fl4.daddr = tun_key->u.ipv4.dst; fl4.daddr = tun_key->u.ipv4.dst;
@ -1573,7 +1573,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev,
&fl4, &n, &ttl); &fl4, &n, &ttl);
if (err) if (err)
goto out; goto free_encap;
/* used by mlx5e_detach_encap to lookup a neigh hash table /* used by mlx5e_detach_encap to lookup a neigh hash table
* entry in the neigh hash table when a user deletes a rule * entry in the neigh hash table when a user deletes a rule
@ -1590,7 +1590,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
*/ */
err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e);
if (err) if (err)
goto out; goto free_encap;
read_lock_bh(&n->lock); read_lock_bh(&n->lock);
nud_state = n->nud_state; nud_state = n->nud_state;
@ -1630,8 +1630,9 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
destroy_neigh_entry: destroy_neigh_entry:
mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e);
out: free_encap:
kfree(encap_header); kfree(encap_header);
out:
if (n) if (n)
neigh_release(n); neigh_release(n);
return err; return err;
@ -1668,7 +1669,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
break; break;
default: default:
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto free_encap;
} }
fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tun_key->tos), tun_key->label); fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tun_key->tos), tun_key->label);
@ -1678,7 +1679,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev,
&fl6, &n, &ttl); &fl6, &n, &ttl);
if (err) if (err)
goto out; goto free_encap;
/* used by mlx5e_detach_encap to lookup a neigh hash table /* used by mlx5e_detach_encap to lookup a neigh hash table
* entry in the neigh hash table when a user deletes a rule * entry in the neigh hash table when a user deletes a rule
@ -1695,7 +1696,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
*/ */
err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e);
if (err) if (err)
goto out; goto free_encap;
read_lock_bh(&n->lock); read_lock_bh(&n->lock);
nud_state = n->nud_state; nud_state = n->nud_state;
@ -1736,8 +1737,9 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
destroy_neigh_entry: destroy_neigh_entry:
mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e);
out: free_encap:
kfree(encap_header); kfree(encap_header);
out:
if (n) if (n)
neigh_release(n); neigh_release(n);
return err; return err;