[v8,08/10] ipsec: add support for initial SQN value
Checks
Commit Message
Update IPsec library to support initial SQN value.
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
---
doc/guides/rel_notes/release_21_11.rst | 1 +
lib/ipsec/sa.c | 25 ++++++++++++++++++-------
2 files changed, 19 insertions(+), 7 deletions(-)
Comments
> Update IPsec library to support initial SQN value.
>
> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
> Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
> Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
> Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
> Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
> ---
> doc/guides/rel_notes/release_21_11.rst | 1 +
> lib/ipsec/sa.c | 25 ++++++++++++++++++-------
> 2 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index f0bc4438a4..0686679677 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -140,6 +140,7 @@ New Features
> * Added support for NAT-T / UDP encapsulated ESP
> * Added support TSO offload support; only supported for inline crypto mode.
> * Added support for SA telemetry.
> + * Added support for setting a non default starting ESN value.
>
>
> Removed Items
> diff --git a/lib/ipsec/sa.c b/lib/ipsec/sa.c
> index 44dcc524ee..85e06069de 100644
> --- a/lib/ipsec/sa.c
> +++ b/lib/ipsec/sa.c
> @@ -294,11 +294,11 @@ esp_inb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
> * Init ESP outbound specific things.
> */
> static void
> -esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)
> +esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen, uint64_t sqn)
> {
> uint8_t algo_type;
>
> - sa->sqn.outb = 1;
> + sa->sqn.outb = sqn > 1 ? sqn : 1;
>
> algo_type = sa->algo_type;
>
> @@ -376,7 +376,7 @@ esp_outb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
> sa->tx_offload.val = rte_mbuf_tx_offload(sa->hdr_l3_off,
> sa->hdr_len - sa->hdr_l3_off, 0, 0, 0, 0, 0);
>
> - esp_outb_init(sa, sa->hdr_len);
> + esp_outb_init(sa, sa->hdr_len, prm->ipsec_xform.esn.value);
> }
>
> /*
> @@ -502,7 +502,7 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
> case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS |
> RTE_IPSEC_SATP_NATT_ENABLE):
> case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):
> - esp_outb_init(sa, 0);
> + esp_outb_init(sa, 0, prm->ipsec_xform.esn.value);
> break;
> }
>
> @@ -513,15 +513,19 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
> * helper function, init SA replay structure.
> */
> static void
> -fill_sa_replay(struct rte_ipsec_sa *sa, uint32_t wnd_sz, uint32_t nb_bucket)
> +fill_sa_replay(struct rte_ipsec_sa *sa, uint32_t wnd_sz, uint32_t nb_bucket,
> + uint64_t sqn)
> {
> sa->replay.win_sz = wnd_sz;
> sa->replay.nb_bucket = nb_bucket;
> sa->replay.bucket_index_mask = nb_bucket - 1;
> sa->sqn.inb.rsn[0] = (struct replay_sqn *)(sa + 1);
> - if ((sa->type & RTE_IPSEC_SATP_SQN_MASK) == RTE_IPSEC_SATP_SQN_ATOM)
> + sa->sqn.inb.rsn[0]->sqn = sqn;
> + if ((sa->type & RTE_IPSEC_SATP_SQN_MASK) == RTE_IPSEC_SATP_SQN_ATOM) {
> sa->sqn.inb.rsn[1] = (struct replay_sqn *)
> ((uintptr_t)sa->sqn.inb.rsn[0] + rsn_size(nb_bucket));
> + sa->sqn.inb.rsn[1]->sqn = sqn;
> + }
> }
>
> int
> @@ -591,13 +595,20 @@ rte_ipsec_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
> sa->sqn_mask = (prm->ipsec_xform.options.esn == 0) ?
> UINT32_MAX : UINT64_MAX;
>
> + /* if we are starting from a non-zero sn value */
> + if (prm->ipsec_xform.esn.value > 0) {
> + if (prm->ipsec_xform.direction ==
> + RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
> + sa->sqn.outb = prm->ipsec_xform.esn.value;
> + }
> +
I think I already asked this question for previous version, but don't
remember what was the answer, so I'll ask again:
You do set sa->sqn.outb inside esp_outb_init().
Which will be invoked by esp_sa_init() below.
Why do you need to duplicate it here?
> rc = esp_sa_init(sa, prm, &cxf);
> if (rc != 0)
> rte_ipsec_sa_fini(sa);
>
> /* fill replay window related fields */
> if (nb != 0)
> - fill_sa_replay(sa, wsz, nb);
> + fill_sa_replay(sa, wsz, nb, prm->ipsec_xform.esn.value);
>
> return sz;
> }
> --
> 2.25.1
@@ -140,6 +140,7 @@ New Features
* Added support for NAT-T / UDP encapsulated ESP
* Added support TSO offload support; only supported for inline crypto mode.
* Added support for SA telemetry.
+ * Added support for setting a non default starting ESN value.
Removed Items
@@ -294,11 +294,11 @@ esp_inb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
* Init ESP outbound specific things.
*/
static void
-esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)
+esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen, uint64_t sqn)
{
uint8_t algo_type;
- sa->sqn.outb = 1;
+ sa->sqn.outb = sqn > 1 ? sqn : 1;
algo_type = sa->algo_type;
@@ -376,7 +376,7 @@ esp_outb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
sa->tx_offload.val = rte_mbuf_tx_offload(sa->hdr_l3_off,
sa->hdr_len - sa->hdr_l3_off, 0, 0, 0, 0, 0);
- esp_outb_init(sa, sa->hdr_len);
+ esp_outb_init(sa, sa->hdr_len, prm->ipsec_xform.esn.value);
}
/*
@@ -502,7 +502,7 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS |
RTE_IPSEC_SATP_NATT_ENABLE):
case (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):
- esp_outb_init(sa, 0);
+ esp_outb_init(sa, 0, prm->ipsec_xform.esn.value);
break;
}
@@ -513,15 +513,19 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
* helper function, init SA replay structure.
*/
static void
-fill_sa_replay(struct rte_ipsec_sa *sa, uint32_t wnd_sz, uint32_t nb_bucket)
+fill_sa_replay(struct rte_ipsec_sa *sa, uint32_t wnd_sz, uint32_t nb_bucket,
+ uint64_t sqn)
{
sa->replay.win_sz = wnd_sz;
sa->replay.nb_bucket = nb_bucket;
sa->replay.bucket_index_mask = nb_bucket - 1;
sa->sqn.inb.rsn[0] = (struct replay_sqn *)(sa + 1);
- if ((sa->type & RTE_IPSEC_SATP_SQN_MASK) == RTE_IPSEC_SATP_SQN_ATOM)
+ sa->sqn.inb.rsn[0]->sqn = sqn;
+ if ((sa->type & RTE_IPSEC_SATP_SQN_MASK) == RTE_IPSEC_SATP_SQN_ATOM) {
sa->sqn.inb.rsn[1] = (struct replay_sqn *)
((uintptr_t)sa->sqn.inb.rsn[0] + rsn_size(nb_bucket));
+ sa->sqn.inb.rsn[1]->sqn = sqn;
+ }
}
int
@@ -591,13 +595,20 @@ rte_ipsec_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
sa->sqn_mask = (prm->ipsec_xform.options.esn == 0) ?
UINT32_MAX : UINT64_MAX;
+ /* if we are starting from a non-zero sn value */
+ if (prm->ipsec_xform.esn.value > 0) {
+ if (prm->ipsec_xform.direction ==
+ RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
+ sa->sqn.outb = prm->ipsec_xform.esn.value;
+ }
+
rc = esp_sa_init(sa, prm, &cxf);
if (rc != 0)
rte_ipsec_sa_fini(sa);
/* fill replay window related fields */
if (nb != 0)
- fill_sa_replay(sa, wsz, nb);
+ fill_sa_replay(sa, wsz, nb, prm->ipsec_xform.esn.value);
return sz;
}