Skip to content

Commit 22239eb

Browse files
cjubranPaolo Abeni
authored andcommitted
net/mlx5e: Prevent tunnel reformat when tunnel mode not allowed
When configuring IPsec packet offload in tunnel mode, the driver tries to create tunnel reformat objects unconditionally. This is incorrect, because tunnel mode is only permitted under specific encapsulation settings, and that decision is already made when the flow table is created. The offending commit attempted to block this case in the state add path, but the check there happens too late and does not prevent the reformat from being configured. Fix by taking short reservations for both the eswitch mode and the encap at the start of state setup. This preserves the block ordering (mode --> encap) used later: the mode is blocked during RX/TX get, and the encap is blocked during flow-table creation. This lets us fail early if either reservation cannot be obtained, it means a mode transition is underway or a conflicting configuration already owns encap. If both succeed, the flow-table path later takes the ownership and the reservations are released on exit. Fixes: 146c196 ("net/mlx5e: Create IPsec table with tunnel support only when encap is disabled") Signed-off-by: Carolina Jubran <[email protected]> Reviewed-by: Jianbo Liu <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Signed-off-by: Tariq Toukan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 7593439 commit 22239eb

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

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

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
772772
struct netlink_ext_ack *extack)
773773
{
774774
struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
775+
bool allow_tunnel_mode = false;
775776
struct mlx5e_ipsec *ipsec;
776777
struct mlx5e_priv *priv;
777778
gfp_t gfp;
@@ -803,6 +804,20 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
803804
goto err_xfrm;
804805
}
805806

807+
if (mlx5_eswitch_block_mode(priv->mdev))
808+
goto unblock_ipsec;
809+
810+
if (x->props.mode == XFRM_MODE_TUNNEL &&
811+
x->xso.type == XFRM_DEV_OFFLOAD_PACKET) {
812+
allow_tunnel_mode = mlx5e_ipsec_fs_tunnel_allowed(sa_entry);
813+
if (!allow_tunnel_mode) {
814+
NL_SET_ERR_MSG_MOD(extack,
815+
"Packet offload tunnel mode is disabled due to encap settings");
816+
err = -EINVAL;
817+
goto unblock_mode;
818+
}
819+
}
820+
806821
/* check esn */
807822
if (x->props.flags & XFRM_STATE_ESN)
808823
mlx5e_ipsec_update_esn_state(sa_entry);
@@ -817,7 +832,7 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
817832

818833
err = mlx5_ipsec_create_work(sa_entry);
819834
if (err)
820-
goto unblock_ipsec;
835+
goto unblock_encap;
821836

822837
err = mlx5e_ipsec_create_dwork(sa_entry);
823838
if (err)
@@ -832,14 +847,6 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
832847
if (err)
833848
goto err_hw_ctx;
834849

835-
if (x->props.mode == XFRM_MODE_TUNNEL &&
836-
x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
837-
!mlx5e_ipsec_fs_tunnel_enabled(sa_entry)) {
838-
NL_SET_ERR_MSG_MOD(extack, "Packet offload tunnel mode is disabled due to encap settings");
839-
err = -EINVAL;
840-
goto err_add_rule;
841-
}
842-
843850
/* We use *_bh() variant because xfrm_timer_handler(), which runs
844851
* in softirq context, can reach our state delete logic and we need
845852
* xa_erase_bh() there.
@@ -855,8 +862,7 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
855862
queue_delayed_work(ipsec->wq, &sa_entry->dwork->dwork,
856863
MLX5_IPSEC_RESCHED);
857864

858-
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
859-
x->props.mode == XFRM_MODE_TUNNEL) {
865+
if (allow_tunnel_mode) {
860866
xa_lock_bh(&ipsec->sadb);
861867
__xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
862868
MLX5E_IPSEC_TUNNEL_SA);
@@ -865,6 +871,11 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
865871

866872
out:
867873
x->xso.offload_handle = (unsigned long)sa_entry;
874+
if (allow_tunnel_mode)
875+
mlx5_eswitch_unblock_encap(priv->mdev);
876+
877+
mlx5_eswitch_unblock_mode(priv->mdev);
878+
868879
return 0;
869880

870881
err_add_rule:
@@ -877,6 +888,11 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
877888
if (sa_entry->work)
878889
kfree(sa_entry->work->data);
879890
kfree(sa_entry->work);
891+
unblock_encap:
892+
if (allow_tunnel_mode)
893+
mlx5_eswitch_unblock_encap(priv->mdev);
894+
unblock_mode:
895+
mlx5_eswitch_unblock_mode(priv->mdev);
880896
unblock_ipsec:
881897
mlx5_eswitch_unblock_ipsec(priv->mdev);
882898
err_xfrm:

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
319319
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
320320
void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
321321
void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry);
322-
bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry);
322+
bool mlx5e_ipsec_fs_tunnel_allowed(struct mlx5e_ipsec_sa_entry *sa_entry);
323323

324324
int mlx5_ipsec_create_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
325325
void mlx5_ipsec_free_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2850,18 +2850,24 @@ void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry)
28502850
memcpy(sa_entry, &sa_entry_shadow, sizeof(*sa_entry));
28512851
}
28522852

2853-
bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry)
2853+
bool mlx5e_ipsec_fs_tunnel_allowed(struct mlx5e_ipsec_sa_entry *sa_entry)
28542854
{
2855-
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
2856-
struct mlx5e_ipsec_rx *rx;
2857-
struct mlx5e_ipsec_tx *tx;
2855+
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
2856+
struct xfrm_state *x = sa_entry->x;
2857+
bool from_fdb;
28582858

2859-
rx = ipsec_rx(sa_entry->ipsec, attrs->addrs.family, attrs->type);
2860-
tx = ipsec_tx(sa_entry->ipsec, attrs->type);
2861-
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
2862-
return tx->allow_tunnel_mode;
2859+
if (x->xso.dir == XFRM_DEV_OFFLOAD_OUT) {
2860+
struct mlx5e_ipsec_tx *tx = ipsec_tx(ipsec, x->xso.type);
2861+
2862+
from_fdb = (tx == ipsec->tx_esw);
2863+
} else {
2864+
struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, x->props.family,
2865+
x->xso.type);
2866+
2867+
from_fdb = (rx == ipsec->rx_esw);
2868+
}
28632869

2864-
return rx->allow_tunnel_mode;
2870+
return mlx5_eswitch_block_encap(ipsec->mdev, from_fdb);
28652871
}
28662872

28672873
void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,

0 commit comments

Comments
 (0)