diff mbox series

[v2,2/6] common/cnxk: support lifetime configuration

Message ID 1631032372-275-3-git-send-email-anoobj@marvell.com (mailing list archive)
State Changes Requested
Delegated to: akhil goyal
Headers show
Series Add SA lifetime in security | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Anoob Joseph Sept. 7, 2021, 4:32 p.m. UTC
Add support for SA lifetime configuration. Expiry can
be either in units of octets or packets.

Also, updated cryptodev dequeue path to update crypto op result to
indicate soft expiry.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
---
 drivers/common/cnxk/cnxk_security.c       | 70 +++++++++++++++++++++++++++++++
 drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 48 ++++++++++++++++-----
 drivers/crypto/cnxk/cn9k_ipsec.c          |  6 ++-
 3 files changed, 112 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index 4f7fd1b..215d9fd 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -161,6 +161,26 @@  ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 		return -EINVAL;
 	}
 
+	if (ipsec_xfrm->life.packets_soft_limit != 0 ||
+	    ipsec_xfrm->life.packets_hard_limit != 0) {
+		if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
+		    ipsec_xfrm->life.bytes_hard_limit != 0) {
+			plt_err("Expiry tracking with both packets & bytes is not supported");
+			return -EINVAL;
+		}
+		w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
+	}
+
+	if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
+	    ipsec_xfrm->life.bytes_hard_limit != 0) {
+		if (ipsec_xfrm->life.packets_soft_limit != 0 ||
+		    ipsec_xfrm->life.packets_hard_limit != 0) {
+			plt_err("Expiry tracking with both packets & bytes is not supported");
+			return -EINVAL;
+		}
+		w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
+	}
+
 	return 0;
 }
 
@@ -236,6 +256,31 @@  cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
 		 ROC_CTX_UNIT_128B) -
 		1;
 
+	/**
+	 * CPT MC triggers expiry when counter value changes from 2 to 1. To
+	 * mitigate this behaviour add 1 to the life counter values provided.
+	 */
+
+	if (ipsec_xfrm->life.bytes_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.bytes_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
 	/* There are two words of CPT_CTX_HW_S for ucode to skip */
 	sa->w0.s.ctx_hdr_size = 1;
 	sa->w0.s.aop_valid = 1;
@@ -360,6 +405,31 @@  cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
 	/* IPID gen */
 	sa->w2.s.ipid_gen = 1;
 
+	/**
+	 * CPT MC triggers expiry when counter value changes from 2 to 1. To
+	 * mitigate this behaviour add 1 to the life counter values provided.
+	 */
+
+	if (ipsec_xfrm->life.bytes_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_soft_limit) {
+		sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
+		sa->w0.s.soft_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.bytes_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
+	if (ipsec_xfrm->life.packets_hard_limit) {
+		sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
+		sa->w0.s.hard_life_dec = 1;
+	}
+
 	/* There are two words of CPT_CTX_HW_S for ucode to skip */
 	sa->w0.s.ctx_hdr_size = 1;
 	sa->w0.s.aop_valid = 1;
diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index cccca77..e6ed733 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -348,12 +348,44 @@  cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 			       struct cpt_inflight_req *infl_req)
 {
 	struct cpt_cn10k_res_s *res = (struct cpt_cn10k_res_s *)&infl_req->res;
+	const uint8_t uc_compcode = res->uc_compcode;
+	const uint8_t compcode = res->compcode;
 	unsigned int sz;
 
-	if (likely(res->compcode == CPT_COMP_GOOD ||
-		   res->compcode == CPT_COMP_WARN)) {
-		if (unlikely(res->uc_compcode)) {
-			if (res->uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+	if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
+	    cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
+		if (likely(compcode == CPT_COMP_WARN)) {
+			if (unlikely(uc_compcode != ROC_IE_OT_UCC_SUCCESS)) {
+				/* Success with additional info */
+				switch (uc_compcode) {
+				case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_FIRST:
+					cop->aux_flags =
+						RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY;
+					break;
+				default:
+					break;
+				}
+			}
+			cn10k_cpt_sec_post_process(cop, res);
+		} else {
+			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+			plt_dp_info("HW completion code 0x%x", res->compcode);
+			if (compcode == CPT_COMP_GOOD) {
+				plt_dp_info(
+					"Request failed with microcode error");
+				plt_dp_info("MC completion code 0x%x",
+					    uc_compcode);
+			}
+		}
+
+		return;
+	}
+
+	if (likely(compcode == CPT_COMP_GOOD || compcode == CPT_COMP_WARN)) {
+		if (unlikely(uc_compcode)) {
+			if (uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
 				cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
 			else
 				cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
@@ -364,13 +396,7 @@  cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 			goto temp_sess_free;
 		}
 
-		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
 		if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
-			if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
-				cn10k_cpt_sec_post_process(cop, res);
-				return;
-			}
-
 			/* Verify authentication data if required */
 			if (unlikely(infl_req->op_flags &
 				     CPT_OP_FLAGS_AUTH_VERIFY)) {
@@ -392,7 +418,7 @@  cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
 		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
 		plt_dp_info("HW completion code 0x%x", res->compcode);
 
-		switch (res->compcode) {
+		switch (compcode) {
 		case CPT_COMP_INSTERR:
 			plt_dp_err("Request failed with instruction error");
 			break;
diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c
index 0b63cc4..63ae025 100644
--- a/drivers/crypto/cnxk/cn9k_ipsec.c
+++ b/drivers/crypto/cnxk/cn9k_ipsec.c
@@ -485,7 +485,11 @@  cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
 static inline int
 cn9k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec)
 {
-	RTE_SET_USED(ipsec);
+	if (ipsec->life.bytes_hard_limit != 0 ||
+	    ipsec->life.bytes_soft_limit != 0 ||
+	    ipsec->life.packets_hard_limit != 0 ||
+	    ipsec->life.packets_soft_limit != 0)
+		return -ENOTSUP;
 
 	return 0;
 }