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 <abhijits.si...@intel.com>
Signed-off-by: Daniel Martin Buckley <daniel.m.buck...@intel.com>
---
 lib/ipsec/esp_outb.c | 19 ++++++++++++-------
 lib/ipsec/sa.c       | 29 ++++++++++++++++++++++-------
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/lib/ipsec/esp_outb.c b/lib/ipsec/esp_outb.c
index 2c02c3bb12..8a6d09558f 100644
--- a/lib/ipsec/esp_outb.c
+++ b/lib/ipsec/esp_outb.c
@@ -661,7 +661,7 @@ esp_outb_sqh_process(const struct rte_ipsec_session *ss, 
struct rte_mbuf *mb[],
  */
 static inline void
 inline_outb_mbuf_prepare(const struct rte_ipsec_session *ss,
-       struct rte_mbuf *mb[], uint16_t num)
+       struct rte_mbuf *mb[], uint16_t num, uint64_t *sqn)
 {
        uint32_t i, ol_flags, bytes = 0;
 
@@ -672,7 +672,7 @@ inline_outb_mbuf_prepare(const struct rte_ipsec_session *ss,
                bytes += mb[i]->data_len;
                if (ol_flags != 0)
                        rte_security_set_pkt_metadata(ss->security.ctx,
-                               ss->security.ses, mb[i], NULL);
+                               ss->security.ses, mb[i], sqn);
        }
        ss->sa->statistics.count += num;
        ss->sa->statistics.bytes += bytes - (ss->sa->hdr_len * num);
@@ -764,7 +764,10 @@ inline_outb_tun_pkt_process(const struct rte_ipsec_session 
*ss,
        if (k != num && k != 0)
                move_bad_mbufs(mb, dr, num, num - k);
 
-       inline_outb_mbuf_prepare(ss, mb, k);
+       if (sa->sqn_mask > UINT32_MAX)
+               inline_outb_mbuf_prepare(ss, mb, k, &sqn);
+       else
+               inline_outb_mbuf_prepare(ss, mb, k, NULL);
        return k;
 }
 
@@ -799,8 +802,7 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session 
*ss,
        if (nb_sqn_alloc != nb_sqn)
                rte_errno = EOVERFLOW;
 
-       k = 0;
-       for (i = 0; i != num; i++) {
+       for (i = 0, k = 0; i != num; i++) {
 
                sqc = rte_cpu_to_be_64(sqn + i);
                gen_iv(iv, sqc);
@@ -828,7 +830,10 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session 
*ss,
        if (k != num && k != 0)
                move_bad_mbufs(mb, dr, num, num - k);
 
-       inline_outb_mbuf_prepare(ss, mb, k);
+       if (sa->sqn_mask > UINT32_MAX)
+               inline_outb_mbuf_prepare(ss, mb, k, &sqn);
+       else
+               inline_outb_mbuf_prepare(ss, mb, k, NULL);
        return k;
 }
 
@@ -840,6 +845,6 @@ uint16_t
 inline_proto_outb_pkt_process(const struct rte_ipsec_session *ss,
        struct rte_mbuf *mb[], uint16_t num)
 {
-       inline_outb_mbuf_prepare(ss, mb, num);
+       inline_outb_mbuf_prepare(ss, mb, num, NULL);
        return num;
 }
diff --git a/lib/ipsec/sa.c b/lib/ipsec/sa.c
index 5b55bbc098..242fdcd461 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;
 
        algo_type = sa->algo_type;
 
@@ -356,6 +356,8 @@ esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)
 static void
 esp_outb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
 {
+       uint64_t sqn = prm->ipsec_xform.esn.value > 0 ?
+                       prm->ipsec_xform.esn.value : 0;
        sa->proto = prm->tun.next_proto;
        sa->hdr_len = prm->tun.hdr_len;
        sa->hdr_l3_off = prm->tun.hdr_l3_off;
@@ -366,7 +368,7 @@ esp_outb_tun_init(struct rte_ipsec_sa *sa, const struct 
rte_ipsec_sa_prm *prm)
 
        memcpy(sa->hdr, prm->tun.hdr, sa->hdr_len);
 
-       esp_outb_init(sa, sa->hdr_len);
+       esp_outb_init(sa, sa->hdr_len, sqn);
 }
 
 /*
@@ -376,6 +378,8 @@ static int
 esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
        const struct crypto_xform *cxf)
 {
+       uint64_t sqn = prm->ipsec_xform.esn.value > 0 ?
+                       prm->ipsec_xform.esn.value : 0;
        static const uint64_t msk = RTE_IPSEC_SATP_DIR_MASK |
                                RTE_IPSEC_SATP_MODE_MASK |
                                RTE_IPSEC_SATP_NATT_MASK;
@@ -492,7 +496,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, sqn);
                break;
        }
 
@@ -503,15 +507,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
@@ -830,13 +838,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;
 }
-- 
2.25.1

Reply via email to