diff options
author | Paul Blakey <paulb@mellanox.com> | 2017-09-05 08:05:51 -0400 |
---|---|---|
committer | Saeed Mahameed <saeedm@mellanox.com> | 2017-09-28 00:23:09 -0400 |
commit | ace743214ea205c7d433562c5fa24e33bdfda7ab (patch) | |
tree | 24b0e11cd1f38b74d43c361472ceb2a0118f70b3 | |
parent | 16f1c5bb3ed75b3cf3ced537db40f7e1a244debe (diff) |
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: 232c001398ae ('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>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index da503e6411da..4e2fc016bdd6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -1564,7 +1564,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, | |||
1564 | break; | 1564 | break; |
1565 | default: | 1565 | default: |
1566 | err = -EOPNOTSUPP; | 1566 | err = -EOPNOTSUPP; |
1567 | goto out; | 1567 | goto free_encap; |
1568 | } | 1568 | } |
1569 | fl4.flowi4_tos = tun_key->tos; | 1569 | fl4.flowi4_tos = tun_key->tos; |
1570 | fl4.daddr = tun_key->u.ipv4.dst; | 1570 | fl4.daddr = tun_key->u.ipv4.dst; |
@@ -1573,7 +1573,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, | |||
1573 | err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, | 1573 | err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, |
1574 | &fl4, &n, &ttl); | 1574 | &fl4, &n, &ttl); |
1575 | if (err) | 1575 | if (err) |
1576 | goto out; | 1576 | goto free_encap; |
1577 | 1577 | ||
1578 | /* used by mlx5e_detach_encap to lookup a neigh hash table | 1578 | /* used by mlx5e_detach_encap to lookup a neigh hash table |
1579 | * entry in the neigh hash table when a user deletes a rule | 1579 | * 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, | |||
1590 | */ | 1590 | */ |
1591 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); | 1591 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); |
1592 | if (err) | 1592 | if (err) |
1593 | goto out; | 1593 | goto free_encap; |
1594 | 1594 | ||
1595 | read_lock_bh(&n->lock); | 1595 | read_lock_bh(&n->lock); |
1596 | nud_state = n->nud_state; | 1596 | nud_state = n->nud_state; |
@@ -1630,8 +1630,9 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, | |||
1630 | 1630 | ||
1631 | destroy_neigh_entry: | 1631 | destroy_neigh_entry: |
1632 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); | 1632 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); |
1633 | out: | 1633 | free_encap: |
1634 | kfree(encap_header); | 1634 | kfree(encap_header); |
1635 | out: | ||
1635 | if (n) | 1636 | if (n) |
1636 | neigh_release(n); | 1637 | neigh_release(n); |
1637 | return err; | 1638 | return err; |
@@ -1668,7 +1669,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, | |||
1668 | break; | 1669 | break; |
1669 | default: | 1670 | default: |
1670 | err = -EOPNOTSUPP; | 1671 | err = -EOPNOTSUPP; |
1671 | goto out; | 1672 | goto free_encap; |
1672 | } | 1673 | } |
1673 | 1674 | ||
1674 | fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tun_key->tos), tun_key->label); | 1675 | 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, | |||
1678 | err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, | 1679 | err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, |
1679 | &fl6, &n, &ttl); | 1680 | &fl6, &n, &ttl); |
1680 | if (err) | 1681 | if (err) |
1681 | goto out; | 1682 | goto free_encap; |
1682 | 1683 | ||
1683 | /* used by mlx5e_detach_encap to lookup a neigh hash table | 1684 | /* used by mlx5e_detach_encap to lookup a neigh hash table |
1684 | * entry in the neigh hash table when a user deletes a rule | 1685 | * 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, | |||
1695 | */ | 1696 | */ |
1696 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); | 1697 | err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); |
1697 | if (err) | 1698 | if (err) |
1698 | goto out; | 1699 | goto free_encap; |
1699 | 1700 | ||
1700 | read_lock_bh(&n->lock); | 1701 | read_lock_bh(&n->lock); |
1701 | nud_state = n->nud_state; | 1702 | nud_state = n->nud_state; |
@@ -1736,8 +1737,9 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, | |||
1736 | 1737 | ||
1737 | destroy_neigh_entry: | 1738 | destroy_neigh_entry: |
1738 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); | 1739 | mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); |
1739 | out: | 1740 | free_encap: |
1740 | kfree(encap_header); | 1741 | kfree(encap_header); |
1742 | out: | ||
1741 | if (n) | 1743 | if (n) |
1742 | neigh_release(n); | 1744 | neigh_release(n); |
1743 | return err; | 1745 | return err; |