DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
* [dpdk-dev] [PATCH v1 0/2] examples/ipsec-secgw: add fallback session
@ 2019-08-14 20:48 Marcin Smoczynski
  2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 1/2] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-08-14 20:48 UTC (permalink / raw)
  To: konstantin.ananyev; +Cc: dev, Marcin Smoczynski

Inline processing is limited to a specified subset of traffic. It is
often unable to handle more complicated situations, such as fragmented
traffic. When using inline processing such traffic is dropped.

Introduce multiple sessions per SA allowing to configure a fallback
lookaside session for packets that normally would be dropped.
A fallback session type in the SA configuration by adding 'fallback'
with 'lookaside-none' or 'lookaside-protocol' parameter to determine
type of session.

Fallback session feature is available only when using librte_ipsec.

Marcin Smoczynski (2):
  examples/ipsec-secgw: ipsec_sa structure cleanup
  examples/ipsec-secgw: add fallback session feature

 doc/guides/sample_app_ug/ipsec_secgw.rst |  17 ++-
 examples/ipsec-secgw/esp.c               |  35 ++++--
 examples/ipsec-secgw/ipsec-secgw.c       |  16 ++-
 examples/ipsec-secgw/ipsec.c             |  99 ++++++++-------
 examples/ipsec-secgw/ipsec.h             |  61 +++++++--
 examples/ipsec-secgw/ipsec_process.c     | 113 ++++++++++-------
 examples/ipsec-secgw/sa.c                | 153 +++++++++++++++++------
 7 files changed, 334 insertions(+), 160 deletions(-)

--
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v1 1/2] examples/ipsec-secgw: ipsec_sa structure cleanup
  2019-08-14 20:48 [dpdk-dev] [PATCH v1 0/2] examples/ipsec-secgw: add fallback session Marcin Smoczynski
@ 2019-08-14 20:48 ` Marcin Smoczynski
  2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 2/2] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2 siblings, 0 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-08-14 20:48 UTC (permalink / raw)
  To: konstantin.ananyev; +Cc: dev, Marcin Smoczynski

Cleanup ipsec_sa structure by removing every field that is already in
the rte_ipsec_session structure:
 * cryptodev/security session union
 * action type
 * offload flags
 * security context
References to abovementioned fields are changed to direct references
to matching fields of rte_ipsec_session structure.

Such refactoring is needed to introduce many sessions per SA feature,
e.g. fallback session for inline offload processing.

Signed-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>
---
 examples/ipsec-secgw/esp.c           | 35 +++++++----
 examples/ipsec-secgw/ipsec.c         | 91 +++++++++++++++-------------
 examples/ipsec-secgw/ipsec.h         | 27 ++++++---
 examples/ipsec-secgw/ipsec_process.c | 30 ++++-----
 examples/ipsec-secgw/sa.c            | 66 ++++++++++----------
 5 files changed, 137 insertions(+), 112 deletions(-)

diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index d6d7b1256..c1b49da1e 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -30,7 +30,8 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	int32_t payload_len, ip_hdr_len;
 
 	RTE_ASSERT(sa != NULL);
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
+	if (ipsec_get_action_type(sa) ==
+			RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
 		return 0;
 
 	RTE_ASSERT(m != NULL);
@@ -148,13 +149,16 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	uint8_t *nexthdr, *pad_len;
 	uint8_t *padding;
 	uint16_t i;
+	struct rte_ipsec_session *ips;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-			(sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+	ips = ipsec_get_session(sa);
+
+	if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+			(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
 		if (m->ol_flags & PKT_RX_SEC_OFFLOAD) {
 			if (m->ol_flags & PKT_RX_SEC_OFFLOAD_FAILED)
 				cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
@@ -169,8 +173,8 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 		return -1;
 	}
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-	    sa->ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+		ips->security.ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
 		nexthdr = &m->inner_esp_next_proto;
 	} else {
 		nexthdr = rte_pktmbuf_mtod_offset(m, uint8_t*,
@@ -225,10 +229,12 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	struct rte_crypto_sym_op *sym_cop;
 	int32_t i;
 	uint16_t pad_payload_len, pad_len, ip_hdr_len;
+	struct rte_ipsec_session *ips;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
+	ips = ipsec_get_session(sa);
 	ip_hdr_len = 0;
 
 	ip4 = rte_pktmbuf_mtod(m, struct ip *);
@@ -277,9 +283,10 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	}
 
 	/* Add trailer padding if it is not constructed by HW */
-	if (sa->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-	    (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-	     !(sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
+	if (ips->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+		(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+		 !(ips->security.ol_flags &
+			 RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
 		padding = (uint8_t *)rte_pktmbuf_append(m, pad_len +
 							sa->digest_len);
 		if (unlikely(padding == NULL)) {
@@ -344,8 +351,9 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 		}
 	}
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
-		if (sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+		if (ips->security.ol_flags &
+				RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
 			/* Set the inner esp next protocol for HW trailer */
 			m->inner_esp_next_proto = nlp;
 			m->packet_type |= RTE_PTYPE_TUNNEL_ESP;
@@ -448,11 +456,14 @@ esp_outbound_post(struct rte_mbuf *m,
 		  struct ipsec_sa *sa,
 		  struct rte_crypto_op *cop)
 {
+	enum rte_security_session_action_type type;
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
-	if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-			(sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+	type = ipsec_get_action_type(sa);
+
+	if ((type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+			(type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
 		m->ol_flags |= PKT_TX_SEC_OFFLOAD;
 	} else {
 		RTE_ASSERT(cop != NULL);
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index dc85adfe5..8c60bd84b 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -40,7 +40,8 @@ set_ipsec_conf(struct ipsec_sa *sa, struct rte_security_ipsec_xform *ipsec)
 }
 
 int
-create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
+create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips)
 {
 	struct rte_cryptodev_info cdev_info;
 	unsigned long cdev_id_qp = 0;
@@ -71,9 +72,9 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			ipsec_ctx->tbl[cdev_id_qp].id,
 			ipsec_ctx->tbl[cdev_id_qp].qp);
 
-	if (sa->type != RTE_SECURITY_ACTION_TYPE_NONE) {
+	if (ips->type != RTE_SECURITY_ACTION_TYPE_NONE) {
 		struct rte_security_session_conf sess_conf = {
-			.action_type = sa->type,
+			.action_type = ips->type,
 			.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
 			{.ipsec = {
 				.spi = sa->spi,
@@ -90,7 +91,7 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 
 		};
 
-		if (sa->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
+		if (ips->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
 			struct rte_security_ctx *ctx = (struct rte_security_ctx *)
 							rte_cryptodev_get_sec_ctx(
 							ipsec_ctx->tbl[cdev_id_qp].id);
@@ -98,9 +99,9 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			/* Set IPsec parameters in conf */
 			set_ipsec_conf(sa, &(sess_conf.ipsec));
 
-			sa->sec_session = rte_security_session_create(ctx,
+			ips->security.ses = rte_security_session_create(ctx,
 					&sess_conf, ipsec_ctx->session_priv_pool);
-			if (sa->sec_session == NULL) {
+			if (ips->security.ses == NULL) {
 				RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 				return -1;
@@ -110,10 +111,10 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 	} else {
-		sa->crypto_session = rte_cryptodev_sym_session_create(
+		ips->crypto.ses = rte_cryptodev_sym_session_create(
 				ipsec_ctx->session_pool);
 		rte_cryptodev_sym_session_init(ipsec_ctx->tbl[cdev_id_qp].id,
-				sa->crypto_session, sa->xforms,
+				ips->crypto.ses, sa->xforms,
 				ipsec_ctx->session_priv_pool);
 
 		rte_cryptodev_info_get(ipsec_ctx->tbl[cdev_id_qp].id,
@@ -126,12 +127,13 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 }
 
 int
-create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
+create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips)
 {
 	int32_t ret = 0;
 	struct rte_security_ctx *sec_ctx;
 	struct rte_security_session_conf sess_conf = {
-		.action_type = sa->type,
+		.action_type = ips->type,
 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
 		{.ipsec = {
 			.spi = sa->spi,
@@ -151,7 +153,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 	RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n",
 		sa->spi, sa->portid);
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 		struct rte_flow_error err;
 		const struct rte_security_capability *sec_cap;
 		int ret = 0;
@@ -165,9 +167,9 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->sec_session = rte_security_session_create(sec_ctx,
+		ips->security.ses = rte_security_session_create(sec_ctx,
 				&sess_conf, skt_ctx->session_pool);
-		if (sa->sec_session == NULL) {
+		if (ips->security.ses == NULL) {
 			RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 			return -1;
@@ -177,7 +179,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 
 		/* iterate until ESP tunnel*/
 		while (sec_cap->action != RTE_SECURITY_ACTION_TYPE_NONE) {
-			if (sec_cap->action == sa->type &&
+			if (sec_cap->action == ips->type &&
 			    sec_cap->protocol ==
 				RTE_SECURITY_PROTOCOL_IPSEC &&
 			    sec_cap->ipsec.mode ==
@@ -193,8 +195,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->ol_flags = sec_cap->ol_flags;
-		sa->security_ctx = sec_ctx;
+		ips->security.ol_flags = sec_cap->ol_flags;
+		ips->security.ctx = sec_ctx;
 		sa->pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
 
 		if (IS_IP6(sa->flags)) {
@@ -223,7 +225,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 		sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
 
 		sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
-		sa->action[0].conf = sa->sec_session;
+		sa->action[0].conf = ips->security.ses;
 
 		sa->action[1].type = RTE_FLOW_ACTION_TYPE_END;
 
@@ -282,8 +284,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			if (ret)
 				goto flow_create_failure;
 		} else if (sa->attr.egress &&
-			   (sa->ol_flags &
-				    RTE_SECURITY_TX_HW_TRAILER_OFFLOAD)) {
+				(ips->security.ol_flags &
+					RTE_SECURITY_TX_HW_TRAILER_OFFLOAD)) {
 			sa->action[1].type =
 					RTE_FLOW_ACTION_TYPE_PASSTHRU;
 			sa->action[2].type =
@@ -299,7 +301,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 				err.message);
 			return -1;
 		}
-	} else if (sa->type ==	RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
+	} else if (ips->type ==	RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 		const struct rte_security_capability *sec_cap;
 
 		sec_ctx = (struct rte_security_ctx *)
@@ -327,9 +329,9 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 
 		sess_conf.userdata = (void *) sa;
 
-		sa->sec_session = rte_security_session_create(sec_ctx,
+		ips->security.ses = rte_security_session_create(sec_ctx,
 					&sess_conf, skt_ctx->session_pool);
-		if (sa->sec_session == NULL) {
+		if (ips->security.ses == NULL) {
 			RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 			return -1;
@@ -345,7 +347,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 		/* iterate until ESP tunnel*/
 		while (sec_cap->action !=
 				RTE_SECURITY_ACTION_TYPE_NONE) {
-			if (sec_cap->action == sa->type &&
+			if (sec_cap->action == ips->type &&
 			    sec_cap->protocol ==
 				RTE_SECURITY_PROTOCOL_IPSEC &&
 			    sec_cap->ipsec.mode ==
@@ -361,8 +363,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->ol_flags = sec_cap->ol_flags;
-		sa->security_ctx = sec_ctx;
+		ips->security.ol_flags = sec_cap->ol_flags;
+		ips->security.ctx = sec_ctx;
 	}
 	sa->cdev_id_qp = 0;
 
@@ -409,6 +411,7 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 	struct ipsec_mbuf_metadata *priv;
 	struct rte_crypto_sym_op *sym_cop;
 	struct ipsec_sa *sa;
+	struct rte_ipsec_session *ips;
 
 	for (i = 0; i < nb_pkts; i++) {
 		if (unlikely(sas[i] == NULL)) {
@@ -422,16 +425,17 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		priv = get_priv(pkts[i]);
 		sa = sas[i];
 		priv->sa = sa;
+		ips = ipsec_get_session(sa);
 
-		switch (sa->type) {
+		switch (ips->type) {
 		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
 			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
 			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 
 			rte_prefetch0(&priv->sym_cop);
 
-			if ((unlikely(sa->sec_session == NULL)) &&
-				create_lookaside_session(ipsec_ctx, sa)) {
+			if ((unlikely(ips->security.ses == NULL)) &&
+				create_lookaside_session(ipsec_ctx, sa, ips)) {
 				rte_pktmbuf_free(pkts[i]);
 				continue;
 			}
@@ -440,7 +444,7 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			sym_cop->m_src = pkts[i];
 
 			rte_security_attach_session(&priv->cop,
-					sa->sec_session);
+				ips->security.ses);
 			break;
 		case RTE_SECURITY_ACTION_TYPE_NONE:
 
@@ -449,14 +453,14 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 
 			rte_prefetch0(&priv->sym_cop);
 
-			if ((unlikely(sa->crypto_session == NULL)) &&
-				create_lookaside_session(ipsec_ctx, sa)) {
+			if ((unlikely(ips->crypto.ses == NULL)) &&
+				create_lookaside_session(ipsec_ctx, sa, ips)) {
 				rte_pktmbuf_free(pkts[i]);
 				continue;
 			}
 
 			rte_crypto_op_attach_sym_session(&priv->cop,
-					sa->crypto_session);
+					ips->crypto.ses);
 
 			ret = xform_func(pkts[i], sa, &priv->cop);
 			if (unlikely(ret)) {
@@ -465,21 +469,22 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			}
 			break;
 		case RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL:
-			RTE_ASSERT(sa->sec_session != NULL);
+			RTE_ASSERT(ips->security.ses != NULL);
 			ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i];
-			if (sa->ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
+			if (ips->security.ol_flags &
+				RTE_SECURITY_TX_OLOAD_NEED_MDATA)
 				rte_security_set_pkt_metadata(
-						sa->security_ctx,
-						sa->sec_session, pkts[i], NULL);
+					ips->security.ctx, ips->security.ses,
+					pkts[i], NULL);
 			continue;
 		case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO:
-			RTE_ASSERT(sa->sec_session != NULL);
+			RTE_ASSERT(ips->security.ses != NULL);
 			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
 			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 
 			rte_prefetch0(&priv->sym_cop);
 			rte_security_attach_session(&priv->cop,
-					sa->sec_session);
+					ips->security.ses);
 
 			ret = xform_func(pkts[i], sa, &priv->cop);
 			if (unlikely(ret)) {
@@ -488,10 +493,11 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			}
 
 			ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i];
-			if (sa->ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
+			if (ips->security.ol_flags &
+				RTE_SECURITY_TX_OLOAD_NEED_MDATA)
 				rte_security_set_pkt_metadata(
-						sa->security_ctx,
-						sa->sec_session, pkts[i], NULL);
+					ips->security.ctx, ips->security.ses,
+					pkts[i], NULL);
 			continue;
 		}
 
@@ -560,7 +566,8 @@ ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 
 			RTE_ASSERT(sa != NULL);
 
-			if (sa->type == RTE_SECURITY_ACTION_TYPE_NONE) {
+			if (ipsec_get_action_type(sa) ==
+				RTE_SECURITY_ACTION_TYPE_NONE) {
 				ret = xform_func(pkt, sa, cops[j]);
 				if (unlikely(ret)) {
 					rte_pktmbuf_free(pkt);
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 1efa6e488..a4ad81b0e 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -87,10 +87,6 @@ struct ipsec_sa {
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
-	union {
-		struct rte_cryptodev_sym_session *crypto_session;
-		struct rte_security_session *sec_session;
-	};
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
 	enum rte_crypto_aead_algorithm aead_algo;
@@ -114,11 +110,8 @@ struct ipsec_sa {
 		struct rte_crypto_sym_xform *xforms;
 		struct rte_security_ipsec_xform *sec_xform;
 	};
-	enum rte_security_session_action_type type;
 	enum rte_security_ipsec_sa_direction direction;
 	uint16_t portid;
-	struct rte_security_ctx *security_ctx;
-	uint32_t ol_flags;
 
 #define MAX_RTE_FLOW_PATTERN (4)
 #define MAX_RTE_FLOW_ACTIONS (3)
@@ -284,6 +277,20 @@ get_sym_cop(struct rte_crypto_op *cop)
 	return (cop + 1);
 }
 
+static inline struct rte_ipsec_session *
+ipsec_get_session(struct ipsec_sa *sa)
+{
+	return &sa->ips;
+}
+
+static inline enum rte_security_session_action_type
+ipsec_get_action_type(struct ipsec_sa *sa)
+{
+	struct rte_ipsec_session *ips;
+	ips = ipsec_get_session(sa);
+	return ips->type;
+}
+
 int
 inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx);
 
@@ -338,9 +345,11 @@ void
 enqueue_cop_burst(struct cdev_qp *cqp);
 
 int
-create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa);
+create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips);
 
 int
-create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa);
+create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips);
 
 #endif /* __IPSEC_H__ */
diff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c
index 868f1a28d..239d81ef6 100644
--- a/examples/ipsec-secgw/ipsec_process.c
+++ b/examples/ipsec-secgw/ipsec_process.c
@@ -94,22 +94,16 @@ fill_ipsec_session(struct rte_ipsec_session *ss, struct ipsec_ctx *ctx,
 
 	/* setup crypto section */
 	if (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {
-		if (sa->crypto_session == NULL) {
-			rc = create_lookaside_session(ctx, sa);
-			if (rc != 0)
-				return rc;
-		}
-		ss->crypto.ses = sa->crypto_session;
+		RTE_ASSERT(ss->crypto.ses == NULL);
+		rc = create_lookaside_session(ctx, sa, ss);
+		if (rc != 0)
+			return rc;
 	/* setup session action type */
-	} else if (sa->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
-		if (sa->sec_session == NULL) {
-			rc = create_lookaside_session(ctx, sa);
-			if (rc != 0)
-				return rc;
-		}
-		ss->security.ses = sa->sec_session;
-		ss->security.ctx = sa->security_ctx;
-		ss->security.ol_flags = sa->ol_flags;
+	} else if (ss->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
+		RTE_ASSERT(ss->security.ses == NULL);
+		rc = create_lookaside_session(ctx, sa, ss);
+		if (rc != 0)
+			return rc;
 	} else
 		RTE_ASSERT(0);
 
@@ -218,7 +212,7 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 		pg = grp + i;
 		sa = pg->id.ptr;
 
-		ips = &sa->ips;
+		ips = ipsec_get_session(sa);
 
 		/* no valid HW session for that SA, try to create one */
 		if (sa == NULL || (ips->crypto.ses == NULL &&
@@ -226,8 +220,8 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 			k = 0;
 
 		/* process packets inline */
-		else if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				sa->type ==
+		else if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 
 			satp = rte_ipsec_sa_type(ips->sa);
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index c3cf3bd1f..a3d8e4545 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -224,6 +224,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	struct parse_status *status)
 {
 	struct ipsec_sa *rule = NULL;
+	struct rte_ipsec_session *ips;
 	uint32_t ti; /*token index*/
 	uint32_t *ri /*rule index*/;
 	uint32_t cipher_algo_p = 0;
@@ -262,6 +263,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (atoi(tokens[1]) == INVALID_SPI)
 		return;
 	rule->spi = atoi(tokens[1]);
+	ips = ipsec_get_session(rule);
 
 	for (ti = 2; ti < n_tokens; ti++) {
 		if (strcmp(tokens[ti], "mode") == 0) {
@@ -558,18 +560,18 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 				return;
 
 			if (strcmp(tokens[ti], "inline-crypto-offload") == 0)
-				rule->type =
+				ips->type =
 					RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO;
 			else if (strcmp(tokens[ti],
 					"inline-protocol-offload") == 0)
-				rule->type =
+				ips->type =
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
 			else if (strcmp(tokens[ti],
 					"lookaside-protocol-offload") == 0)
-				rule->type =
+				ips->type =
 				RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
 			else if (strcmp(tokens[ti], "no-offload") == 0)
-				rule->type = RTE_SECURITY_ACTION_TYPE_NONE;
+				ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
 			else {
 				APP_CHECK(0, status, "Invalid input \"%s\"",
 						tokens[ti]);
@@ -624,11 +626,11 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (status->status < 0)
 		return;
 
-	if ((rule->type != RTE_SECURITY_ACTION_TYPE_NONE) && (portid_p == 0))
+	if ((ips->type != RTE_SECURITY_ACTION_TYPE_NONE) && (portid_p == 0))
 		printf("Missing portid option, falling back to non-offload\n");
 
 	if (!type_p || !portid_p) {
-		rule->type = RTE_SECURITY_ACTION_TYPE_NONE;
+		ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
 		rule->portid = -1;
 	}
 
@@ -640,6 +642,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 {
 	uint32_t i;
 	uint8_t a, b, c, d;
+	const struct rte_ipsec_session *ips;
 
 	printf("\tspi_%s(%3u):", inbound?"in":"out", sa->spi);
 
@@ -695,8 +698,10 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		printf("Transport ");
 		break;
 	}
+
+	ips = &sa->ips;
 	printf(" type:");
-	switch (sa->type) {
+	switch (ips->type) {
 	case RTE_SECURITY_ACTION_TYPE_NONE:
 		printf("no-offload ");
 		break;
@@ -876,6 +881,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 	uint16_t iv_length, aad_length;
 	int inline_status;
 	int32_t rc;
+	struct rte_ipsec_session *ips;
 
 	/* for ESN upper 32 bits of SQN also need to be part of AAD */
 	aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
@@ -890,9 +896,10 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 		*sa = entries[i];
 		sa->seq = 0;
+		ips = ipsec_get_session(sa);
 
-		if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
-			sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+		if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
+			ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 			if (check_eth_dev_caps(sa->portid, inbound))
 				return -EINVAL;
 		}
@@ -907,7 +914,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 			sa->dst.ip.ip4 = rte_cpu_to_be_32(sa->dst.ip.ip4);
 			break;
 		case TRANSPORT:
-			if (sa->type ==
+			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 				inline_status =
 					sa_add_address_inline_crypto(sa);
@@ -918,6 +925,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 
 		if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
+			struct rte_ipsec_session *ips;
 			iv_length = 16;
 
 			sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
@@ -938,11 +946,12 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			sa->xforms = &sa_ctx->xf[idx].a;
 
-			if (sa->type ==
+			ips = ipsec_get_session(sa);
+			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
-				sa->type ==
+				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
-				rc = create_inline_session(skt_ctx, sa);
+				rc = create_inline_session(skt_ctx, sa, ips);
 				if (rc != 0) {
 					RTE_LOG(ERR, IPSEC_ESP,
 						"create_inline_session() failed\n");
@@ -1100,23 +1109,11 @@ fill_ipsec_sa_prm(struct rte_ipsec_sa_prm *prm, const struct ipsec_sa *ss,
 }
 
 static int
-fill_ipsec_session(struct rte_ipsec_session *ss, struct rte_ipsec_sa *sa,
-	const struct ipsec_sa *lsa)
+fill_ipsec_session(struct rte_ipsec_session *ss, struct rte_ipsec_sa *sa)
 {
 	int32_t rc = 0;
 
 	ss->sa = sa;
-	ss->type = lsa->type;
-
-	/* setup crypto section */
-	if (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {
-		ss->crypto.ses = lsa->crypto_session;
-	/* setup session action type */
-	} else {
-		ss->security.ses = lsa->sec_session;
-		ss->security.ctx = lsa->security_ctx;
-		ss->security.ol_flags = lsa->ol_flags;
-	}
 
 	if (ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 		ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
@@ -1138,6 +1135,7 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 {
 	int rc;
 	struct rte_ipsec_sa_prm prm;
+	struct rte_ipsec_session *ips;
 	struct rte_ipv4_hdr v4  = {
 		.version_ihl = IPVERSION << 4 |
 			sizeof(v4) / RTE_IPV4_IHL_MULTIPLIER,
@@ -1162,7 +1160,10 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 	if (rc < 0)
 		return rc;
 
-	rc = fill_ipsec_session(&lsa->ips, sa, lsa);
+	/* init processing session */
+	ips = ipsec_get_session(lsa);
+	rc = fill_ipsec_session(ips, sa);
+
 	return rc;
 }
 
@@ -1386,6 +1387,7 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 {
 	struct ipsec_sa *rule;
 	uint32_t idx_sa;
+	enum rte_security_session_action_type rule_type;
 
 	*rx_offloads = 0;
 	*tx_offloads = 0;
@@ -1393,8 +1395,9 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	/* Check for inbound rules that use offloads and use this port */
 	for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) {
 		rule = &sa_in[idx_sa];
-		if ((rule->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				rule->type ==
+		rule_type = ipsec_get_action_type(rule);
+		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				rule_type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
 				&& rule->portid == port_id)
 			*rx_offloads |= DEV_RX_OFFLOAD_SECURITY;
@@ -1403,8 +1406,9 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	/* Check for outbound rules that use offloads and use this port */
 	for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) {
 		rule = &sa_out[idx_sa];
-		if ((rule->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				rule->type ==
+		rule_type = ipsec_get_action_type(rule);
+		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				rule_type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
 				&& rule->portid == port_id)
 			*tx_offloads |= DEV_TX_OFFLOAD_SECURITY;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v1 2/2] examples/ipsec-secgw: add fallback session feature
  2019-08-14 20:48 [dpdk-dev] [PATCH v1 0/2] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 1/2] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
@ 2019-08-14 20:48 ` Marcin Smoczynski
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2 siblings, 0 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-08-14 20:48 UTC (permalink / raw)
  To: konstantin.ananyev; +Cc: dev, Marcin Smoczynski

Inline processing is limited to a specified subset of traffic. It is
often unable to handle more complicated situations, such as fragmented
traffic. When using inline processing such traffic is dropped.

Introduce multiple sessions per SA allowing to configure a fallback
lookaside session for packets that normally would be dropped.
A fallback session type in the SA configuration by adding 'fallback'
with 'lookaside-none' or 'lookaside-protocol' parameter to determine
type of session.

Fallback session feature is available only when using librte_ipsec.

Signed-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>
---
 doc/guides/sample_app_ug/ipsec_secgw.rst | 17 +++-
 examples/ipsec-secgw/esp.c               |  4 +-
 examples/ipsec-secgw/ipsec-secgw.c       | 16 ++--
 examples/ipsec-secgw/ipsec.c             | 10 +--
 examples/ipsec-secgw/ipsec.h             | 40 ++++++++--
 examples/ipsec-secgw/ipsec_process.c     | 85 +++++++++++++-------
 examples/ipsec-secgw/sa.c                | 99 ++++++++++++++++++++----
 7 files changed, 210 insertions(+), 61 deletions(-)

diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst
index ad2d79e75..9ded5fb70 100644
--- a/doc/guides/sample_app_ug/ipsec_secgw.rst
+++ b/doc/guides/sample_app_ug/ipsec_secgw.rst
@@ -401,7 +401,7 @@ The SA rule syntax is shown as follows:
 .. code-block:: console
 
     sa <dir> <spi> <cipher_algo> <cipher_key> <auth_algo> <auth_key>
-    <mode> <src_ip> <dst_ip> <action_type> <port_id>
+    <mode> <src_ip> <dst_ip> <action_type> <port_id> <fallback>
 
 where each options means:
 
@@ -573,6 +573,21 @@ where each options means:
 
    * *port_id X* X is a valid device number in decimal
 
+ ``<fallback>``
+
+ * Action type for packets that inline processor failed to process.
+
+ * Optional: Yes, by default there is *no fallback* session type.
+
+ * Available options:
+
+   * *lookaside-none*: use automatically chosen cryptodev to process packets
+   * *lookaside-protocol*: lookaside protocol offload to HW accelerator
+
+ * Syntax:
+
+   * *fallback lookaside-none*
+   * *fallback lookaside-protocol*
 
 Example SA rules:
 
diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index c1b49da1e..bfa7ff721 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -155,7 +155,7 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 
 	if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
 			(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
@@ -234,7 +234,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 	ip_hdr_len = 0;
 
 	ip4 = rte_pktmbuf_mtod(m, struct ip *);
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 0d1fd6af6..641ed3767 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -189,6 +189,7 @@ static uint32_t mtu_size = RTE_ETHER_MTU;
 
 /* application wide librte_ipsec/SA parameters */
 struct app_sa_prm app_sa_prm = {.enable = 0};
+static const char *cfgfile;
 
 struct lcore_rx_queue {
 	uint16_t port_id;
@@ -1462,12 +1463,7 @@ parse_args(int32_t argc, char **argv)
 				print_usage(prgname);
 				return -1;
 			}
-			if (parse_cfg_file(optarg) < 0) {
-				printf("parsing file \"%s\" failed\n",
-					optarg);
-				print_usage(prgname);
-				return -1;
-			}
+			cfgfile = optarg;
 			f_present = 1;
 			break;
 		case 'j':
@@ -2398,6 +2394,14 @@ main(int32_t argc, char **argv)
 	if (ret < 0)
 		rte_exit(EXIT_FAILURE, "Invalid parameters\n");
 
+	/* parse configuration file */
+	if (parse_cfg_file(cfgfile) < 0) {
+		printf("parsing file \"%s\" failed\n",
+			optarg);
+		print_usage(argv[0]);
+		return -1;
+	}
+
 	if ((unprotected_port_mask & enabled_port_mask) !=
 			unprotected_port_mask)
 		rte_exit(EXIT_FAILURE, "Invalid unprotected portmask 0x%x\n",
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 8c60bd84b..8b0441028 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -404,7 +404,7 @@ enqueue_cop(struct cdev_qp *cqp, struct rte_crypto_op *cop)
 
 static inline void
 ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
-		struct rte_mbuf *pkts[], struct ipsec_sa *sas[],
+		struct rte_mbuf *pkts[], void *sas[],
 		uint16_t nb_pkts)
 {
 	int32_t ret = 0, i;
@@ -423,9 +423,9 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		rte_prefetch0(pkts[i]);
 
 		priv = get_priv(pkts[i]);
-		sa = sas[i];
+		sa = ipsec_mask_saptr(sas[i]);
 		priv->sa = sa;
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		switch (ips->type) {
 		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
@@ -586,7 +586,7 @@ uint16_t
 ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
 		uint16_t nb_pkts, uint16_t len)
 {
-	struct ipsec_sa *sas[nb_pkts];
+	void *sas[nb_pkts];
 
 	inbound_sa_lookup(ctx->sa_ctx, pkts, sas, nb_pkts);
 
@@ -606,7 +606,7 @@ uint16_t
 ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
 		uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len)
 {
-	struct ipsec_sa *sas[nb_pkts];
+	void *sas[nb_pkts];
 
 	outbound_sa_lookup(ctx->sa_ctx, sa_idx, sas, nb_pkts);
 
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index a4ad81b0e..8e075216c 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -81,12 +81,32 @@ struct app_sa_prm {
 
 extern struct app_sa_prm app_sa_prm;
 
+enum {
+	IPSEC_SESSION_PRIMARY = 0,
+	IPSEC_SESSION_FALLBACK = 1,
+	IPSEC_SESSION_MAX
+};
+
+#define IPSEC_SA_OFFLOAD_FALLBACK_FLAG (1)
+
+static inline struct ipsec_sa *
+ipsec_mask_saptr(void *ptr)
+{
+	uintptr_t i = (uintptr_t)ptr;
+	static const uintptr_t mask = IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
+
+	i &= ~mask;
+
+	return (struct ipsec_sa *)i;
+}
+
 struct ipsec_sa {
-	struct rte_ipsec_session ips; /* one session per sa for now */
+	struct rte_ipsec_session sessions[IPSEC_SESSION_MAX];
 	uint32_t spi;
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
+	uint32_t fallback_sessions;
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
 	enum rte_crypto_aead_algorithm aead_algo;
@@ -210,7 +230,7 @@ struct cnt_blk {
 struct traffic_type {
 	const uint8_t *data[MAX_PKT_BURST * 2];
 	struct rte_mbuf *pkts[MAX_PKT_BURST * 2];
-	struct ipsec_sa *saptr[MAX_PKT_BURST * 2];
+	void *saptr[MAX_PKT_BURST * 2];
 	uint32_t res[MAX_PKT_BURST * 2];
 	uint32_t num;
 };
@@ -278,16 +298,22 @@ get_sym_cop(struct rte_crypto_op *cop)
 }
 
 static inline struct rte_ipsec_session *
-ipsec_get_session(struct ipsec_sa *sa)
+ipsec_get_primary_session(struct ipsec_sa *sa)
+{
+	return &sa->sessions[IPSEC_SESSION_PRIMARY];
+}
+
+static inline struct rte_ipsec_session *
+ipsec_get_fallback_session(struct ipsec_sa *sa)
 {
-	return &sa->ips;
+	return &sa->sessions[IPSEC_SESSION_FALLBACK];
 }
 
 static inline enum rte_security_session_action_type
 ipsec_get_action_type(struct ipsec_sa *sa)
 {
 	struct rte_ipsec_session *ips;
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 	return ips->type;
 }
 
@@ -296,11 +322,11 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx);
 
 void
 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts);
+		void *sa[], uint16_t nb_pkts);
 
 void
 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts);
+		void *sa[], uint16_t nb_pkts);
 
 void
 sp4_init(struct socket_ctx *ctx, int32_t socket_id);
diff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c
index 239d81ef6..2eb5c8b34 100644
--- a/examples/ipsec-secgw/ipsec_process.c
+++ b/examples/ipsec-secgw/ipsec_process.c
@@ -18,7 +18,6 @@
 	(((t) & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)) || \
 	((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TUNLV4)
 
-
 /* helper routine to free bulk of packets */
 static inline void
 free_pkts(struct rte_mbuf *mb[], uint32_t n)
@@ -118,7 +117,7 @@ fill_ipsec_session(struct rte_ipsec_session *ss, struct ipsec_ctx *ctx,
  * group input packets byt the SA they belong to.
  */
 static uint32_t
-sa_group(struct ipsec_sa *sa_ptr[], struct rte_mbuf *pkts[],
+sa_group(void *sa_ptr[], struct rte_mbuf *pkts[],
 	struct rte_ipsec_group grp[], uint32_t num)
 {
 	uint32_t i, n, spi;
@@ -185,6 +184,37 @@ copy_to_trf(struct ipsec_traffic *trf, uint64_t satp, struct rte_mbuf *mb[],
 	out->num += num;
 }
 
+static uint32_t
+ipsec_prepare_crypto_group(struct ipsec_ctx *ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips, struct rte_mbuf **m,
+		unsigned int cnt)
+{
+	struct cdev_qp *cqp;
+	struct rte_crypto_op *cop[cnt];
+	uint32_t j, k;
+	struct ipsec_mbuf_metadata *priv;
+
+	cqp = &ctx->tbl[sa->cdev_id_qp];
+
+	/* for that app each mbuf has it's own crypto op */
+	for (j = 0; j != cnt; j++) {
+		priv = get_priv(m[j]);
+		cop[j] = &priv->cop;
+		/*
+		 * this is just to satisfy inbound_sa_check()
+		 * should be removed in future.
+		 */
+		priv->sa = sa;
+	}
+
+	/* prepare and enqueue crypto ops */
+	k = rte_ipsec_pkt_crypto_prepare(ips, m, cop, cnt);
+	if (k != 0)
+		enqueue_cop_bulk(cqp, cop, k);
+
+	return k;
+}
+
 /*
  * Process ipsec packets.
  * If packet belong to SA that is subject of inline-crypto,
@@ -201,18 +231,15 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 	struct ipsec_mbuf_metadata *priv;
 	struct rte_ipsec_group *pg;
 	struct rte_ipsec_session *ips;
-	struct cdev_qp *cqp;
-	struct rte_crypto_op *cop[RTE_DIM(trf->ipsec.pkts)];
 	struct rte_ipsec_group grp[RTE_DIM(trf->ipsec.pkts)];
 
 	n = sa_group(trf->ipsec.saptr, trf->ipsec.pkts, grp, trf->ipsec.num);
 
 	for (i = 0; i != n; i++) {
-
 		pg = grp + i;
-		sa = pg->id.ptr;
+		sa = ipsec_mask_saptr(pg->id.ptr);
 
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		/* no valid HW session for that SA, try to create one */
 		if (sa == NULL || (ips->crypto.ses == NULL &&
@@ -224,6 +251,7 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 
+			/* get SA type */
 			satp = rte_ipsec_sa_type(ips->sa);
 
 			/*
@@ -236,30 +264,33 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 				priv->sa = sa;
 			}
 
-			k = rte_ipsec_pkt_process(ips, pg->m, pg->cnt);
-			copy_to_trf(trf, satp, pg->m, k);
+			/* fallback to cryptodev with RX packets which inline
+			 * processor was unable to process
+			 */
+			if (pg->id.val & IPSEC_SA_OFFLOAD_FALLBACK_FLAG) {
+				/* offload packets to cryptodev */
+				struct rte_ipsec_session *fallback;
+
+				fallback = ipsec_get_fallback_session(sa);
+				if (fallback->crypto.ses == NULL &&
+					fill_ipsec_session(fallback, ctx, sa)
+					!= 0)
+					k = 0;
+				else
+					k = ipsec_prepare_crypto_group(ctx, sa,
+						fallback, pg->m, pg->cnt);
+			} else {
+				/* finish processing of packets successfully
+				 * decrypted by an inline processor
+				 */
+				k = rte_ipsec_pkt_process(ips, pg->m, pg->cnt);
+				copy_to_trf(trf, satp, pg->m, k);
 
+			}
 		/* enqueue packets to crypto dev */
 		} else {
-
-			cqp = &ctx->tbl[sa->cdev_id_qp];
-
-			/* for that app each mbuf has it's own crypto op */
-			for (j = 0; j != pg->cnt; j++) {
-				priv = get_priv(pg->m[j]);
-				cop[j] = &priv->cop;
-				/*
-				 * this is just to satisfy inbound_sa_check()
-				 * should be removed in future.
-				 */
-				priv->sa = sa;
-			}
-
-			/* prepare and enqueue crypto ops */
-			k = rte_ipsec_pkt_crypto_prepare(ips, pg->m, cop,
+			k = ipsec_prepare_crypto_group(ctx, sa, ips, pg->m,
 				pg->cnt);
-			if (k != 0)
-				enqueue_cop_bulk(cqp, cop, k);
 		}
 
 		/* drop packets that cannot be enqueued/processed */
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index a3d8e4545..0c8db6349 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -31,6 +31,8 @@
 
 #define IP6_FULL_MASK (sizeof(((struct ip_addr *)NULL)->ip.ip6.ip6) * CHAR_BIT)
 
+#define MBUF_NO_SEC_OFFLOAD(m) ((m->ol_flags & PKT_RX_SEC_OFFLOAD) == 0)
+
 struct supported_cipher_algo {
 	const char *keyword;
 	enum rte_crypto_cipher_algorithm algo;
@@ -235,6 +237,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	uint32_t mode_p = 0;
 	uint32_t type_p = 0;
 	uint32_t portid_p = 0;
+	uint32_t fallback_p = 0;
 
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
@@ -263,7 +266,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (atoi(tokens[1]) == INVALID_SPI)
 		return;
 	rule->spi = atoi(tokens[1]);
-	ips = ipsec_get_session(rule);
+	ips = ipsec_get_primary_session(rule);
 
 	for (ti = 2; ti < n_tokens; ti++) {
 		if (strcmp(tokens[ti], "mode") == 0) {
@@ -596,6 +599,37 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			continue;
 		}
 
+		if (strcmp(tokens[ti], "fallback") == 0) {
+			struct rte_ipsec_session *fb;
+
+			APP_CHECK(app_sa_prm.enable, status, "Fallback session "
+				"not allowed for legacy mode.");
+			if (status->status < 0)
+				return;
+			APP_CHECK_PRESENCE(fallback_p, tokens[ti], status);
+			if (status->status < 0)
+				return;
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+			fb = ipsec_get_fallback_session(rule);
+			if (strcmp(tokens[ti], "lookaside-none") == 0) {
+				fb->type = RTE_SECURITY_ACTION_TYPE_NONE;
+			} else if (strcmp(tokens[ti], "lookaside-protocol")
+				== 0) {
+				fb->type =
+				RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
+			} else {
+				APP_CHECK(0, status, "unrecognized fallback "
+					"type %s.", tokens[ti]);
+				return;
+			}
+
+			rule->fallback_sessions = 1;
+			fallback_p = 1;
+			continue;
+		}
+
 		/* unrecognizeable input */
 		APP_CHECK(0, status, "unrecognized input \"%s\"",
 			tokens[ti]);
@@ -643,6 +677,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 	uint32_t i;
 	uint8_t a, b, c, d;
 	const struct rte_ipsec_session *ips;
+	const struct rte_ipsec_session *fallback_ips;
 
 	printf("\tspi_%s(%3u):", inbound?"in":"out", sa->spi);
 
@@ -699,7 +734,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		break;
 	}
 
-	ips = &sa->ips;
+	ips = &sa->sessions[IPSEC_SESSION_PRIMARY];
 	printf(" type:");
 	switch (ips->type) {
 	case RTE_SECURITY_ACTION_TYPE_NONE:
@@ -715,6 +750,22 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		printf("lookaside-protocol-offload ");
 		break;
 	}
+
+	fallback_ips = &sa->sessions[IPSEC_SESSION_FALLBACK];
+	if (fallback_ips != NULL && sa->fallback_sessions > 0) {
+		printf("inline fallback:");
+		switch (fallback_ips->type) {
+		case RTE_SECURITY_ACTION_TYPE_NONE:
+			printf("lookaside-none ");
+			break;
+		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
+			printf("lookaside-protocol ");
+			break;
+		default:
+			printf("invalid ");
+			break;
+		}
+	}
 	printf("\n");
 }
 
@@ -896,7 +947,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 		*sa = entries[i];
 		sa->seq = 0;
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
 			ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
@@ -946,7 +997,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			sa->xforms = &sa_ctx->xf[idx].a;
 
-			ips = ipsec_get_session(sa);
+			ips = ipsec_get_primary_session(sa);
 			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
 				ips->type ==
@@ -1160,9 +1211,15 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 	if (rc < 0)
 		return rc;
 
-	/* init processing session */
-	ips = ipsec_get_session(lsa);
+	/* init primary processing session */
+	ips = ipsec_get_primary_session(lsa);
 	rc = fill_ipsec_session(ips, sa);
+	if (rc != 0)
+		return rc;
+
+	/* init inline fallback processing session */
+	if (lsa->fallback_sessions == 1)
+		rc = fill_ipsec_session(ipsec_get_fallback_session(lsa), sa);
 
 	return rc;
 }
@@ -1318,13 +1375,14 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)
 
 static inline void
 single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
-		struct ipsec_sa **sa_ret)
+		void **sa_ret)
 {
 	struct rte_esp_hdr *esp;
 	struct ip *ip;
 	uint32_t *src4_addr;
 	uint8_t *src6_addr;
 	struct ipsec_sa *sa;
+	void *result_sa;
 
 	*sa_ret = NULL;
 
@@ -1334,33 +1392,48 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
 	if (esp->spi == INVALID_SPI)
 		return;
 
-	sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
+	result_sa = sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
 	if (rte_be_to_cpu_32(esp->spi) != sa->spi)
 		return;
 
+	/*
+	 * Mark need for inline offload fallback on the LSB of SA pointer.
+	 * Thanks to packet grouping mechanism which ipsec_process is using
+	 * packets marked for fallback processing will form separate group.
+	 *
+	 * Because it is not safe to use SA pointer it is casted to generic
+	 * pointer to prevent from unintentional use. Use ipsec_mask_saptr
+	 * to get valid struct pointer.
+	 */
+	if (MBUF_NO_SEC_OFFLOAD(pkt) && sa->fallback_sessions > 0) {
+		uintptr_t intsa = (uintptr_t)sa;
+		intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
+		result_sa = (void *)intsa;
+	}
+
 	switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
 	case IP4_TUNNEL:
 		src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src));
 		if ((ip->ip_v == IPVERSION) &&
 				(sa->src.ip.ip4 == *src4_addr) &&
 				(sa->dst.ip.ip4 == *(src4_addr + 1)))
-			*sa_ret = sa;
+			*sa_ret = result_sa;
 		break;
 	case IP6_TUNNEL:
 		src6_addr = RTE_PTR_ADD(ip, offsetof(struct ip6_hdr, ip6_src));
 		if ((ip->ip_v == IP6_VERSION) &&
 				!memcmp(&sa->src.ip.ip6.ip6, src6_addr, 16) &&
 				!memcmp(&sa->dst.ip.ip6.ip6, src6_addr + 16, 16))
-			*sa_ret = sa;
+			*sa_ret = result_sa;
 		break;
 	case TRANSPORT:
-		*sa_ret = sa;
+		*sa_ret = result_sa;
 	}
 }
 
 void
 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts)
+		void *sa[], uint16_t nb_pkts)
 {
 	uint32_t i;
 
@@ -1370,7 +1443,7 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
 
 void
 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts)
+		void *sa[], uint16_t nb_pkts)
 {
 	uint32_t i;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-08-14 20:48 [dpdk-dev] [PATCH v1 0/2] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 1/2] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
  2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 2/2] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
@ 2019-09-04 14:16 ` Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 1/3] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
                     ` (3 more replies)
  2 siblings, 4 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-09-04 14:16 UTC (permalink / raw)
  To: konstantin.ananyev, akhil.goyal; +Cc: dev, Marcin Smoczynski

Inline processing is limited to a specified subset of traffic. It is
often unable to handle more complicated situations, such as fragmented
traffic. When using inline processing such traffic is dropped.

Introduce multiple sessions per SA allowing to configure a fallback
lookaside session for packets that normally would be dropped.
A fallback session type in the SA configuration by adding 'fallback'
with 'lookaside-none' or 'lookaside-protocol' parameter to determine
type of session.

Fallback session feature is available only when using librte_ipsec.

v1 to v2 changes:
 - disable fallback offload for outbound SAs
 - add test scripts

Marcin Smoczynski (3):
  examples/ipsec-secgw: ipsec_sa structure cleanup
  examples/ipsec-secgw: add fallback session feature
  examples/ipsec-secgw: add offload fallback tests

 doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
 examples/ipsec-secgw/esp.c                    |  35 ++--
 examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
 examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
 examples/ipsec-secgw/ipsec.h                  |  61 +++++--
 examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
 examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
 .../test/trs_aesgcm_common_defs.sh            |   4 +-
 .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
 .../test/tun_aesgcm_common_defs.sh            |   6 +-
 .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
 11 files changed, 358 insertions(+), 167 deletions(-)
 create mode 100644 examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
 create mode 100644 examples/ipsec-secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh

-- 
2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 1/3] examples/ipsec-secgw: ipsec_sa structure cleanup
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
@ 2019-09-04 14:16   ` Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 2/3] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-09-04 14:16 UTC (permalink / raw)
  To: konstantin.ananyev, akhil.goyal; +Cc: dev, Marcin Smoczynski

Cleanup ipsec_sa structure by removing every field that is already in
the rte_ipsec_session structure:
 * cryptodev/security session union
 * action type
 * offload flags
 * security context
References to abovementioned fields are changed to direct references
to matching fields of rte_ipsec_session structure.

Such refactoring is needed to introduce many sessions per SA feature,
e.g. fallback session for inline offload processing.

Signed-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>
---
 examples/ipsec-secgw/esp.c           | 35 +++++++----
 examples/ipsec-secgw/ipsec.c         | 91 +++++++++++++++-------------
 examples/ipsec-secgw/ipsec.h         | 27 ++++++---
 examples/ipsec-secgw/ipsec_process.c | 30 ++++-----
 examples/ipsec-secgw/sa.c            | 66 ++++++++++----------
 5 files changed, 137 insertions(+), 112 deletions(-)

diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index d6d7b1256..c1b49da1e 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -30,7 +30,8 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	int32_t payload_len, ip_hdr_len;
 
 	RTE_ASSERT(sa != NULL);
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
+	if (ipsec_get_action_type(sa) ==
+			RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
 		return 0;
 
 	RTE_ASSERT(m != NULL);
@@ -148,13 +149,16 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	uint8_t *nexthdr, *pad_len;
 	uint8_t *padding;
 	uint16_t i;
+	struct rte_ipsec_session *ips;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-			(sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+	ips = ipsec_get_session(sa);
+
+	if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+			(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
 		if (m->ol_flags & PKT_RX_SEC_OFFLOAD) {
 			if (m->ol_flags & PKT_RX_SEC_OFFLOAD_FAILED)
 				cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
@@ -169,8 +173,8 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 		return -1;
 	}
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-	    sa->ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+		ips->security.ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
 		nexthdr = &m->inner_esp_next_proto;
 	} else {
 		nexthdr = rte_pktmbuf_mtod_offset(m, uint8_t*,
@@ -225,10 +229,12 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	struct rte_crypto_sym_op *sym_cop;
 	int32_t i;
 	uint16_t pad_payload_len, pad_len, ip_hdr_len;
+	struct rte_ipsec_session *ips;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
+	ips = ipsec_get_session(sa);
 	ip_hdr_len = 0;
 
 	ip4 = rte_pktmbuf_mtod(m, struct ip *);
@@ -277,9 +283,10 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	}
 
 	/* Add trailer padding if it is not constructed by HW */
-	if (sa->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-	    (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-	     !(sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
+	if (ips->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+		(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+		 !(ips->security.ol_flags &
+			 RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
 		padding = (uint8_t *)rte_pktmbuf_append(m, pad_len +
 							sa->digest_len);
 		if (unlikely(padding == NULL)) {
@@ -344,8 +351,9 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 		}
 	}
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
-		if (sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+		if (ips->security.ol_flags &
+				RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
 			/* Set the inner esp next protocol for HW trailer */
 			m->inner_esp_next_proto = nlp;
 			m->packet_type |= RTE_PTYPE_TUNNEL_ESP;
@@ -448,11 +456,14 @@ esp_outbound_post(struct rte_mbuf *m,
 		  struct ipsec_sa *sa,
 		  struct rte_crypto_op *cop)
 {
+	enum rte_security_session_action_type type;
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
-	if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-			(sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+	type = ipsec_get_action_type(sa);
+
+	if ((type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+			(type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
 		m->ol_flags |= PKT_TX_SEC_OFFLOAD;
 	} else {
 		RTE_ASSERT(cop != NULL);
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index dc85adfe5..8c60bd84b 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -40,7 +40,8 @@ set_ipsec_conf(struct ipsec_sa *sa, struct rte_security_ipsec_xform *ipsec)
 }
 
 int
-create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
+create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips)
 {
 	struct rte_cryptodev_info cdev_info;
 	unsigned long cdev_id_qp = 0;
@@ -71,9 +72,9 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			ipsec_ctx->tbl[cdev_id_qp].id,
 			ipsec_ctx->tbl[cdev_id_qp].qp);
 
-	if (sa->type != RTE_SECURITY_ACTION_TYPE_NONE) {
+	if (ips->type != RTE_SECURITY_ACTION_TYPE_NONE) {
 		struct rte_security_session_conf sess_conf = {
-			.action_type = sa->type,
+			.action_type = ips->type,
 			.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
 			{.ipsec = {
 				.spi = sa->spi,
@@ -90,7 +91,7 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 
 		};
 
-		if (sa->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
+		if (ips->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
 			struct rte_security_ctx *ctx = (struct rte_security_ctx *)
 							rte_cryptodev_get_sec_ctx(
 							ipsec_ctx->tbl[cdev_id_qp].id);
@@ -98,9 +99,9 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			/* Set IPsec parameters in conf */
 			set_ipsec_conf(sa, &(sess_conf.ipsec));
 
-			sa->sec_session = rte_security_session_create(ctx,
+			ips->security.ses = rte_security_session_create(ctx,
 					&sess_conf, ipsec_ctx->session_priv_pool);
-			if (sa->sec_session == NULL) {
+			if (ips->security.ses == NULL) {
 				RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 				return -1;
@@ -110,10 +111,10 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 	} else {
-		sa->crypto_session = rte_cryptodev_sym_session_create(
+		ips->crypto.ses = rte_cryptodev_sym_session_create(
 				ipsec_ctx->session_pool);
 		rte_cryptodev_sym_session_init(ipsec_ctx->tbl[cdev_id_qp].id,
-				sa->crypto_session, sa->xforms,
+				ips->crypto.ses, sa->xforms,
 				ipsec_ctx->session_priv_pool);
 
 		rte_cryptodev_info_get(ipsec_ctx->tbl[cdev_id_qp].id,
@@ -126,12 +127,13 @@ create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 }
 
 int
-create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
+create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips)
 {
 	int32_t ret = 0;
 	struct rte_security_ctx *sec_ctx;
 	struct rte_security_session_conf sess_conf = {
-		.action_type = sa->type,
+		.action_type = ips->type,
 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
 		{.ipsec = {
 			.spi = sa->spi,
@@ -151,7 +153,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 	RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n",
 		sa->spi, sa->portid);
 
-	if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+	if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 		struct rte_flow_error err;
 		const struct rte_security_capability *sec_cap;
 		int ret = 0;
@@ -165,9 +167,9 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->sec_session = rte_security_session_create(sec_ctx,
+		ips->security.ses = rte_security_session_create(sec_ctx,
 				&sess_conf, skt_ctx->session_pool);
-		if (sa->sec_session == NULL) {
+		if (ips->security.ses == NULL) {
 			RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 			return -1;
@@ -177,7 +179,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 
 		/* iterate until ESP tunnel*/
 		while (sec_cap->action != RTE_SECURITY_ACTION_TYPE_NONE) {
-			if (sec_cap->action == sa->type &&
+			if (sec_cap->action == ips->type &&
 			    sec_cap->protocol ==
 				RTE_SECURITY_PROTOCOL_IPSEC &&
 			    sec_cap->ipsec.mode ==
@@ -193,8 +195,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->ol_flags = sec_cap->ol_flags;
-		sa->security_ctx = sec_ctx;
+		ips->security.ol_flags = sec_cap->ol_flags;
+		ips->security.ctx = sec_ctx;
 		sa->pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
 
 		if (IS_IP6(sa->flags)) {
@@ -223,7 +225,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 		sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
 
 		sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
-		sa->action[0].conf = sa->sec_session;
+		sa->action[0].conf = ips->security.ses;
 
 		sa->action[1].type = RTE_FLOW_ACTION_TYPE_END;
 
@@ -282,8 +284,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			if (ret)
 				goto flow_create_failure;
 		} else if (sa->attr.egress &&
-			   (sa->ol_flags &
-				    RTE_SECURITY_TX_HW_TRAILER_OFFLOAD)) {
+				(ips->security.ol_flags &
+					RTE_SECURITY_TX_HW_TRAILER_OFFLOAD)) {
 			sa->action[1].type =
 					RTE_FLOW_ACTION_TYPE_PASSTHRU;
 			sa->action[2].type =
@@ -299,7 +301,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 				err.message);
 			return -1;
 		}
-	} else if (sa->type ==	RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
+	} else if (ips->type ==	RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 		const struct rte_security_capability *sec_cap;
 
 		sec_ctx = (struct rte_security_ctx *)
@@ -327,9 +329,9 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 
 		sess_conf.userdata = (void *) sa;
 
-		sa->sec_session = rte_security_session_create(sec_ctx,
+		ips->security.ses = rte_security_session_create(sec_ctx,
 					&sess_conf, skt_ctx->session_pool);
-		if (sa->sec_session == NULL) {
+		if (ips->security.ses == NULL) {
 			RTE_LOG(ERR, IPSEC,
 				"SEC Session init failed: err: %d\n", ret);
 			return -1;
@@ -345,7 +347,7 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 		/* iterate until ESP tunnel*/
 		while (sec_cap->action !=
 				RTE_SECURITY_ACTION_TYPE_NONE) {
-			if (sec_cap->action == sa->type &&
+			if (sec_cap->action == ips->type &&
 			    sec_cap->protocol ==
 				RTE_SECURITY_PROTOCOL_IPSEC &&
 			    sec_cap->ipsec.mode ==
@@ -361,8 +363,8 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa)
 			return -1;
 		}
 
-		sa->ol_flags = sec_cap->ol_flags;
-		sa->security_ctx = sec_ctx;
+		ips->security.ol_flags = sec_cap->ol_flags;
+		ips->security.ctx = sec_ctx;
 	}
 	sa->cdev_id_qp = 0;
 
@@ -409,6 +411,7 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 	struct ipsec_mbuf_metadata *priv;
 	struct rte_crypto_sym_op *sym_cop;
 	struct ipsec_sa *sa;
+	struct rte_ipsec_session *ips;
 
 	for (i = 0; i < nb_pkts; i++) {
 		if (unlikely(sas[i] == NULL)) {
@@ -422,16 +425,17 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		priv = get_priv(pkts[i]);
 		sa = sas[i];
 		priv->sa = sa;
+		ips = ipsec_get_session(sa);
 
-		switch (sa->type) {
+		switch (ips->type) {
 		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
 			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
 			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 
 			rte_prefetch0(&priv->sym_cop);
 
-			if ((unlikely(sa->sec_session == NULL)) &&
-				create_lookaside_session(ipsec_ctx, sa)) {
+			if ((unlikely(ips->security.ses == NULL)) &&
+				create_lookaside_session(ipsec_ctx, sa, ips)) {
 				rte_pktmbuf_free(pkts[i]);
 				continue;
 			}
@@ -440,7 +444,7 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			sym_cop->m_src = pkts[i];
 
 			rte_security_attach_session(&priv->cop,
-					sa->sec_session);
+				ips->security.ses);
 			break;
 		case RTE_SECURITY_ACTION_TYPE_NONE:
 
@@ -449,14 +453,14 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 
 			rte_prefetch0(&priv->sym_cop);
 
-			if ((unlikely(sa->crypto_session == NULL)) &&
-				create_lookaside_session(ipsec_ctx, sa)) {
+			if ((unlikely(ips->crypto.ses == NULL)) &&
+				create_lookaside_session(ipsec_ctx, sa, ips)) {
 				rte_pktmbuf_free(pkts[i]);
 				continue;
 			}
 
 			rte_crypto_op_attach_sym_session(&priv->cop,
-					sa->crypto_session);
+					ips->crypto.ses);
 
 			ret = xform_func(pkts[i], sa, &priv->cop);
 			if (unlikely(ret)) {
@@ -465,21 +469,22 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			}
 			break;
 		case RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL:
-			RTE_ASSERT(sa->sec_session != NULL);
+			RTE_ASSERT(ips->security.ses != NULL);
 			ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i];
-			if (sa->ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
+			if (ips->security.ol_flags &
+				RTE_SECURITY_TX_OLOAD_NEED_MDATA)
 				rte_security_set_pkt_metadata(
-						sa->security_ctx,
-						sa->sec_session, pkts[i], NULL);
+					ips->security.ctx, ips->security.ses,
+					pkts[i], NULL);
 			continue;
 		case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO:
-			RTE_ASSERT(sa->sec_session != NULL);
+			RTE_ASSERT(ips->security.ses != NULL);
 			priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
 			priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 
 			rte_prefetch0(&priv->sym_cop);
 			rte_security_attach_session(&priv->cop,
-					sa->sec_session);
+					ips->security.ses);
 
 			ret = xform_func(pkts[i], sa, &priv->cop);
 			if (unlikely(ret)) {
@@ -488,10 +493,11 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 			}
 
 			ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i];
-			if (sa->ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)
+			if (ips->security.ol_flags &
+				RTE_SECURITY_TX_OLOAD_NEED_MDATA)
 				rte_security_set_pkt_metadata(
-						sa->security_ctx,
-						sa->sec_session, pkts[i], NULL);
+					ips->security.ctx, ips->security.ses,
+					pkts[i], NULL);
 			continue;
 		}
 
@@ -560,7 +566,8 @@ ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 
 			RTE_ASSERT(sa != NULL);
 
-			if (sa->type == RTE_SECURITY_ACTION_TYPE_NONE) {
+			if (ipsec_get_action_type(sa) ==
+				RTE_SECURITY_ACTION_TYPE_NONE) {
 				ret = xform_func(pkt, sa, cops[j]);
 				if (unlikely(ret)) {
 					rte_pktmbuf_free(pkt);
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 1efa6e488..a4ad81b0e 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -87,10 +87,6 @@ struct ipsec_sa {
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
-	union {
-		struct rte_cryptodev_sym_session *crypto_session;
-		struct rte_security_session *sec_session;
-	};
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
 	enum rte_crypto_aead_algorithm aead_algo;
@@ -114,11 +110,8 @@ struct ipsec_sa {
 		struct rte_crypto_sym_xform *xforms;
 		struct rte_security_ipsec_xform *sec_xform;
 	};
-	enum rte_security_session_action_type type;
 	enum rte_security_ipsec_sa_direction direction;
 	uint16_t portid;
-	struct rte_security_ctx *security_ctx;
-	uint32_t ol_flags;
 
 #define MAX_RTE_FLOW_PATTERN (4)
 #define MAX_RTE_FLOW_ACTIONS (3)
@@ -284,6 +277,20 @@ get_sym_cop(struct rte_crypto_op *cop)
 	return (cop + 1);
 }
 
+static inline struct rte_ipsec_session *
+ipsec_get_session(struct ipsec_sa *sa)
+{
+	return &sa->ips;
+}
+
+static inline enum rte_security_session_action_type
+ipsec_get_action_type(struct ipsec_sa *sa)
+{
+	struct rte_ipsec_session *ips;
+	ips = ipsec_get_session(sa);
+	return ips->type;
+}
+
 int
 inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx);
 
@@ -338,9 +345,11 @@ void
 enqueue_cop_burst(struct cdev_qp *cqp);
 
 int
-create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa);
+create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips);
 
 int
-create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa);
+create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips);
 
 #endif /* __IPSEC_H__ */
diff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c
index 868f1a28d..239d81ef6 100644
--- a/examples/ipsec-secgw/ipsec_process.c
+++ b/examples/ipsec-secgw/ipsec_process.c
@@ -94,22 +94,16 @@ fill_ipsec_session(struct rte_ipsec_session *ss, struct ipsec_ctx *ctx,
 
 	/* setup crypto section */
 	if (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {
-		if (sa->crypto_session == NULL) {
-			rc = create_lookaside_session(ctx, sa);
-			if (rc != 0)
-				return rc;
-		}
-		ss->crypto.ses = sa->crypto_session;
+		RTE_ASSERT(ss->crypto.ses == NULL);
+		rc = create_lookaside_session(ctx, sa, ss);
+		if (rc != 0)
+			return rc;
 	/* setup session action type */
-	} else if (sa->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
-		if (sa->sec_session == NULL) {
-			rc = create_lookaside_session(ctx, sa);
-			if (rc != 0)
-				return rc;
-		}
-		ss->security.ses = sa->sec_session;
-		ss->security.ctx = sa->security_ctx;
-		ss->security.ol_flags = sa->ol_flags;
+	} else if (ss->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) {
+		RTE_ASSERT(ss->security.ses == NULL);
+		rc = create_lookaside_session(ctx, sa, ss);
+		if (rc != 0)
+			return rc;
 	} else
 		RTE_ASSERT(0);
 
@@ -218,7 +212,7 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 		pg = grp + i;
 		sa = pg->id.ptr;
 
-		ips = &sa->ips;
+		ips = ipsec_get_session(sa);
 
 		/* no valid HW session for that SA, try to create one */
 		if (sa == NULL || (ips->crypto.ses == NULL &&
@@ -226,8 +220,8 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 			k = 0;
 
 		/* process packets inline */
-		else if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				sa->type ==
+		else if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 
 			satp = rte_ipsec_sa_type(ips->sa);
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index c3cf3bd1f..a3d8e4545 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -224,6 +224,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	struct parse_status *status)
 {
 	struct ipsec_sa *rule = NULL;
+	struct rte_ipsec_session *ips;
 	uint32_t ti; /*token index*/
 	uint32_t *ri /*rule index*/;
 	uint32_t cipher_algo_p = 0;
@@ -262,6 +263,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (atoi(tokens[1]) == INVALID_SPI)
 		return;
 	rule->spi = atoi(tokens[1]);
+	ips = ipsec_get_session(rule);
 
 	for (ti = 2; ti < n_tokens; ti++) {
 		if (strcmp(tokens[ti], "mode") == 0) {
@@ -558,18 +560,18 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 				return;
 
 			if (strcmp(tokens[ti], "inline-crypto-offload") == 0)
-				rule->type =
+				ips->type =
 					RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO;
 			else if (strcmp(tokens[ti],
 					"inline-protocol-offload") == 0)
-				rule->type =
+				ips->type =
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
 			else if (strcmp(tokens[ti],
 					"lookaside-protocol-offload") == 0)
-				rule->type =
+				ips->type =
 				RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
 			else if (strcmp(tokens[ti], "no-offload") == 0)
-				rule->type = RTE_SECURITY_ACTION_TYPE_NONE;
+				ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
 			else {
 				APP_CHECK(0, status, "Invalid input \"%s\"",
 						tokens[ti]);
@@ -624,11 +626,11 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (status->status < 0)
 		return;
 
-	if ((rule->type != RTE_SECURITY_ACTION_TYPE_NONE) && (portid_p == 0))
+	if ((ips->type != RTE_SECURITY_ACTION_TYPE_NONE) && (portid_p == 0))
 		printf("Missing portid option, falling back to non-offload\n");
 
 	if (!type_p || !portid_p) {
-		rule->type = RTE_SECURITY_ACTION_TYPE_NONE;
+		ips->type = RTE_SECURITY_ACTION_TYPE_NONE;
 		rule->portid = -1;
 	}
 
@@ -640,6 +642,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 {
 	uint32_t i;
 	uint8_t a, b, c, d;
+	const struct rte_ipsec_session *ips;
 
 	printf("\tspi_%s(%3u):", inbound?"in":"out", sa->spi);
 
@@ -695,8 +698,10 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		printf("Transport ");
 		break;
 	}
+
+	ips = &sa->ips;
 	printf(" type:");
-	switch (sa->type) {
+	switch (ips->type) {
 	case RTE_SECURITY_ACTION_TYPE_NONE:
 		printf("no-offload ");
 		break;
@@ -876,6 +881,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 	uint16_t iv_length, aad_length;
 	int inline_status;
 	int32_t rc;
+	struct rte_ipsec_session *ips;
 
 	/* for ESN upper 32 bits of SQN also need to be part of AAD */
 	aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
@@ -890,9 +896,10 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 		*sa = entries[i];
 		sa->seq = 0;
+		ips = ipsec_get_session(sa);
 
-		if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
-			sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+		if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
+			ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 			if (check_eth_dev_caps(sa->portid, inbound))
 				return -EINVAL;
 		}
@@ -907,7 +914,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 			sa->dst.ip.ip4 = rte_cpu_to_be_32(sa->dst.ip.ip4);
 			break;
 		case TRANSPORT:
-			if (sa->type ==
+			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
 				inline_status =
 					sa_add_address_inline_crypto(sa);
@@ -918,6 +925,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 
 		if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) {
+			struct rte_ipsec_session *ips;
 			iv_length = 16;
 
 			sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD;
@@ -938,11 +946,12 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			sa->xforms = &sa_ctx->xf[idx].a;
 
-			if (sa->type ==
+			ips = ipsec_get_session(sa);
+			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
-				sa->type ==
+				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
-				rc = create_inline_session(skt_ctx, sa);
+				rc = create_inline_session(skt_ctx, sa, ips);
 				if (rc != 0) {
 					RTE_LOG(ERR, IPSEC_ESP,
 						"create_inline_session() failed\n");
@@ -1100,23 +1109,11 @@ fill_ipsec_sa_prm(struct rte_ipsec_sa_prm *prm, const struct ipsec_sa *ss,
 }
 
 static int
-fill_ipsec_session(struct rte_ipsec_session *ss, struct rte_ipsec_sa *sa,
-	const struct ipsec_sa *lsa)
+fill_ipsec_session(struct rte_ipsec_session *ss, struct rte_ipsec_sa *sa)
 {
 	int32_t rc = 0;
 
 	ss->sa = sa;
-	ss->type = lsa->type;
-
-	/* setup crypto section */
-	if (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {
-		ss->crypto.ses = lsa->crypto_session;
-	/* setup session action type */
-	} else {
-		ss->security.ses = lsa->sec_session;
-		ss->security.ctx = lsa->security_ctx;
-		ss->security.ol_flags = lsa->ol_flags;
-	}
 
 	if (ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 		ss->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
@@ -1138,6 +1135,7 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 {
 	int rc;
 	struct rte_ipsec_sa_prm prm;
+	struct rte_ipsec_session *ips;
 	struct rte_ipv4_hdr v4  = {
 		.version_ihl = IPVERSION << 4 |
 			sizeof(v4) / RTE_IPV4_IHL_MULTIPLIER,
@@ -1162,7 +1160,10 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 	if (rc < 0)
 		return rc;
 
-	rc = fill_ipsec_session(&lsa->ips, sa, lsa);
+	/* init processing session */
+	ips = ipsec_get_session(lsa);
+	rc = fill_ipsec_session(ips, sa);
+
 	return rc;
 }
 
@@ -1386,6 +1387,7 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 {
 	struct ipsec_sa *rule;
 	uint32_t idx_sa;
+	enum rte_security_session_action_type rule_type;
 
 	*rx_offloads = 0;
 	*tx_offloads = 0;
@@ -1393,8 +1395,9 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	/* Check for inbound rules that use offloads and use this port */
 	for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) {
 		rule = &sa_in[idx_sa];
-		if ((rule->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				rule->type ==
+		rule_type = ipsec_get_action_type(rule);
+		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				rule_type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
 				&& rule->portid == port_id)
 			*rx_offloads |= DEV_RX_OFFLOAD_SECURITY;
@@ -1403,8 +1406,9 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	/* Check for outbound rules that use offloads and use this port */
 	for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) {
 		rule = &sa_out[idx_sa];
-		if ((rule->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-				rule->type ==
+		rule_type = ipsec_get_action_type(rule);
+		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+				rule_type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)
 				&& rule->portid == port_id)
 			*tx_offloads |= DEV_TX_OFFLOAD_SECURITY;
-- 
2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 2/3] examples/ipsec-secgw: add fallback session feature
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 1/3] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
@ 2019-09-04 14:16   ` Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 3/3] examples/ipsec-secgw: add offload fallback tests Marcin Smoczynski
  2019-09-18  6:45   ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Anoob Joseph
  3 siblings, 0 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-09-04 14:16 UTC (permalink / raw)
  To: konstantin.ananyev, akhil.goyal; +Cc: dev, Marcin Smoczynski

Inline processing is limited to a specified subset of traffic. It is
often unable to handle more complicated situations, such as fragmented
traffic. When using inline processing such traffic is dropped.

Introduce multiple sessions per SA allowing to configure a fallback
lookaside session for packets that normally would be dropped.
A fallback session type in the SA configuration by adding 'fallback'
with 'lookaside-none' or 'lookaside-protocol' parameter to determine
type of session.

Fallback session feature is available only when using librte_ipsec.

Signed-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>
---
 doc/guides/sample_app_ug/ipsec_secgw.rst |  17 +++-
 examples/ipsec-secgw/esp.c               |   4 +-
 examples/ipsec-secgw/ipsec-secgw.c       |  16 ++--
 examples/ipsec-secgw/ipsec.c             |  10 +--
 examples/ipsec-secgw/ipsec.h             |  40 +++++++--
 examples/ipsec-secgw/ipsec_process.c     |  85 ++++++++++++------
 examples/ipsec-secgw/sa.c                | 110 +++++++++++++++++++----
 7 files changed, 218 insertions(+), 64 deletions(-)

diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst
index ad2d79e75..9ded5fb70 100644
--- a/doc/guides/sample_app_ug/ipsec_secgw.rst
+++ b/doc/guides/sample_app_ug/ipsec_secgw.rst
@@ -401,7 +401,7 @@ The SA rule syntax is shown as follows:
 .. code-block:: console
 
     sa <dir> <spi> <cipher_algo> <cipher_key> <auth_algo> <auth_key>
-    <mode> <src_ip> <dst_ip> <action_type> <port_id>
+    <mode> <src_ip> <dst_ip> <action_type> <port_id> <fallback>
 
 where each options means:
 
@@ -573,6 +573,21 @@ where each options means:
 
    * *port_id X* X is a valid device number in decimal
 
+ ``<fallback>``
+
+ * Action type for packets that inline processor failed to process.
+
+ * Optional: Yes, by default there is *no fallback* session type.
+
+ * Available options:
+
+   * *lookaside-none*: use automatically chosen cryptodev to process packets
+   * *lookaside-protocol*: lookaside protocol offload to HW accelerator
+
+ * Syntax:
+
+   * *fallback lookaside-none*
+   * *fallback lookaside-protocol*
 
 Example SA rules:
 
diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index c1b49da1e..bfa7ff721 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -155,7 +155,7 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 
 	if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
 			(ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
@@ -234,7 +234,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 	ip_hdr_len = 0;
 
 	ip4 = rte_pktmbuf_mtod(m, struct ip *);
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 0d1fd6af6..641ed3767 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -189,6 +189,7 @@ static uint32_t mtu_size = RTE_ETHER_MTU;
 
 /* application wide librte_ipsec/SA parameters */
 struct app_sa_prm app_sa_prm = {.enable = 0};
+static const char *cfgfile;
 
 struct lcore_rx_queue {
 	uint16_t port_id;
@@ -1462,12 +1463,7 @@ parse_args(int32_t argc, char **argv)
 				print_usage(prgname);
 				return -1;
 			}
-			if (parse_cfg_file(optarg) < 0) {
-				printf("parsing file \"%s\" failed\n",
-					optarg);
-				print_usage(prgname);
-				return -1;
-			}
+			cfgfile = optarg;
 			f_present = 1;
 			break;
 		case 'j':
@@ -2398,6 +2394,14 @@ main(int32_t argc, char **argv)
 	if (ret < 0)
 		rte_exit(EXIT_FAILURE, "Invalid parameters\n");
 
+	/* parse configuration file */
+	if (parse_cfg_file(cfgfile) < 0) {
+		printf("parsing file \"%s\" failed\n",
+			optarg);
+		print_usage(argv[0]);
+		return -1;
+	}
+
 	if ((unprotected_port_mask & enabled_port_mask) !=
 			unprotected_port_mask)
 		rte_exit(EXIT_FAILURE, "Invalid unprotected portmask 0x%x\n",
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 8c60bd84b..8b0441028 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -404,7 +404,7 @@ enqueue_cop(struct cdev_qp *cqp, struct rte_crypto_op *cop)
 
 static inline void
 ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
-		struct rte_mbuf *pkts[], struct ipsec_sa *sas[],
+		struct rte_mbuf *pkts[], void *sas[],
 		uint16_t nb_pkts)
 {
 	int32_t ret = 0, i;
@@ -423,9 +423,9 @@ ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx,
 		rte_prefetch0(pkts[i]);
 
 		priv = get_priv(pkts[i]);
-		sa = sas[i];
+		sa = ipsec_mask_saptr(sas[i]);
 		priv->sa = sa;
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		switch (ips->type) {
 		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
@@ -586,7 +586,7 @@ uint16_t
 ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
 		uint16_t nb_pkts, uint16_t len)
 {
-	struct ipsec_sa *sas[nb_pkts];
+	void *sas[nb_pkts];
 
 	inbound_sa_lookup(ctx->sa_ctx, pkts, sas, nb_pkts);
 
@@ -606,7 +606,7 @@ uint16_t
 ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
 		uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len)
 {
-	struct ipsec_sa *sas[nb_pkts];
+	void *sas[nb_pkts];
 
 	outbound_sa_lookup(ctx->sa_ctx, sa_idx, sas, nb_pkts);
 
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index a4ad81b0e..8e075216c 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -81,12 +81,32 @@ struct app_sa_prm {
 
 extern struct app_sa_prm app_sa_prm;
 
+enum {
+	IPSEC_SESSION_PRIMARY = 0,
+	IPSEC_SESSION_FALLBACK = 1,
+	IPSEC_SESSION_MAX
+};
+
+#define IPSEC_SA_OFFLOAD_FALLBACK_FLAG (1)
+
+static inline struct ipsec_sa *
+ipsec_mask_saptr(void *ptr)
+{
+	uintptr_t i = (uintptr_t)ptr;
+	static const uintptr_t mask = IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
+
+	i &= ~mask;
+
+	return (struct ipsec_sa *)i;
+}
+
 struct ipsec_sa {
-	struct rte_ipsec_session ips; /* one session per sa for now */
+	struct rte_ipsec_session sessions[IPSEC_SESSION_MAX];
 	uint32_t spi;
 	uint32_t cdev_id_qp;
 	uint64_t seq;
 	uint32_t salt;
+	uint32_t fallback_sessions;
 	enum rte_crypto_cipher_algorithm cipher_algo;
 	enum rte_crypto_auth_algorithm auth_algo;
 	enum rte_crypto_aead_algorithm aead_algo;
@@ -210,7 +230,7 @@ struct cnt_blk {
 struct traffic_type {
 	const uint8_t *data[MAX_PKT_BURST * 2];
 	struct rte_mbuf *pkts[MAX_PKT_BURST * 2];
-	struct ipsec_sa *saptr[MAX_PKT_BURST * 2];
+	void *saptr[MAX_PKT_BURST * 2];
 	uint32_t res[MAX_PKT_BURST * 2];
 	uint32_t num;
 };
@@ -278,16 +298,22 @@ get_sym_cop(struct rte_crypto_op *cop)
 }
 
 static inline struct rte_ipsec_session *
-ipsec_get_session(struct ipsec_sa *sa)
+ipsec_get_primary_session(struct ipsec_sa *sa)
+{
+	return &sa->sessions[IPSEC_SESSION_PRIMARY];
+}
+
+static inline struct rte_ipsec_session *
+ipsec_get_fallback_session(struct ipsec_sa *sa)
 {
-	return &sa->ips;
+	return &sa->sessions[IPSEC_SESSION_FALLBACK];
 }
 
 static inline enum rte_security_session_action_type
 ipsec_get_action_type(struct ipsec_sa *sa)
 {
 	struct rte_ipsec_session *ips;
-	ips = ipsec_get_session(sa);
+	ips = ipsec_get_primary_session(sa);
 	return ips->type;
 }
 
@@ -296,11 +322,11 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx);
 
 void
 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts);
+		void *sa[], uint16_t nb_pkts);
 
 void
 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts);
+		void *sa[], uint16_t nb_pkts);
 
 void
 sp4_init(struct socket_ctx *ctx, int32_t socket_id);
diff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c
index 239d81ef6..2eb5c8b34 100644
--- a/examples/ipsec-secgw/ipsec_process.c
+++ b/examples/ipsec-secgw/ipsec_process.c
@@ -18,7 +18,6 @@
 	(((t) & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)) || \
 	((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TUNLV4)
 
-
 /* helper routine to free bulk of packets */
 static inline void
 free_pkts(struct rte_mbuf *mb[], uint32_t n)
@@ -118,7 +117,7 @@ fill_ipsec_session(struct rte_ipsec_session *ss, struct ipsec_ctx *ctx,
  * group input packets byt the SA they belong to.
  */
 static uint32_t
-sa_group(struct ipsec_sa *sa_ptr[], struct rte_mbuf *pkts[],
+sa_group(void *sa_ptr[], struct rte_mbuf *pkts[],
 	struct rte_ipsec_group grp[], uint32_t num)
 {
 	uint32_t i, n, spi;
@@ -185,6 +184,37 @@ copy_to_trf(struct ipsec_traffic *trf, uint64_t satp, struct rte_mbuf *mb[],
 	out->num += num;
 }
 
+static uint32_t
+ipsec_prepare_crypto_group(struct ipsec_ctx *ctx, struct ipsec_sa *sa,
+		struct rte_ipsec_session *ips, struct rte_mbuf **m,
+		unsigned int cnt)
+{
+	struct cdev_qp *cqp;
+	struct rte_crypto_op *cop[cnt];
+	uint32_t j, k;
+	struct ipsec_mbuf_metadata *priv;
+
+	cqp = &ctx->tbl[sa->cdev_id_qp];
+
+	/* for that app each mbuf has it's own crypto op */
+	for (j = 0; j != cnt; j++) {
+		priv = get_priv(m[j]);
+		cop[j] = &priv->cop;
+		/*
+		 * this is just to satisfy inbound_sa_check()
+		 * should be removed in future.
+		 */
+		priv->sa = sa;
+	}
+
+	/* prepare and enqueue crypto ops */
+	k = rte_ipsec_pkt_crypto_prepare(ips, m, cop, cnt);
+	if (k != 0)
+		enqueue_cop_bulk(cqp, cop, k);
+
+	return k;
+}
+
 /*
  * Process ipsec packets.
  * If packet belong to SA that is subject of inline-crypto,
@@ -201,18 +231,15 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 	struct ipsec_mbuf_metadata *priv;
 	struct rte_ipsec_group *pg;
 	struct rte_ipsec_session *ips;
-	struct cdev_qp *cqp;
-	struct rte_crypto_op *cop[RTE_DIM(trf->ipsec.pkts)];
 	struct rte_ipsec_group grp[RTE_DIM(trf->ipsec.pkts)];
 
 	n = sa_group(trf->ipsec.saptr, trf->ipsec.pkts, grp, trf->ipsec.num);
 
 	for (i = 0; i != n; i++) {
-
 		pg = grp + i;
-		sa = pg->id.ptr;
+		sa = ipsec_mask_saptr(pg->id.ptr);
 
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		/* no valid HW session for that SA, try to create one */
 		if (sa == NULL || (ips->crypto.ses == NULL &&
@@ -224,6 +251,7 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 				ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
 
+			/* get SA type */
 			satp = rte_ipsec_sa_type(ips->sa);
 
 			/*
@@ -236,30 +264,33 @@ ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)
 				priv->sa = sa;
 			}
 
-			k = rte_ipsec_pkt_process(ips, pg->m, pg->cnt);
-			copy_to_trf(trf, satp, pg->m, k);
+			/* fallback to cryptodev with RX packets which inline
+			 * processor was unable to process
+			 */
+			if (pg->id.val & IPSEC_SA_OFFLOAD_FALLBACK_FLAG) {
+				/* offload packets to cryptodev */
+				struct rte_ipsec_session *fallback;
+
+				fallback = ipsec_get_fallback_session(sa);
+				if (fallback->crypto.ses == NULL &&
+					fill_ipsec_session(fallback, ctx, sa)
+					!= 0)
+					k = 0;
+				else
+					k = ipsec_prepare_crypto_group(ctx, sa,
+						fallback, pg->m, pg->cnt);
+			} else {
+				/* finish processing of packets successfully
+				 * decrypted by an inline processor
+				 */
+				k = rte_ipsec_pkt_process(ips, pg->m, pg->cnt);
+				copy_to_trf(trf, satp, pg->m, k);
 
+			}
 		/* enqueue packets to crypto dev */
 		} else {
-
-			cqp = &ctx->tbl[sa->cdev_id_qp];
-
-			/* for that app each mbuf has it's own crypto op */
-			for (j = 0; j != pg->cnt; j++) {
-				priv = get_priv(pg->m[j]);
-				cop[j] = &priv->cop;
-				/*
-				 * this is just to satisfy inbound_sa_check()
-				 * should be removed in future.
-				 */
-				priv->sa = sa;
-			}
-
-			/* prepare and enqueue crypto ops */
-			k = rte_ipsec_pkt_crypto_prepare(ips, pg->m, cop,
+			k = ipsec_prepare_crypto_group(ctx, sa, ips, pg->m,
 				pg->cnt);
-			if (k != 0)
-				enqueue_cop_bulk(cqp, cop, k);
 		}
 
 		/* drop packets that cannot be enqueued/processed */
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index a3d8e4545..700d52490 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -31,6 +31,8 @@
 
 #define IP6_FULL_MASK (sizeof(((struct ip_addr *)NULL)->ip.ip6.ip6) * CHAR_BIT)
 
+#define MBUF_NO_SEC_OFFLOAD(m) ((m->ol_flags & PKT_RX_SEC_OFFLOAD) == 0)
+
 struct supported_cipher_algo {
 	const char *keyword;
 	enum rte_crypto_cipher_algorithm algo;
@@ -235,6 +237,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	uint32_t mode_p = 0;
 	uint32_t type_p = 0;
 	uint32_t portid_p = 0;
+	uint32_t fallback_p = 0;
 
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
@@ -245,6 +248,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			return;
 
 		rule = &sa_in[*ri];
+		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
 	} else {
 		ri = &nb_sa_out;
 
@@ -254,6 +258,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			return;
 
 		rule = &sa_out[*ri];
+		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
 	}
 
 	/* spi number */
@@ -263,7 +268,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	if (atoi(tokens[1]) == INVALID_SPI)
 		return;
 	rule->spi = atoi(tokens[1]);
-	ips = ipsec_get_session(rule);
+	ips = ipsec_get_primary_session(rule);
 
 	for (ti = 2; ti < n_tokens; ti++) {
 		if (strcmp(tokens[ti], "mode") == 0) {
@@ -596,6 +601,43 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			continue;
 		}
 
+		if (strcmp(tokens[ti], "fallback") == 0) {
+			struct rte_ipsec_session *fb;
+
+			APP_CHECK(app_sa_prm.enable, status, "Fallback session "
+				"not allowed for legacy mode.");
+			if (status->status < 0)
+				return;
+			APP_CHECK(rule->direction ==
+				RTE_SECURITY_IPSEC_SA_DIR_INGRESS, status,
+				"Fallback session not allowed for egress "
+				"rule");
+			if (status->status < 0)
+				return;
+			APP_CHECK_PRESENCE(fallback_p, tokens[ti], status);
+			if (status->status < 0)
+				return;
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+			fb = ipsec_get_fallback_session(rule);
+			if (strcmp(tokens[ti], "lookaside-none") == 0) {
+				fb->type = RTE_SECURITY_ACTION_TYPE_NONE;
+			} else if (strcmp(tokens[ti], "lookaside-protocol")
+				== 0) {
+				fb->type =
+				RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
+			} else {
+				APP_CHECK(0, status, "unrecognized fallback "
+					"type %s.", tokens[ti]);
+				return;
+			}
+
+			rule->fallback_sessions = 1;
+			fallback_p = 1;
+			continue;
+		}
+
 		/* unrecognizeable input */
 		APP_CHECK(0, status, "unrecognized input \"%s\"",
 			tokens[ti]);
@@ -643,6 +685,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 	uint32_t i;
 	uint8_t a, b, c, d;
 	const struct rte_ipsec_session *ips;
+	const struct rte_ipsec_session *fallback_ips;
 
 	printf("\tspi_%s(%3u):", inbound?"in":"out", sa->spi);
 
@@ -699,7 +742,7 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		break;
 	}
 
-	ips = &sa->ips;
+	ips = &sa->sessions[IPSEC_SESSION_PRIMARY];
 	printf(" type:");
 	switch (ips->type) {
 	case RTE_SECURITY_ACTION_TYPE_NONE:
@@ -715,6 +758,22 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 		printf("lookaside-protocol-offload ");
 		break;
 	}
+
+	fallback_ips = &sa->sessions[IPSEC_SESSION_FALLBACK];
+	if (fallback_ips != NULL && sa->fallback_sessions > 0) {
+		printf("inline fallback:");
+		switch (fallback_ips->type) {
+		case RTE_SECURITY_ACTION_TYPE_NONE:
+			printf("lookaside-none ");
+			break;
+		case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:
+			printf("lookaside-protocol ");
+			break;
+		default:
+			printf("invalid ");
+			break;
+		}
+	}
 	printf("\n");
 }
 
@@ -896,7 +955,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 		}
 		*sa = entries[i];
 		sa->seq = 0;
-		ips = ipsec_get_session(sa);
+		ips = ipsec_get_primary_session(sa);
 
 		if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
 			ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
@@ -904,9 +963,6 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 				return -EINVAL;
 		}
 
-		sa->direction = (inbound == 1) ?
-				RTE_SECURITY_IPSEC_SA_DIR_INGRESS :
-				RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
 
 		switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
 		case IP4_TUNNEL:
@@ -946,7 +1002,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			sa->xforms = &sa_ctx->xf[idx].a;
 
-			ips = ipsec_get_session(sa);
+			ips = ipsec_get_primary_session(sa);
 			if (ips->type ==
 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL ||
 				ips->type ==
@@ -1160,9 +1216,15 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
 	if (rc < 0)
 		return rc;
 
-	/* init processing session */
-	ips = ipsec_get_session(lsa);
+	/* init primary processing session */
+	ips = ipsec_get_primary_session(lsa);
 	rc = fill_ipsec_session(ips, sa);
+	if (rc != 0)
+		return rc;
+
+	/* init inline fallback processing session */
+	if (lsa->fallback_sessions == 1)
+		rc = fill_ipsec_session(ipsec_get_fallback_session(lsa), sa);
 
 	return rc;
 }
@@ -1318,13 +1380,14 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)
 
 static inline void
 single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
-		struct ipsec_sa **sa_ret)
+		void **sa_ret)
 {
 	struct rte_esp_hdr *esp;
 	struct ip *ip;
 	uint32_t *src4_addr;
 	uint8_t *src6_addr;
 	struct ipsec_sa *sa;
+	void *result_sa;
 
 	*sa_ret = NULL;
 
@@ -1334,33 +1397,48 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
 	if (esp->spi == INVALID_SPI)
 		return;
 
-	sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
+	result_sa = sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
 	if (rte_be_to_cpu_32(esp->spi) != sa->spi)
 		return;
 
+	/*
+	 * Mark need for inline offload fallback on the LSB of SA pointer.
+	 * Thanks to packet grouping mechanism which ipsec_process is using
+	 * packets marked for fallback processing will form separate group.
+	 *
+	 * Because it is not safe to use SA pointer it is casted to generic
+	 * pointer to prevent from unintentional use. Use ipsec_mask_saptr
+	 * to get valid struct pointer.
+	 */
+	if (MBUF_NO_SEC_OFFLOAD(pkt) && sa->fallback_sessions > 0) {
+		uintptr_t intsa = (uintptr_t)sa;
+		intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
+		result_sa = (void *)intsa;
+	}
+
 	switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
 	case IP4_TUNNEL:
 		src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src));
 		if ((ip->ip_v == IPVERSION) &&
 				(sa->src.ip.ip4 == *src4_addr) &&
 				(sa->dst.ip.ip4 == *(src4_addr + 1)))
-			*sa_ret = sa;
+			*sa_ret = result_sa;
 		break;
 	case IP6_TUNNEL:
 		src6_addr = RTE_PTR_ADD(ip, offsetof(struct ip6_hdr, ip6_src));
 		if ((ip->ip_v == IP6_VERSION) &&
 				!memcmp(&sa->src.ip.ip6.ip6, src6_addr, 16) &&
 				!memcmp(&sa->dst.ip.ip6.ip6, src6_addr + 16, 16))
-			*sa_ret = sa;
+			*sa_ret = result_sa;
 		break;
 	case TRANSPORT:
-		*sa_ret = sa;
+		*sa_ret = result_sa;
 	}
 }
 
 void
 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts)
+		void *sa[], uint16_t nb_pkts)
 {
 	uint32_t i;
 
@@ -1370,7 +1448,7 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
 
 void
 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
-		struct ipsec_sa *sa[], uint16_t nb_pkts)
+		void *sa[], uint16_t nb_pkts)
 {
 	uint32_t i;
 
-- 
2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 3/3] examples/ipsec-secgw: add offload fallback tests
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 1/3] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 2/3] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
@ 2019-09-04 14:16   ` Marcin Smoczynski
  2019-09-18  6:45   ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Anoob Joseph
  3 siblings, 0 replies; 14+ messages in thread
From: Marcin Smoczynski @ 2019-09-04 14:16 UTC (permalink / raw)
  To: konstantin.ananyev, akhil.goyal; +Cc: dev, Marcin Smoczynski

Add tests for offload fallback feature; add inbound config modificator
SGW_CFG_XPRM_IN (offload fallback setting can be set only for inbound
SAs). Tests are using cryptodev for outbound SA.

To test fragmentation with QAT set:
MULTI_SEG_TEST="--reassemble=4096 --cryptodev_mask=0x5555"

Signed-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>
---
 examples/ipsec-secgw/test/trs_aesgcm_common_defs.sh         | 4 ++--
 .../test/trs_aesgcm_inline_crypto_fallback_defs.sh          | 5 +++++
 examples/ipsec-secgw/test/tun_aesgcm_common_defs.sh         | 6 ++++--
 .../test/tun_aesgcm_inline_crypto_fallback_defs.sh          | 5 +++++
 4 files changed, 16 insertions(+), 4 deletions(-)
 create mode 100644 examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
 create mode 100644 examples/ipsec-secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh

diff --git a/examples/ipsec-secgw/test/trs_aesgcm_common_defs.sh b/examples/ipsec-secgw/test/trs_aesgcm_common_defs.sh
index f6c5bf5a7..17f2f86d2 100644
--- a/examples/ipsec-secgw/test/trs_aesgcm_common_defs.sh
+++ b/examples/ipsec-secgw/test/trs_aesgcm_common_defs.sh
@@ -29,11 +29,11 @@ sp ipv6 out esp bypass pri 1 sport 0:65535 dport 0:65535
 #SA in rules
 sa in 7 aead_algo aes-128-gcm \
 aead_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \
-mode transport ${SGW_CFG_XPRM}
+mode transport ${SGW_CFG_XPRM} ${SGW_CFG_XPRM_IN}
 
 sa in 9 aead_algo aes-128-gcm \
 aead_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \
-mode transport ${SGW_CFG_XPRM}
+mode transport ${SGW_CFG_XPRM} ${SGW_CFG_XPRM_IN}
 
 #SA out rules
 sa out 7 aead_algo aes-128-gcm \
diff --git a/examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh b/examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
new file mode 100644
index 000000000..875a7457d
--- /dev/null
+++ b/examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
@@ -0,0 +1,5 @@
+#! /bin/bash
+
+. ${DIR}/trs_aesgcm_defs.sh
+
+SGW_CFG_XPRM_IN='port_id 0 type inline-crypto-offload fallback lookaside-none'
diff --git a/examples/ipsec-secgw/test/tun_aesgcm_common_defs.sh b/examples/ipsec-secgw/test/tun_aesgcm_common_defs.sh
index 278377967..7490baded 100644
--- a/examples/ipsec-secgw/test/tun_aesgcm_common_defs.sh
+++ b/examples/ipsec-secgw/test/tun_aesgcm_common_defs.sh
@@ -29,11 +29,13 @@ sp ipv6 out esp bypass pri 1 sport 0:65535 dport 0:65535
 #SA in rules
 sa in 7 aead_algo aes-128-gcm \
 aead_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \
-mode ipv4-tunnel src ${REMOTE_IPV4} dst ${LOCAL_IPV4} ${SGW_CFG_XPRM}
+mode ipv4-tunnel src ${REMOTE_IPV4} dst ${LOCAL_IPV4} ${SGW_CFG_XPRM} \
+${SGW_CFG_XPRM_IN}
 
 sa in 9 aead_algo aes-128-gcm \
 aead_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \
-mode ipv6-tunnel src ${REMOTE_IPV6} dst ${LOCAL_IPV6} ${SGW_CFG_XPRM}
+mode ipv6-tunnel src ${REMOTE_IPV6} dst ${LOCAL_IPV6} ${SGW_CFG_XPRM} \
+${SGW_CFG_XPRM_IN}
 
 #SA out rules
 sa out 7 aead_algo aes-128-gcm \
diff --git a/examples/ipsec-secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh b/examples/ipsec-secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
new file mode 100644
index 000000000..696848432
--- /dev/null
+++ b/examples/ipsec-secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
@@ -0,0 +1,5 @@
+#! /bin/bash
+
+. ${DIR}/tun_aesgcm_defs.sh
+
+SGW_CFG_XPRM_IN='port_id 0 type inline-crypto-offload fallback lookaside-none'
-- 
2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
                     ` (2 preceding siblings ...)
  2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 3/3] examples/ipsec-secgw: add offload fallback tests Marcin Smoczynski
@ 2019-09-18  6:45   ` Anoob Joseph
  2019-09-18  8:46     ` Ananyev, Konstantin
  3 siblings, 1 reply; 14+ messages in thread
From: Anoob Joseph @ 2019-09-18  6:45 UTC (permalink / raw)
  To: Marcin Smoczynski, konstantin.ananyev, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti

Hi Marcin,

Sorry for the late response. But how do you plan to handle "inline protocol" processed packets? 

Thanks,
Anoob

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> Sent: Wednesday, September 4, 2019 7:47 PM
> To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; Marcin Smoczynski <marcinx.smoczynski@intel.com>
> Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback
> session
> 
> Inline processing is limited to a specified subset of traffic. It is often unable to
> handle more complicated situations, such as fragmented traffic. When using
> inline processing such traffic is dropped.
> 
> Introduce multiple sessions per SA allowing to configure a fallback lookaside
> session for packets that normally would be dropped.
> A fallback session type in the SA configuration by adding 'fallback'
> with 'lookaside-none' or 'lookaside-protocol' parameter to determine type of
> session.
> 
> Fallback session feature is available only when using librte_ipsec.
> 
> v1 to v2 changes:
>  - disable fallback offload for outbound SAs
>  - add test scripts
> 
> Marcin Smoczynski (3):
>   examples/ipsec-secgw: ipsec_sa structure cleanup
>   examples/ipsec-secgw: add fallback session feature
>   examples/ipsec-secgw: add offload fallback tests
> 
>  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
>  examples/ipsec-secgw/esp.c                    |  35 ++--
>  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
>  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
>  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
>  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
>  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
>  .../test/trs_aesgcm_common_defs.sh            |   4 +-
>  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
>  .../test/tun_aesgcm_common_defs.sh            |   6 +-
>  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
>  11 files changed, 358 insertions(+), 167 deletions(-)  create mode 100644
> examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
>  create mode 100644 examples/ipsec-
> secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> 
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-18  6:45   ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Anoob Joseph
@ 2019-09-18  8:46     ` Ananyev, Konstantin
  2019-09-18 11:40       ` Anoob Joseph
  0 siblings, 1 reply; 14+ messages in thread
From: Ananyev, Konstantin @ 2019-09-18  8:46 UTC (permalink / raw)
  To: Anoob Joseph, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti


Hi Anoob,

> 
> Hi Marcin,
> 
> Sorry for the late response. But how do you plan to handle "inline protocol" processed packets?

Right now that feature is supported for "inline crypto" only.
For the case when SA doesn't enable replay window and/or ESN
current patch should also work for "inline proto" too,
but this is just my understanding (not tested, etc.). 
Konstantin

> 
> Thanks,
> Anoob
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> > Sent: Wednesday, September 4, 2019 7:47 PM
> > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > Cc: dev@dpdk.org; Marcin Smoczynski <marcinx.smoczynski@intel.com>
> > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback
> > session
> >
> > Inline processing is limited to a specified subset of traffic. It is often unable to
> > handle more complicated situations, such as fragmented traffic. When using
> > inline processing such traffic is dropped.
> >
> > Introduce multiple sessions per SA allowing to configure a fallback lookaside
> > session for packets that normally would be dropped.
> > A fallback session type in the SA configuration by adding 'fallback'
> > with 'lookaside-none' or 'lookaside-protocol' parameter to determine type of
> > session.
> >
> > Fallback session feature is available only when using librte_ipsec.
> >
> > v1 to v2 changes:
> >  - disable fallback offload for outbound SAs
> >  - add test scripts
> >
> > Marcin Smoczynski (3):
> >   examples/ipsec-secgw: ipsec_sa structure cleanup
> >   examples/ipsec-secgw: add fallback session feature
> >   examples/ipsec-secgw: add offload fallback tests
> >
> >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> >  examples/ipsec-secgw/esp.c                    |  35 ++--
> >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> >  11 files changed, 358 insertions(+), 167 deletions(-)  create mode 100644
> > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
> >  create mode 100644 examples/ipsec-
> > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> >
> > --
> > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-18  8:46     ` Ananyev, Konstantin
@ 2019-09-18 11:40       ` Anoob Joseph
  2019-09-18 22:19         ` Ananyev, Konstantin
  0 siblings, 1 reply; 14+ messages in thread
From: Anoob Joseph @ 2019-09-18 11:40 UTC (permalink / raw)
  To: Ananyev, Konstantin, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti

Hi Konstantin,

Please see inline.

Thanks,
Anoob

> -----Original Message-----
> From: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Sent: Wednesday, September 18, 2019 2:16 PM
> To: Anoob Joseph <anoobj@marvell.com>; Smoczynski, MarcinX
> <marcinx.smoczynski@intel.com>; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; Narayana Prasad Raju Athreya <pathreya@marvell.com>;
> Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Archana Muniganti
> <marchana@marvell.com>
> Subject: RE: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback
> session
> 
> 
> Hi Anoob,
> 
> >
> > Hi Marcin,
> >
> > Sorry for the late response. But how do you plan to handle "inline protocol"
> processed packets?
> 
> Right now that feature is supported for "inline crypto" only.

[Anoob] The description says "inline processed" packets. Hence the confusion.
 
> For the case when SA doesn't enable replay window and/or ESN current
> patch should also work for "inline proto" too, but this is just my
> understanding (not tested, etc.).

[Anoob] In case of inline ipsec processing, the ipsec state (which would track sequence number etc) will be internal to the PMDs. So anti-replay/ESN would have to be done either in the h/w or PMD. This would mean application will not have state information regarding ipsec processing. Hence fallback handling with the above scheme will not work in that case.

To address this properly for inline protocol, we will have to come up with some logic to share session private data b/w "eligible" PMDs. This would involve library changes to rte_security, etc. Once that is proposed, there will be one kind of handling for inline protocol processing and another kind for inline crypto processing. Would you be fine with that?
 
> Konstantin
> 
> >
> > Thanks,
> > Anoob
> >
> > > -----Original Message-----
> > > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> > > Sent: Wednesday, September 4, 2019 7:47 PM
> > > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > > Cc: dev@dpdk.org; Marcin Smoczynski <marcinx.smoczynski@intel.com>
> > > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add
> > > fallback session
> > >
> > > Inline processing is limited to a specified subset of traffic. It is
> > > often unable to handle more complicated situations, such as
> > > fragmented traffic. When using inline processing such traffic is dropped.
> > >
> > > Introduce multiple sessions per SA allowing to configure a fallback
> > > lookaside session for packets that normally would be dropped.
> > > A fallback session type in the SA configuration by adding 'fallback'
> > > with 'lookaside-none' or 'lookaside-protocol' parameter to determine
> > > type of session.
> > >
> > > Fallback session feature is available only when using librte_ipsec.
> > >
> > > v1 to v2 changes:
> > >  - disable fallback offload for outbound SAs
> > >  - add test scripts
> > >
> > > Marcin Smoczynski (3):
> > >   examples/ipsec-secgw: ipsec_sa structure cleanup
> > >   examples/ipsec-secgw: add fallback session feature
> > >   examples/ipsec-secgw: add offload fallback tests
> > >
> > >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> > >  examples/ipsec-secgw/esp.c                    |  35 ++--
> > >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> > >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> > >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> > >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> > >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> > >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> > >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> > >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > >  11 files changed, 358 insertions(+), 167 deletions(-)  create mode
> > > 100644
> > > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
> > >  create mode 100644 examples/ipsec-
> > > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> > >
> > > --
> > > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-18 11:40       ` Anoob Joseph
@ 2019-09-18 22:19         ` Ananyev, Konstantin
  2019-09-19  2:50           ` Anoob Joseph
  0 siblings, 1 reply; 14+ messages in thread
From: Ananyev, Konstantin @ 2019-09-18 22:19 UTC (permalink / raw)
  To: Anoob Joseph, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti



Hi Anoob,

> > > Sorry for the late response. But how do you plan to handle "inline protocol"
> > processed packets?
> >
> > Right now that feature is supported for "inline crypto" only.
> 
> [Anoob] The description says "inline processed" packets. Hence the confusion.
> 
> > For the case when SA doesn't enable replay window and/or ESN current
> > patch should also work for "inline proto" too, but this is just my
> > understanding (not tested, etc.).
> 
> [Anoob] In case of inline ipsec processing, the ipsec state (which would track sequence number etc) will be internal to the PMDs. So anti-
> replay/ESN would have to be done either in the h/w or PMD. This would mean application will not have state information regarding ipsec
> processing. Hence fallback handling with the above scheme will not work in that case.

Agree, that's why I wrote above that current wok might work for inline-proto
*only* if replay window and ESN is disabled. 

> 
> To address this properly for inline protocol, we will have to come up with some logic to share session private data b/w "eligible" PMDs. This
> would involve library changes to rte_security, etc.

Again, totally agree.
As I remember we already discussed it about a year ago, but didn't come up with any concrete proposal.

> Once that is proposed, there will be one kind of handling for inline protocol processing
> and another kind for inline crypto processing. Would you be fine with that?

For sure something needs to be changed for inline-proto to sync replay-window/ESN related data
between HW/PMD and SW. 
What it should be - new function, or something else - hard to tell right now. 
Konstantin

> 
> > Konstantin
> >
> > >
> > > Thanks,
> > > Anoob
> > >
> > > > -----Original Message-----
> > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> > > > Sent: Wednesday, September 4, 2019 7:47 PM
> > > > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > > > Cc: dev@dpdk.org; Marcin Smoczynski <marcinx.smoczynski@intel.com>
> > > > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add
> > > > fallback session
> > > >
> > > > Inline processing is limited to a specified subset of traffic. It is
> > > > often unable to handle more complicated situations, such as
> > > > fragmented traffic. When using inline processing such traffic is dropped.
> > > >
> > > > Introduce multiple sessions per SA allowing to configure a fallback
> > > > lookaside session for packets that normally would be dropped.
> > > > A fallback session type in the SA configuration by adding 'fallback'
> > > > with 'lookaside-none' or 'lookaside-protocol' parameter to determine
> > > > type of session.
> > > >
> > > > Fallback session feature is available only when using librte_ipsec.
> > > >
> > > > v1 to v2 changes:
> > > >  - disable fallback offload for outbound SAs
> > > >  - add test scripts
> > > >
> > > > Marcin Smoczynski (3):
> > > >   examples/ipsec-secgw: ipsec_sa structure cleanup
> > > >   examples/ipsec-secgw: add fallback session feature
> > > >   examples/ipsec-secgw: add offload fallback tests
> > > >
> > > >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> > > >  examples/ipsec-secgw/esp.c                    |  35 ++--
> > > >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> > > >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> > > >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> > > >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> > > >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> > > >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> > > >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> > > >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > >  11 files changed, 358 insertions(+), 167 deletions(-)  create mode
> > > > 100644
> > > > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs.sh
> > > >  create mode 100644 examples/ipsec-
> > > > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> > > >
> > > > --
> > > > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-18 22:19         ` Ananyev, Konstantin
@ 2019-09-19  2:50           ` Anoob Joseph
  2019-09-19  7:33             ` Ananyev, Konstantin
  0 siblings, 1 reply; 14+ messages in thread
From: Anoob Joseph @ 2019-09-19  2:50 UTC (permalink / raw)
  To: Ananyev, Konstantin, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti

Hi Konstantin, 

Please see inline.

Thanks,
Anoob

> -----Original Message-----
> From: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Sent: Thursday, September 19, 2019 3:49 AM
> To: Anoob Joseph <anoobj@marvell.com>; Smoczynski, MarcinX
> <marcinx.smoczynski@intel.com>; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; Narayana Prasad Raju Athreya <pathreya@marvell.com>;
> Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Archana Muniganti
> <marchana@marvell.com>
> Subject: RE: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback
> session
> 
> 
> 
> Hi Anoob,
> 
> > > > Sorry for the late response. But how do you plan to handle "inline
> protocol"
> > > processed packets?
> > >
> > > Right now that feature is supported for "inline crypto" only.
> >
> > [Anoob] The description says "inline processed" packets. Hence the confusion.
> >
> > > For the case when SA doesn't enable replay window and/or ESN current
> > > patch should also work for "inline proto" too, but this is just my
> > > understanding (not tested, etc.).
> >
> > [Anoob] In case of inline ipsec processing, the ipsec state (which
> > would track sequence number etc) will be internal to the PMDs. So
> > anti- replay/ESN would have to be done either in the h/w or PMD. This would
> mean application will not have state information regarding ipsec processing.
> Hence fallback handling with the above scheme will not work in that case.
> 
> Agree, that's why I wrote above that current wok might work for inline-proto
> *only* if replay window and ESN is disabled.

[Anoob] Any feature that makes use of protocol "state" would fail with this scheme. In case of inline ipsec, that is anti-replay & ESN. I see that you are not planning for fallback session for outbound. If at all that is planned, this scheme will fail to co-ordinate sequence number between original and fallback sessions.

> 
> >
> > To address this properly for inline protocol, we will have to come up
> > with some logic to share session private data b/w "eligible" PMDs. This would
> involve library changes to rte_security, etc.
> 
> Again, totally agree.
> As I remember we already discussed it about a year ago, but didn't come up with
> any concrete proposal.
> 
> > Once that is proposed, there will be one kind of handling for inline
> > protocol processing and another kind for inline crypto processing. Would you
> be fine with that?
> 
> For sure something needs to be changed for inline-proto to sync replay-
> window/ESN related data between HW/PMD and SW.
> What it should be - new function, or something else - hard to tell right now.

[Anoob] No disagreement. My only concern is the incompleteness of this solution. We will have to propose a totally new scheme for inline protocol. You do agree that this approach will not help inline protocol offloading, right? If you are okay with having different solutions for inline crypto & inline protocol, I don't have any issue with this series.

Also, how do you plan to pass "state" info to lookaside protocol session? That will be required to handle ESN/anti-replay in lookaside protocol capable PMD as well.
 
> Konstantin
> 
> >
> > > Konstantin
> > >
> > > >
> > > > Thanks,
> > > > Anoob
> > > >
> > > > > -----Original Message-----
> > > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> > > > > Sent: Wednesday, September 4, 2019 7:47 PM
> > > > > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > > > > Cc: dev@dpdk.org; Marcin Smoczynski
> > > > > <marcinx.smoczynski@intel.com>
> > > > > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add
> > > > > fallback session
> > > > >
> > > > > Inline processing is limited to a specified subset of traffic.
> > > > > It is often unable to handle more complicated situations, such
> > > > > as fragmented traffic. When using inline processing such traffic is
> dropped.
> > > > >
> > > > > Introduce multiple sessions per SA allowing to configure a
> > > > > fallback lookaside session for packets that normally would be dropped.
> > > > > A fallback session type in the SA configuration by adding 'fallback'
> > > > > with 'lookaside-none' or 'lookaside-protocol' parameter to
> > > > > determine type of session.
> > > > >
> > > > > Fallback session feature is available only when using librte_ipsec.
> > > > >
> > > > > v1 to v2 changes:
> > > > >  - disable fallback offload for outbound SAs
> > > > >  - add test scripts
> > > > >
> > > > > Marcin Smoczynski (3):
> > > > >   examples/ipsec-secgw: ipsec_sa structure cleanup
> > > > >   examples/ipsec-secgw: add fallback session feature
> > > > >   examples/ipsec-secgw: add offload fallback tests
> > > > >
> > > > >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> > > > >  examples/ipsec-secgw/esp.c                    |  35 ++--
> > > > >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> > > > >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> > > > >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> > > > >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> > > > >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> > > > >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> > > > >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> > > > >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > >  11 files changed, 358 insertions(+), 167 deletions(-)  create
> > > > > mode
> > > > > 100644
> > > > > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs
> > > > > .sh  create mode 100644 examples/ipsec-
> > > > > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> > > > >
> > > > > --
> > > > > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-19  2:50           ` Anoob Joseph
@ 2019-09-19  7:33             ` Ananyev, Konstantin
  2019-09-19 10:53               ` Anoob Joseph
  0 siblings, 1 reply; 14+ messages in thread
From: Ananyev, Konstantin @ 2019-09-19  7:33 UTC (permalink / raw)
  To: Anoob Joseph, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti


Hi Anoob,

> > > > > Sorry for the late response. But how do you plan to handle "inline
> > protocol"
> > > > processed packets?
> > > >
> > > > Right now that feature is supported for "inline crypto" only.
> > >
> > > [Anoob] The description says "inline processed" packets. Hence the confusion.
> > >
> > > > For the case when SA doesn't enable replay window and/or ESN current
> > > > patch should also work for "inline proto" too, but this is just my
> > > > understanding (not tested, etc.).
> > >
> > > [Anoob] In case of inline ipsec processing, the ipsec state (which
> > > would track sequence number etc) will be internal to the PMDs. So
> > > anti- replay/ESN would have to be done either in the h/w or PMD. This would
> > mean application will not have state information regarding ipsec processing.
> > Hence fallback handling with the above scheme will not work in that case.
> >
> > Agree, that's why I wrote above that current wok might work for inline-proto
> > *only* if replay window and ESN is disabled.
> 
> [Anoob] Any feature that makes use of protocol "state" would fail with this scheme. In case of inline ipsec, that is anti-replay & ESN. I see
> that you are not planning for fallback session for outbound. If at all that is planned, this scheme will fail to co-ordinate sequence number
> between original and fallback sessions.

Right now we don't do outbound fallback sessions.
Again, similar scheme would work for TX with lookaside-none and inline-crypto, but not for inline/lookaside-proto.
Of course few extra changes would be needed - move fragmentation before ipsec processing part. 

> 
> >
> > >
> > > To address this properly for inline protocol, we will have to come up
> > > with some logic to share session private data b/w "eligible" PMDs. This would
> > involve library changes to rte_security, etc.
> >
> > Again, totally agree.
> > As I remember we already discussed it about a year ago, but didn't come up with
> > any concrete proposal.
> >
> > > Once that is proposed, there will be one kind of handling for inline
> > > protocol processing and another kind for inline crypto processing. Would you
> > be fine with that?
> >
> > For sure something needs to be changed for inline-proto to sync replay-
> > window/ESN related data between HW/PMD and SW.
> > What it should be - new function, or something else - hard to tell right now.
> 
> [Anoob] No disagreement. My only concern is the incompleteness of this solution.
> We will have to propose a totally new scheme for inline
> protocol.

Sure, looking forward for it.
In fact, I asked these questions a year ago but as I said before there was no progress on that.

> You do agree that this approach will not help inline protocol offloading, right?

Yes, see above.

> If you are okay with having different solutions for
> inline crypto & inline protocol, I don't have any issue with this series.
> 
> Also, how do you plan to pass "state" info to lookaside protocol session? That will be required to handle ESN/anti-replay in lookaside
> protocol capable PMD as well.

Obviously there is no such API for any *-proto devices, see above.
Not sure why do you keep repeating it, I already agreed with you, see above :)
Just to summarize:
1. Yes I think for lookaiside/iniline-proto devices there is a need for some extra API
    to sync session state between HW and SW.
   Right now, I don't have a clear idea how exactly it should look like.
2. Intel team doesn't plan to work on this API right now.
3. I am happy to review with what you guys will come-up with and provide my feedback.  
Hope that makes things clear.
Konstantin

> 
> > Konstantin
> >
> > >
> > > > Konstantin
> > > >
> > > > >
> > > > > Thanks,
> > > > > Anoob
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin Smoczynski
> > > > > > Sent: Wednesday, September 4, 2019 7:47 PM
> > > > > > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > > > > > Cc: dev@dpdk.org; Marcin Smoczynski
> > > > > > <marcinx.smoczynski@intel.com>
> > > > > > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add
> > > > > > fallback session
> > > > > >
> > > > > > Inline processing is limited to a specified subset of traffic.
> > > > > > It is often unable to handle more complicated situations, such
> > > > > > as fragmented traffic. When using inline processing such traffic is
> > dropped.
> > > > > >
> > > > > > Introduce multiple sessions per SA allowing to configure a
> > > > > > fallback lookaside session for packets that normally would be dropped.
> > > > > > A fallback session type in the SA configuration by adding 'fallback'
> > > > > > with 'lookaside-none' or 'lookaside-protocol' parameter to
> > > > > > determine type of session.
> > > > > >
> > > > > > Fallback session feature is available only when using librte_ipsec.
> > > > > >
> > > > > > v1 to v2 changes:
> > > > > >  - disable fallback offload for outbound SAs
> > > > > >  - add test scripts
> > > > > >
> > > > > > Marcin Smoczynski (3):
> > > > > >   examples/ipsec-secgw: ipsec_sa structure cleanup
> > > > > >   examples/ipsec-secgw: add fallback session feature
> > > > > >   examples/ipsec-secgw: add offload fallback tests
> > > > > >
> > > > > >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> > > > > >  examples/ipsec-secgw/esp.c                    |  35 ++--
> > > > > >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> > > > > >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> > > > > >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> > > > > >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> > > > > >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> > > > > >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> > > > > >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > > >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> > > > > >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > > >  11 files changed, 358 insertions(+), 167 deletions(-)  create
> > > > > > mode
> > > > > > 100644
> > > > > > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_defs
> > > > > > .sh  create mode 100644 examples/ipsec-
> > > > > > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> > > > > >
> > > > > > --
> > > > > > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session
  2019-09-19  7:33             ` Ananyev, Konstantin
@ 2019-09-19 10:53               ` Anoob Joseph
  0 siblings, 0 replies; 14+ messages in thread
From: Anoob Joseph @ 2019-09-19 10:53 UTC (permalink / raw)
  To: Ananyev, Konstantin, Smoczynski, MarcinX, akhil.goyal
  Cc: dev, Narayana Prasad Raju Athreya, Jerin Jacob Kollanukkaran,
	Archana Muniganti

Hi Konstantin,

Please see inline.

Thanks,
Anoob

> -----Original Message-----
> From: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Sent: Thursday, September 19, 2019 1:04 PM
> To: Anoob Joseph <anoobj@marvell.com>; Smoczynski, MarcinX
> <marcinx.smoczynski@intel.com>; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; Narayana Prasad Raju Athreya <pathreya@marvell.com>;
> Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Archana Muniganti
> <marchana@marvell.com>
> Subject: RE: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback
> session
> 
> 
> Hi Anoob,
> 
> > > > > > Sorry for the late response. But how do you plan to handle
> > > > > > "inline
> > > protocol"
> > > > > processed packets?
> > > > >
> > > > > Right now that feature is supported for "inline crypto" only.
> > > >
> > > > [Anoob] The description says "inline processed" packets. Hence the
> confusion.
> > > >
> > > > > For the case when SA doesn't enable replay window and/or ESN
> > > > > current patch should also work for "inline proto" too, but this
> > > > > is just my understanding (not tested, etc.).
> > > >
> > > > [Anoob] In case of inline ipsec processing, the ipsec state (which
> > > > would track sequence number etc) will be internal to the PMDs. So
> > > > anti- replay/ESN would have to be done either in the h/w or PMD.
> > > > This would
> > > mean application will not have state information regarding ipsec processing.
> > > Hence fallback handling with the above scheme will not work in that case.
> > >
> > > Agree, that's why I wrote above that current wok might work for
> > > inline-proto
> > > *only* if replay window and ESN is disabled.
> >
> > [Anoob] Any feature that makes use of protocol "state" would fail with
> > this scheme. In case of inline ipsec, that is anti-replay & ESN. I see
> > that you are not planning for fallback session for outbound. If at all that is
> planned, this scheme will fail to co-ordinate sequence number between original
> and fallback sessions.
> 
> Right now we don't do outbound fallback sessions.
> Again, similar scheme would work for TX with lookaside-none and inline-crypto,
> but not for inline/lookaside-proto.
> Of course few extra changes would be needed - move fragmentation before
> ipsec processing part.

[Anoob] Understood.
 
> 
> >
> > >
> > > >
> > > > To address this properly for inline protocol, we will have to come
> > > > up with some logic to share session private data b/w "eligible"
> > > > PMDs. This would
> > > involve library changes to rte_security, etc.
> > >
> > > Again, totally agree.
> > > As I remember we already discussed it about a year ago, but didn't
> > > come up with any concrete proposal.
> > >
> > > > Once that is proposed, there will be one kind of handling for
> > > > inline protocol processing and another kind for inline crypto
> > > > processing. Would you
> > > be fine with that?
> > >
> > > For sure something needs to be changed for inline-proto to sync
> > > replay- window/ESN related data between HW/PMD and SW.
> > > What it should be - new function, or something else - hard to tell right now.
> >
> > [Anoob] No disagreement. My only concern is the incompleteness of this
> solution.
> > We will have to propose a totally new scheme for inline protocol.
> 
> Sure, looking forward for it.
> In fact, I asked these questions a year ago but as I said before there was no
> progress on that.
> 
> > You do agree that this approach will not help inline protocol offloading, right?
> 
> Yes, see above.
> 
> > If you are okay with having different solutions for inline crypto &
> > inline protocol, I don't have any issue with this series.
> >
> > Also, how do you plan to pass "state" info to lookaside protocol
> > session? That will be required to handle ESN/anti-replay in lookaside protocol
> capable PMD as well.
> 
> Obviously there is no such API for any *-proto devices, see above.
> Not sure why do you keep repeating it, I already agreed with you, see above :)
> Just to summarize:
> 1. Yes I think for lookaiside/iniline-proto devices there is a need for some extra
> API
>     to sync session state between HW and SW.
>    Right now, I don't have a clear idea how exactly it should look like.
> 2. Intel team doesn't plan to work on this API right now.
> 3. I am happy to review with what you guys will come-up with and provide my
> feedback.
> Hope that makes things clear.

[Anoob] My apologies if the queries seemed repetitive. I guess all my concerns are answered. Please do update the logs (and description) to state limitations regarding protocol offloads. I would suggest using "inline crypto processing" instead of "inline processing" wherever applicable. Also, if lookaside protocol is mentioned, better state that the "protocol state" will have to be maintained by application (or lib ipsec in case of lookaside ipsec offload).
 
> Konstantin
> 
> >
> > > Konstantin
> > >
> > > >
> > > > > Konstantin
> > > > >
> > > > > >
> > > > > > Thanks,
> > > > > > Anoob
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Marcin
> > > > > > > Smoczynski
> > > > > > > Sent: Wednesday, September 4, 2019 7:47 PM
> > > > > > > To: konstantin.ananyev@intel.com; akhil.goyal@nxp.com
> > > > > > > Cc: dev@dpdk.org; Marcin Smoczynski
> > > > > > > <marcinx.smoczynski@intel.com>
> > > > > > > Subject: [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add
> > > > > > > fallback session
> > > > > > >
> > > > > > > Inline processing is limited to a specified subset of traffic.
> > > > > > > It is often unable to handle more complicated situations,
> > > > > > > such as fragmented traffic. When using inline processing
> > > > > > > such traffic is
> > > dropped.
> > > > > > >
> > > > > > > Introduce multiple sessions per SA allowing to configure a
> > > > > > > fallback lookaside session for packets that normally would be
> dropped.
> > > > > > > A fallback session type in the SA configuration by adding 'fallback'
> > > > > > > with 'lookaside-none' or 'lookaside-protocol' parameter to
> > > > > > > determine type of session.
> > > > > > >
> > > > > > > Fallback session feature is available only when using librte_ipsec.
> > > > > > >
> > > > > > > v1 to v2 changes:
> > > > > > >  - disable fallback offload for outbound SAs
> > > > > > >  - add test scripts
> > > > > > >
> > > > > > > Marcin Smoczynski (3):
> > > > > > >   examples/ipsec-secgw: ipsec_sa structure cleanup
> > > > > > >   examples/ipsec-secgw: add fallback session feature
> > > > > > >   examples/ipsec-secgw: add offload fallback tests
> > > > > > >
> > > > > > >  doc/guides/sample_app_ug/ipsec_secgw.rst      |  17 +-
> > > > > > >  examples/ipsec-secgw/esp.c                    |  35 ++--
> > > > > > >  examples/ipsec-secgw/ipsec-secgw.c            |  16 +-
> > > > > > >  examples/ipsec-secgw/ipsec.c                  |  99 ++++++-----
> > > > > > >  examples/ipsec-secgw/ipsec.h                  |  61 +++++--
> > > > > > >  examples/ipsec-secgw/ipsec_process.c          | 113 +++++++-----
> > > > > > >  examples/ipsec-secgw/sa.c                     | 164 +++++++++++++-----
> > > > > > >  .../test/trs_aesgcm_common_defs.sh            |   4 +-
> > > > > > >  .../trs_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > > > >  .../test/tun_aesgcm_common_defs.sh            |   6 +-
> > > > > > >  .../tun_aesgcm_inline_crypto_fallback_defs.sh |   5 +
> > > > > > >  11 files changed, 358 insertions(+), 167 deletions(-)
> > > > > > > create mode
> > > > > > > 100644
> > > > > > > examples/ipsec-secgw/test/trs_aesgcm_inline_crypto_fallback_
> > > > > > > defs .sh  create mode 100644 examples/ipsec-
> > > > > > > secgw/test/tun_aesgcm_inline_crypto_fallback_defs.sh
> > > > > > >
> > > > > > > --
> > > > > > > 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, back to index

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-14 20:48 [dpdk-dev] [PATCH v1 0/2] examples/ipsec-secgw: add fallback session Marcin Smoczynski
2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 1/2] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
2019-08-14 20:48 ` [dpdk-dev] [PATCH v1 2/2] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
2019-09-04 14:16 ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Marcin Smoczynski
2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 1/3] examples/ipsec-secgw: ipsec_sa structure cleanup Marcin Smoczynski
2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 2/3] examples/ipsec-secgw: add fallback session feature Marcin Smoczynski
2019-09-04 14:16   ` [dpdk-dev] [PATCH v2 3/3] examples/ipsec-secgw: add offload fallback tests Marcin Smoczynski
2019-09-18  6:45   ` [dpdk-dev] [PATCH v2 0/3] examples/ipsec-secgw: add fallback session Anoob Joseph
2019-09-18  8:46     ` Ananyev, Konstantin
2019-09-18 11:40       ` Anoob Joseph
2019-09-18 22:19         ` Ananyev, Konstantin
2019-09-19  2:50           ` Anoob Joseph
2019-09-19  7:33             ` Ananyev, Konstantin
2019-09-19 10:53               ` Anoob Joseph

DPDK-dev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dpdk-dev/0 dpdk-dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dpdk-dev dpdk-dev/ https://lore.kernel.org/dpdk-dev \
		dev@dpdk.org dpdk-dev@archiver.kernel.org
	public-inbox-index dpdk-dev


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/ public-inbox