| From 9517cd0f9417a2e4dc9bdfaf6fdd8d7ab933ef4d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 26 Oct 2022 14:51:39 +0100 |
| Subject: net/mlx5e: Do not increment ESN when updating IPsec ESN state |
| |
| From: Hyong Youb Kim <hyonkim@cisco.com> |
| |
| [ Upstream commit 888be6b279b7257b5f6e4c9527675bff0a335596 ] |
| |
| An offloaded SA stops receiving after about 2^32 + replay_window |
| packets. For example, when SA reaches <seq-hi 0x1, seq 0x2c>, all |
| subsequent packets get dropped with SA-icv-failure (integrity_failed). |
| |
| To reproduce the bug: |
| - ConnectX-6 Dx with crypto enabled (FW 22.30.1004) |
| - ipsec.conf: |
| nic-offload = yes |
| replay-window = 32 |
| esn = yes |
| salifetime=24h |
| - Run netperf for a long time to send more than 2^32 packets |
| netperf -H <device-under-test> -t TCP_STREAM -l 20000 |
| |
| When 2^32 + replay_window packets are received, the replay window |
| moves from the 2nd half of subspace (overlap=1) to the 1st half |
| (overlap=0). The driver then updates the 'esn' value in NIC |
| (i.e. seq_hi) as follows. |
| |
| seq_hi = xfrm_replay_seqhi(seq_bottom) |
| new esn in NIC = seq_hi + 1 |
| |
| The +1 increment is wrong, as seq_hi already contains the correct |
| seq_hi. For example, when seq_hi=1, the driver actually tells NIC to |
| use seq_hi=2 (esn). This incorrect esn value causes all subsequent |
| packets to fail integrity checks (SA-icv-failure). So, do not |
| increment. |
| |
| Fixes: cb01008390bb ("net/mlx5: IPSec, Add support for ESN") |
| Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com> |
| Acked-by: Leon Romanovsky <leonro@nvidia.com> |
| Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> |
| Link: https://lore.kernel.org/r/20221026135153.154807-2-saeed@kernel.org |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 --- |
| 1 file changed, 3 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c |
| index 7cab08a2f715..05882d1a4407 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c |
| @@ -113,7 +113,6 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry) |
| struct xfrm_replay_state_esn *replay_esn; |
| u32 seq_bottom = 0; |
| u8 overlap; |
| - u32 *esn; |
| |
| if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) { |
| sa_entry->esn_state.trigger = 0; |
| @@ -128,11 +127,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry) |
| |
| sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x, |
| htonl(seq_bottom)); |
| - esn = &sa_entry->esn_state.esn; |
| |
| sa_entry->esn_state.trigger = 1; |
| if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) { |
| - ++(*esn); |
| sa_entry->esn_state.overlap = 0; |
| return true; |
| } else if (unlikely(!overlap && |
| -- |
| 2.35.1 |
| |