> Update IPsec library to support initial SQN value. > > Signed-off-by: Declan Doherty <declan.dohe...@intel.com> > Signed-off-by: Radu Nicolau <radu.nico...@intel.com> > Signed-off-by: Abhijit Sinha <abhijit.si...@intel.com> > Signed-off-by: Daniel Martin Buckley <daniel.m.buck...@intel.com> > Acked-by: Fan Zhang <roy.fan.zh...@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