Skip to content

Commit 366e462

Browse files
Jianbo Liukuba-moo
authored andcommitted
net/mlx5e: Make IPsec offload work together with eswitch and TC
The eswitch mode is not allowed to change if there are any IPsec rules. Besides, by using mlx5_esw_try_lock() to get eswitch mode lock, IPsec rules are not allowed to be offloaded if there are any TC rules. Signed-off-by: Jianbo Liu <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/e442b512b21a931fbdfb87d57ae428c37badd58a.1690802064.git.leon@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 1632649 commit 366e462

File tree

3 files changed

+128
-15
lines changed

3 files changed

+128
-15
lines changed

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

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,6 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
254254
mlx5_del_flow_rules(rx->sa.rule);
255255
mlx5_destroy_flow_group(rx->sa.group);
256256
mlx5_destroy_flow_table(rx->ft.sa);
257-
if (rx->allow_tunnel_mode)
258-
mlx5_eswitch_unblock_encap(mdev);
259257
if (rx == ipsec->rx_esw) {
260258
mlx5_esw_ipsec_rx_status_destroy(ipsec, rx);
261259
} else {
@@ -359,8 +357,6 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
359357
goto err_add;
360358

361359
/* Create FT */
362-
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
363-
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
364360
if (rx->allow_tunnel_mode)
365361
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
366362
ft = ipsec_ft_create(attr.ns, attr.sa_level, attr.prio, 2, flags);
@@ -415,8 +411,6 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
415411
err_fs:
416412
mlx5_destroy_flow_table(rx->ft.sa);
417413
err_fs_ft:
418-
if (rx->allow_tunnel_mode)
419-
mlx5_eswitch_unblock_encap(mdev);
420414
mlx5_del_flow_rules(rx->status.rule);
421415
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
422416
err_add:
@@ -434,13 +428,26 @@ static int rx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
434428
if (rx->ft.refcnt)
435429
goto skip;
436430

431+
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
432+
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
433+
434+
err = mlx5_eswitch_block_mode_trylock(mdev);
435+
if (err)
436+
goto err_out;
437+
437438
err = rx_create(mdev, ipsec, rx, family);
439+
mlx5_eswitch_block_mode_unlock(mdev, err);
438440
if (err)
439-
return err;
441+
goto err_out;
440442

441443
skip:
442444
rx->ft.refcnt++;
443445
return 0;
446+
447+
err_out:
448+
if (rx->allow_tunnel_mode)
449+
mlx5_eswitch_unblock_encap(mdev);
450+
return err;
444451
}
445452

446453
static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
@@ -449,7 +456,12 @@ static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
449456
if (--rx->ft.refcnt)
450457
return;
451458

459+
mlx5_eswitch_unblock_mode_lock(ipsec->mdev);
452460
rx_destroy(ipsec->mdev, ipsec, rx, family);
461+
mlx5_eswitch_unblock_mode_unlock(ipsec->mdev);
462+
463+
if (rx->allow_tunnel_mode)
464+
mlx5_eswitch_unblock_encap(ipsec->mdev);
453465
}
454466

455467
static struct mlx5e_ipsec_rx *rx_ft_get(struct mlx5_core_dev *mdev,
@@ -569,8 +581,6 @@ static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
569581
mlx5_destroy_flow_group(tx->sa.group);
570582
}
571583
mlx5_destroy_flow_table(tx->ft.sa);
572-
if (tx->allow_tunnel_mode)
573-
mlx5_eswitch_unblock_encap(ipsec->mdev);
574584
mlx5_del_flow_rules(tx->status.rule);
575585
mlx5_destroy_flow_table(tx->ft.status);
576586
}
@@ -611,8 +621,6 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
611621
if (err)
612622
goto err_status_rule;
613623

614-
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
615-
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
616624
if (tx->allow_tunnel_mode)
617625
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
618626
ft = ipsec_ft_create(tx->ns, attr.sa_level, attr.prio, 4, flags);
@@ -679,8 +687,6 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
679687
err_sa_miss:
680688
mlx5_destroy_flow_table(tx->ft.sa);
681689
err_sa_ft:
682-
if (tx->allow_tunnel_mode)
683-
mlx5_eswitch_unblock_encap(mdev);
684690
mlx5_del_flow_rules(tx->status.rule);
685691
err_status_rule:
686692
mlx5_destroy_flow_table(tx->ft.status);
@@ -714,27 +720,50 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
714720
if (tx->ft.refcnt)
715721
goto skip;
716722

717-
err = tx_create(ipsec, tx, ipsec->roce);
723+
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
724+
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
725+
726+
err = mlx5_eswitch_block_mode_trylock(mdev);
718727
if (err)
719-
return err;
728+
goto err_out;
729+
730+
err = tx_create(ipsec, tx, ipsec->roce);
731+
if (err) {
732+
mlx5_eswitch_block_mode_unlock(mdev, err);
733+
goto err_out;
734+
}
720735

721736
if (tx == ipsec->tx_esw)
722737
ipsec_esw_tx_ft_policy_set(mdev, tx->ft.pol);
723738

739+
mlx5_eswitch_block_mode_unlock(mdev, err);
740+
724741
skip:
725742
tx->ft.refcnt++;
726743
return 0;
744+
745+
err_out:
746+
if (tx->allow_tunnel_mode)
747+
mlx5_eswitch_unblock_encap(mdev);
748+
return err;
727749
}
728750

729751
static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)
730752
{
731753
if (--tx->ft.refcnt)
732754
return;
733755

756+
mlx5_eswitch_unblock_mode_lock(ipsec->mdev);
757+
734758
if (tx == ipsec->tx_esw)
735759
ipsec_esw_tx_ft_policy_set(ipsec->mdev, NULL);
736760

737761
tx_destroy(ipsec, tx, ipsec->roce);
762+
763+
mlx5_eswitch_unblock_mode_unlock(ipsec->mdev);
764+
765+
if (tx->allow_tunnel_mode)
766+
mlx5_eswitch_unblock_encap(ipsec->mdev);
738767
}
739768

740769
static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ struct mlx5_esw_offload {
270270
u8 inline_mode;
271271
atomic64_t num_flows;
272272
u64 num_block_encap;
273+
u64 num_block_mode;
273274
enum devlink_eswitch_encap_mode encap;
274275
struct ida vport_metadata_ida;
275276
unsigned int host_number; /* ECPF supports one external host */
@@ -784,6 +785,11 @@ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
784785
bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev);
785786
void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev);
786787

788+
int mlx5_eswitch_block_mode_trylock(struct mlx5_core_dev *dev);
789+
void mlx5_eswitch_block_mode_unlock(struct mlx5_core_dev *dev, int err);
790+
void mlx5_eswitch_unblock_mode_lock(struct mlx5_core_dev *dev);
791+
void mlx5_eswitch_unblock_mode_unlock(struct mlx5_core_dev *dev);
792+
787793
static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
788794
{
789795
if (mlx5_esw_allowed(esw))
@@ -863,6 +869,14 @@ static inline bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev)
863869
static inline void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev)
864870
{
865871
}
872+
873+
static inline int mlx5_eswitch_block_mode_trylock(struct mlx5_core_dev *dev) { return 0; }
874+
875+
static inline void mlx5_eswitch_block_mode_unlock(struct mlx5_core_dev *dev, int err) {}
876+
877+
static inline void mlx5_eswitch_unblock_mode_lock(struct mlx5_core_dev *dev) {}
878+
879+
static inline void mlx5_eswitch_unblock_mode_unlock(struct mlx5_core_dev *dev) {}
866880
#endif /* CONFIG_MLX5_ESWITCH */
867881

868882
#endif /* __MLX5_ESWITCH_H__ */

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,69 @@ static bool esw_offloads_devlink_ns_eq_netdev_ns(struct devlink *devlink)
35183518
return net_eq(devl_net, netdev_net);
35193519
}
35203520

3521+
int mlx5_eswitch_block_mode_trylock(struct mlx5_core_dev *dev)
3522+
{
3523+
struct devlink *devlink = priv_to_devlink(dev);
3524+
struct mlx5_eswitch *esw;
3525+
int err;
3526+
3527+
devl_lock(devlink);
3528+
esw = mlx5_devlink_eswitch_get(devlink);
3529+
if (IS_ERR(esw)) {
3530+
/* Failure means no eswitch => not possible to change eswitch mode */
3531+
devl_unlock(devlink);
3532+
return 0;
3533+
}
3534+
3535+
err = mlx5_esw_try_lock(esw);
3536+
if (err < 0) {
3537+
devl_unlock(devlink);
3538+
return err;
3539+
}
3540+
3541+
return 0;
3542+
}
3543+
3544+
void mlx5_eswitch_block_mode_unlock(struct mlx5_core_dev *dev, int err)
3545+
{
3546+
struct devlink *devlink = priv_to_devlink(dev);
3547+
struct mlx5_eswitch *esw;
3548+
3549+
esw = mlx5_devlink_eswitch_get(devlink);
3550+
if (IS_ERR(esw))
3551+
return;
3552+
3553+
if (!err)
3554+
esw->offloads.num_block_mode++;
3555+
mlx5_esw_unlock(esw);
3556+
devl_unlock(devlink);
3557+
}
3558+
3559+
void mlx5_eswitch_unblock_mode_lock(struct mlx5_core_dev *dev)
3560+
{
3561+
struct devlink *devlink = priv_to_devlink(dev);
3562+
struct mlx5_eswitch *esw;
3563+
3564+
esw = mlx5_devlink_eswitch_get(devlink);
3565+
if (IS_ERR(esw))
3566+
return;
3567+
3568+
down_write(&esw->mode_lock);
3569+
}
3570+
3571+
void mlx5_eswitch_unblock_mode_unlock(struct mlx5_core_dev *dev)
3572+
{
3573+
struct devlink *devlink = priv_to_devlink(dev);
3574+
struct mlx5_eswitch *esw;
3575+
3576+
esw = mlx5_devlink_eswitch_get(devlink);
3577+
if (IS_ERR(esw))
3578+
return;
3579+
3580+
esw->offloads.num_block_mode--;
3581+
up_write(&esw->mode_lock);
3582+
}
3583+
35213584
int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
35223585
struct netlink_ext_ack *extack)
35233586
{
@@ -3551,6 +3614,13 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
35513614
if (cur_mlx5_mode == mlx5_mode)
35523615
goto unlock;
35533616

3617+
if (esw->offloads.num_block_mode) {
3618+
NL_SET_ERR_MSG_MOD(extack,
3619+
"Can't change eswitch mode when IPsec SA and/or policies are configured");
3620+
err = -EOPNOTSUPP;
3621+
goto unlock;
3622+
}
3623+
35543624
mlx5_eswitch_disable_locked(esw);
35553625
if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) {
35563626
if (mlx5_devlink_trap_get_num_active(esw->dev)) {

0 commit comments

Comments
 (0)