[v8,08/10] ipsec: add support for initial SQN value

Message ID 20211011112945.2876-9-radu.nicolau@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series new features for ipsec and security libraries |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Radu Nicolau Oct. 11, 2021, 11:29 a.m. UTC
  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

Ananyev, Konstantin Oct. 12, 2021, 3:35 p.m. UTC | #1
> 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
  

Patch

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;
+	}
+
 	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;
 }