Skip to content

Commit c8e350e

Browse files
Jianbo Liukuba-moo
authored andcommitted
net/mlx5e: Make TC and IPsec offloads mutually exclusive on a netdev
For IPsec packet offload mode, the order of TC offload and IPsec offload on the same netdevice is not aligned with the order in the non-offload software. For example, for RX, the software performs TC first and then IPsec transformation, but the implementation for offload does that in the opposite way. To resolve the difference for now, either IPsec offload or TC offload, not both, is allowed for a specific interface. Signed-off-by: Jianbo Liu <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/8e2e5e3b0984d785066e8663aaf97b3ba1bb873f.1690802064.git.leon@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6e56ab1 commit c8e350e

File tree

3 files changed

+129
-4
lines changed

3 files changed

+129
-4
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,12 +1717,68 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void *ipsec_stats)
17171717
}
17181718
}
17191719

1720+
#ifdef CONFIG_MLX5_ESWITCH
1721+
static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
1722+
{
1723+
struct mlx5_eswitch *esw = mdev->priv.eswitch;
1724+
int err = 0;
1725+
1726+
if (esw)
1727+
down_write(&esw->mode_lock);
1728+
1729+
if (mdev->num_block_ipsec) {
1730+
err = -EBUSY;
1731+
goto unlock;
1732+
}
1733+
1734+
mdev->num_block_tc++;
1735+
1736+
unlock:
1737+
if (esw)
1738+
up_write(&esw->mode_lock);
1739+
1740+
return err;
1741+
}
1742+
#else
1743+
static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
1744+
{
1745+
if (mdev->num_block_ipsec)
1746+
return -EBUSY;
1747+
1748+
mdev->num_block_tc++;
1749+
return 0;
1750+
}
1751+
#endif
1752+
1753+
static void mlx5e_ipsec_unblock_tc_offload(struct mlx5_core_dev *mdev)
1754+
{
1755+
mdev->num_block_tc++;
1756+
}
1757+
17201758
int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
17211759
{
1760+
int err;
1761+
1762+
if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET) {
1763+
err = mlx5e_ipsec_block_tc_offload(sa_entry->ipsec->mdev);
1764+
if (err)
1765+
return err;
1766+
}
1767+
17221768
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
1723-
return tx_add_rule(sa_entry);
1769+
err = tx_add_rule(sa_entry);
1770+
else
1771+
err = rx_add_rule(sa_entry);
1772+
1773+
if (err)
1774+
goto err_out;
1775+
1776+
return 0;
17241777

1725-
return rx_add_rule(sa_entry);
1778+
err_out:
1779+
if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
1780+
mlx5e_ipsec_unblock_tc_offload(sa_entry->ipsec->mdev);
1781+
return err;
17261782
}
17271783

17281784
void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
@@ -1735,6 +1791,9 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
17351791
if (ipsec_rule->pkt_reformat)
17361792
mlx5_packet_reformat_dealloc(mdev, ipsec_rule->pkt_reformat);
17371793

1794+
if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
1795+
mlx5e_ipsec_unblock_tc_offload(mdev);
1796+
17381797
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT) {
17391798
tx_ft_put(sa_entry->ipsec, sa_entry->attrs.type);
17401799
return;
@@ -1747,10 +1806,25 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
17471806

17481807
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
17491808
{
1809+
int err;
1810+
1811+
err = mlx5e_ipsec_block_tc_offload(pol_entry->ipsec->mdev);
1812+
if (err)
1813+
return err;
1814+
17501815
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
1751-
return tx_add_policy(pol_entry);
1816+
err = tx_add_policy(pol_entry);
1817+
else
1818+
err = rx_add_policy(pol_entry);
1819+
1820+
if (err)
1821+
goto err_out;
1822+
1823+
return 0;
17521824

1753-
return rx_add_policy(pol_entry);
1825+
err_out:
1826+
mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
1827+
return err;
17541828
}
17551829

17561830
void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
@@ -1760,6 +1834,8 @@ void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
17601834

17611835
mlx5_del_flow_rules(ipsec_rule->rule);
17621836

1837+
mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
1838+
17631839
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
17641840
rx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.family,
17651841
pol_entry->attrs.prio, pol_entry->attrs.type);

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,6 +4606,46 @@ static bool is_flow_rule_duplicate_allowed(struct net_device *dev,
46064606
return netif_is_lag_port(dev) && rpriv && rpriv->rep->vport != MLX5_VPORT_UPLINK;
46074607
}
46084608

4609+
/* As IPsec and TC order is not aligned between software and hardware-offload,
4610+
* either IPsec offload or TC offload, not both, is allowed for a specific interface.
4611+
*/
4612+
static bool is_tc_ipsec_order_check_needed(struct net_device *filter, struct mlx5e_priv *priv)
4613+
{
4614+
if (!IS_ENABLED(CONFIG_MLX5_EN_IPSEC))
4615+
return false;
4616+
4617+
if (filter != priv->netdev)
4618+
return false;
4619+
4620+
if (mlx5e_eswitch_vf_rep(priv->netdev))
4621+
return false;
4622+
4623+
return true;
4624+
}
4625+
4626+
static int mlx5e_tc_block_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
4627+
{
4628+
struct mlx5_core_dev *mdev = priv->mdev;
4629+
4630+
if (!is_tc_ipsec_order_check_needed(filter, priv))
4631+
return 0;
4632+
4633+
if (mdev->num_block_tc)
4634+
return -EBUSY;
4635+
4636+
mdev->num_block_ipsec++;
4637+
4638+
return 0;
4639+
}
4640+
4641+
static void mlx5e_tc_unblock_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
4642+
{
4643+
if (!is_tc_ipsec_order_check_needed(filter, priv))
4644+
return;
4645+
4646+
priv->mdev->num_block_ipsec--;
4647+
}
4648+
46094649
int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
46104650
struct flow_cls_offload *f, unsigned long flags)
46114651
{
@@ -4618,6 +4658,10 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
46184658
if (!mlx5_esw_hold(priv->mdev))
46194659
return -EBUSY;
46204660

4661+
err = mlx5e_tc_block_ipsec_offload(dev, priv);
4662+
if (err)
4663+
goto esw_release;
4664+
46214665
mlx5_esw_get(priv->mdev);
46224666

46234667
rcu_read_lock();
@@ -4663,7 +4707,9 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
46634707
err_free:
46644708
mlx5e_flow_put(priv, flow);
46654709
out:
4710+
mlx5e_tc_unblock_ipsec_offload(dev, priv);
46664711
mlx5_esw_put(priv->mdev);
4712+
esw_release:
46674713
mlx5_esw_release(priv->mdev);
46684714
return err;
46694715
}
@@ -4704,6 +4750,7 @@ int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv,
47044750
trace_mlx5e_delete_flower(f);
47054751
mlx5e_flow_put(priv, flow);
47064752

4753+
mlx5e_tc_unblock_ipsec_offload(dev, priv);
47074754
mlx5_esw_put(priv->mdev);
47084755
return 0;
47094756

include/linux/mlx5/driver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,8 @@ struct mlx5_core_dev {
806806
u32 vsc_addr;
807807
struct mlx5_hv_vhca *hv_vhca;
808808
struct mlx5_thermal *thermal;
809+
u64 num_block_tc;
810+
u64 num_block_ipsec;
809811
};
810812

811813
struct mlx5_db {

0 commit comments

Comments
 (0)