net/mlx5e: Set IPsec replay sequence numbers
"ip xfrm state ..." command allows users to configure replay sequence numbers with replay-seq* arguments for RX and replay-oseq* for TX. Add the needed driver logic to support setting them. Link: https://lore.kernel.org/r/a9b17827eff2b29a4951225efa684a6cd38f74fe.1680162300.git.leonro@nvidia.com Reviewed-by: Raed Salem <raeds@nvidia.com> Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
This commit is contained in:
parent
f4979e2667
commit
7db21ef456
@ -52,18 +52,46 @@ static struct mlx5e_ipsec_pol_entry *to_ipsec_pol_entry(struct xfrm_policy *x)
|
||||
|
||||
static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
{
|
||||
struct xfrm_replay_state_esn *replay_esn;
|
||||
struct xfrm_state *x = sa_entry->x;
|
||||
u32 seq_bottom = 0;
|
||||
u32 esn, esn_msb;
|
||||
u8 overlap;
|
||||
|
||||
replay_esn = sa_entry->x->replay_esn;
|
||||
if (replay_esn->seq >= replay_esn->replay_window)
|
||||
seq_bottom = replay_esn->seq - replay_esn->replay_window + 1;
|
||||
switch (x->xso.type) {
|
||||
case XFRM_DEV_OFFLOAD_PACKET:
|
||||
switch (x->xso.dir) {
|
||||
case XFRM_DEV_OFFLOAD_IN:
|
||||
esn = x->replay_esn->seq;
|
||||
esn_msb = x->replay_esn->seq_hi;
|
||||
break;
|
||||
case XFRM_DEV_OFFLOAD_OUT:
|
||||
esn = x->replay_esn->oseq;
|
||||
esn_msb = x->replay_esn->oseq_hi;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(true);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case XFRM_DEV_OFFLOAD_CRYPTO:
|
||||
/* Already parsed by XFRM core */
|
||||
esn = x->replay_esn->seq;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
overlap = sa_entry->esn_state.overlap;
|
||||
|
||||
sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
|
||||
htonl(seq_bottom));
|
||||
if (esn >= x->replay_esn->replay_window)
|
||||
seq_bottom = esn - x->replay_esn->replay_window + 1;
|
||||
|
||||
if (x->xso.type == XFRM_DEV_OFFLOAD_CRYPTO)
|
||||
esn_msb = xfrm_replay_seqhi(x, htonl(seq_bottom));
|
||||
|
||||
sa_entry->esn_state.esn = esn;
|
||||
sa_entry->esn_state.esn_msb = esn_msb;
|
||||
|
||||
if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
|
||||
sa_entry->esn_state.overlap = 0;
|
||||
@ -224,10 +252,10 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||
|
||||
/* esn */
|
||||
if (x->props.flags & XFRM_STATE_ESN) {
|
||||
attrs->esn_trigger = true;
|
||||
attrs->esn = sa_entry->esn_state.esn;
|
||||
attrs->esn_overlap = sa_entry->esn_state.overlap;
|
||||
attrs->replay_window = x->replay_esn->replay_window;
|
||||
attrs->replay_esn.trigger = true;
|
||||
attrs->replay_esn.esn = sa_entry->esn_state.esn;
|
||||
attrs->replay_esn.esn_msb = sa_entry->esn_state.esn_msb;
|
||||
attrs->replay_esn.overlap = sa_entry->esn_state.overlap;
|
||||
}
|
||||
|
||||
attrs->dir = x->xso.dir;
|
||||
|
@ -67,8 +67,15 @@ struct mlx5_ipsec_lft {
|
||||
u64 numb_rounds_soft;
|
||||
};
|
||||
|
||||
struct mlx5_replay_esn {
|
||||
u32 replay_window;
|
||||
u32 esn;
|
||||
u32 esn_msb;
|
||||
u8 overlap : 1;
|
||||
u8 trigger : 1;
|
||||
};
|
||||
|
||||
struct mlx5_accel_esp_xfrm_attrs {
|
||||
u32 esn;
|
||||
u32 spi;
|
||||
u32 flags;
|
||||
struct aes_gcm_keymat aes_gcm;
|
||||
@ -85,11 +92,9 @@ struct mlx5_accel_esp_xfrm_attrs {
|
||||
|
||||
struct upspec upspec;
|
||||
u8 dir : 2;
|
||||
u8 esn_overlap : 1;
|
||||
u8 esn_trigger : 1;
|
||||
u8 type : 2;
|
||||
u8 family;
|
||||
u32 replay_window;
|
||||
struct mlx5_replay_esn replay_esn;
|
||||
u32 authsize;
|
||||
u32 reqid;
|
||||
struct mlx5_ipsec_lft lft;
|
||||
@ -160,6 +165,7 @@ struct mlx5e_ipsec {
|
||||
|
||||
struct mlx5e_ipsec_esn_state {
|
||||
u32 esn;
|
||||
u32 esn_msb;
|
||||
u8 overlap: 1;
|
||||
};
|
||||
|
||||
|
@ -76,15 +76,17 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
||||
void *aso_ctx;
|
||||
|
||||
aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
|
||||
if (attrs->esn_trigger) {
|
||||
if (attrs->replay_esn.trigger) {
|
||||
MLX5_SET(ipsec_aso, aso_ctx, esn_event_arm, 1);
|
||||
|
||||
if (attrs->dir == XFRM_DEV_OFFLOAD_IN) {
|
||||
MLX5_SET(ipsec_aso, aso_ctx, window_sz,
|
||||
attrs->replay_window / 64);
|
||||
attrs->replay_esn.replay_window / 64);
|
||||
MLX5_SET(ipsec_aso, aso_ctx, mode,
|
||||
MLX5_IPSEC_ASO_REPLAY_PROTECTION);
|
||||
}
|
||||
}
|
||||
MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
|
||||
attrs->replay_esn.esn);
|
||||
}
|
||||
|
||||
/* ASO context */
|
||||
@ -136,10 +138,10 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||
salt_iv_p = MLX5_ADDR_OF(ipsec_obj, obj, implicit_iv);
|
||||
memcpy(salt_iv_p, &aes_gcm->seq_iv, sizeof(aes_gcm->seq_iv));
|
||||
/* esn */
|
||||
if (attrs->esn_trigger) {
|
||||
if (attrs->replay_esn.trigger) {
|
||||
MLX5_SET(ipsec_obj, obj, esn_en, 1);
|
||||
MLX5_SET(ipsec_obj, obj, esn_msb, attrs->esn);
|
||||
MLX5_SET(ipsec_obj, obj, esn_overlap, attrs->esn_overlap);
|
||||
MLX5_SET(ipsec_obj, obj, esn_msb, attrs->replay_esn.esn_msb);
|
||||
MLX5_SET(ipsec_obj, obj, esn_overlap, attrs->replay_esn.overlap);
|
||||
}
|
||||
|
||||
MLX5_SET(ipsec_obj, obj, dekn, sa_entry->enc_key_id);
|
||||
@ -252,8 +254,8 @@ static int mlx5_modify_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||
MLX5_SET64(ipsec_obj, obj, modify_field_select,
|
||||
MLX5_MODIFY_IPSEC_BITMASK_ESN_OVERLAP |
|
||||
MLX5_MODIFY_IPSEC_BITMASK_ESN_MSB);
|
||||
MLX5_SET(ipsec_obj, obj, esn_msb, attrs->esn);
|
||||
MLX5_SET(ipsec_obj, obj, esn_overlap, attrs->esn_overlap);
|
||||
MLX5_SET(ipsec_obj, obj, esn_msb, attrs->replay_esn.esn_msb);
|
||||
MLX5_SET(ipsec_obj, obj, esn_overlap, attrs->replay_esn.overlap);
|
||||
|
||||
/* general object fields set */
|
||||
MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
|
||||
@ -290,7 +292,7 @@ static void mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||
struct mlx5_wqe_aso_ctrl_seg data = {};
|
||||
|
||||
if (mode_param < MLX5E_IPSEC_ESN_SCOPE_MID) {
|
||||
sa_entry->esn_state.esn++;
|
||||
sa_entry->esn_state.esn_msb++;
|
||||
sa_entry->esn_state.overlap = 0;
|
||||
} else {
|
||||
sa_entry->esn_state.overlap = 1;
|
||||
@ -434,7 +436,7 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
if (attrs->esn_trigger &&
|
||||
if (attrs->replay_esn.trigger &&
|
||||
!MLX5_GET(ipsec_aso, aso->ctx, esn_event_arm)) {
|
||||
u32 mode_param = MLX5_GET(ipsec_aso, aso->ctx, mode_parameter);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user