Skip to content

Commit

Permalink
net/mlx5e: Make TC and IPsec offloads mutually exclusive on a netdev
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Jianbo Liu authored and kuba-moo committed Aug 3, 2023
1 parent 6e56ab1 commit c8e350e
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 4 deletions.
84 changes: 80 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1717,12 +1717,68 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void *ipsec_stats)
}
}

#ifdef CONFIG_MLX5_ESWITCH
static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
{
struct mlx5_eswitch *esw = mdev->priv.eswitch;
int err = 0;

if (esw)
down_write(&esw->mode_lock);

if (mdev->num_block_ipsec) {
err = -EBUSY;
goto unlock;
}

mdev->num_block_tc++;

unlock:
if (esw)
up_write(&esw->mode_lock);

return err;
}
#else
static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
{
if (mdev->num_block_ipsec)
return -EBUSY;

mdev->num_block_tc++;
return 0;
}
#endif

static void mlx5e_ipsec_unblock_tc_offload(struct mlx5_core_dev *mdev)
{
mdev->num_block_tc++;
}

int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
{
int err;

if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET) {
err = mlx5e_ipsec_block_tc_offload(sa_entry->ipsec->mdev);
if (err)
return err;
}

if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
return tx_add_rule(sa_entry);
err = tx_add_rule(sa_entry);
else
err = rx_add_rule(sa_entry);

if (err)
goto err_out;

return 0;

return rx_add_rule(sa_entry);
err_out:
if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
mlx5e_ipsec_unblock_tc_offload(sa_entry->ipsec->mdev);
return err;
}

void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
Expand All @@ -1735,6 +1791,9 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
if (ipsec_rule->pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, ipsec_rule->pkt_reformat);

if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
mlx5e_ipsec_unblock_tc_offload(mdev);

if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT) {
tx_ft_put(sa_entry->ipsec, sa_entry->attrs.type);
return;
Expand All @@ -1747,10 +1806,25 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)

int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
{
int err;

err = mlx5e_ipsec_block_tc_offload(pol_entry->ipsec->mdev);
if (err)
return err;

if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
return tx_add_policy(pol_entry);
err = tx_add_policy(pol_entry);
else
err = rx_add_policy(pol_entry);

if (err)
goto err_out;

return 0;

return rx_add_policy(pol_entry);
err_out:
mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
return err;
}

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

mlx5_del_flow_rules(ipsec_rule->rule);

mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);

if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
rx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.family,
pol_entry->attrs.prio, pol_entry->attrs.type);
Expand Down
47 changes: 47 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4606,6 +4606,46 @@ static bool is_flow_rule_duplicate_allowed(struct net_device *dev,
return netif_is_lag_port(dev) && rpriv && rpriv->rep->vport != MLX5_VPORT_UPLINK;
}

/* As IPsec and TC order is not aligned between software and hardware-offload,
* either IPsec offload or TC offload, not both, is allowed for a specific interface.
*/
static bool is_tc_ipsec_order_check_needed(struct net_device *filter, struct mlx5e_priv *priv)
{
if (!IS_ENABLED(CONFIG_MLX5_EN_IPSEC))
return false;

if (filter != priv->netdev)
return false;

if (mlx5e_eswitch_vf_rep(priv->netdev))
return false;

return true;
}

static int mlx5e_tc_block_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;

if (!is_tc_ipsec_order_check_needed(filter, priv))
return 0;

if (mdev->num_block_tc)
return -EBUSY;

mdev->num_block_ipsec++;

return 0;
}

static void mlx5e_tc_unblock_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
{
if (!is_tc_ipsec_order_check_needed(filter, priv))
return;

priv->mdev->num_block_ipsec--;
}

int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
struct flow_cls_offload *f, unsigned long flags)
{
Expand All @@ -4618,6 +4658,10 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
if (!mlx5_esw_hold(priv->mdev))
return -EBUSY;

err = mlx5e_tc_block_ipsec_offload(dev, priv);
if (err)
goto esw_release;

mlx5_esw_get(priv->mdev);

rcu_read_lock();
Expand Down Expand Up @@ -4663,7 +4707,9 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
err_free:
mlx5e_flow_put(priv, flow);
out:
mlx5e_tc_unblock_ipsec_offload(dev, priv);
mlx5_esw_put(priv->mdev);
esw_release:
mlx5_esw_release(priv->mdev);
return err;
}
Expand Down Expand Up @@ -4704,6 +4750,7 @@ int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv,
trace_mlx5e_delete_flower(f);
mlx5e_flow_put(priv, flow);

mlx5e_tc_unblock_ipsec_offload(dev, priv);
mlx5_esw_put(priv->mdev);
return 0;

Expand Down
2 changes: 2 additions & 0 deletions include/linux/mlx5/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,8 @@ struct mlx5_core_dev {
u32 vsc_addr;
struct mlx5_hv_vhca *hv_vhca;
struct mlx5_thermal *thermal;
u64 num_block_tc;
u64 num_block_ipsec;
};

struct mlx5_db {
Expand Down

0 comments on commit c8e350e

Please sign in to comment.