DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/2] ipsec: add transmit segmentation offload support
@ 2021-10-18 14:58 Radu Nicolau
  2021-10-18 14:58 ` [dpdk-dev] [PATCH 1/2] " Radu Nicolau
  2021-10-18 14:58 ` [dpdk-dev] [PATCH 2/2] examples/ipsec-secgw: add support for TSO Radu Nicolau
  0 siblings, 2 replies; 5+ messages in thread
From: Radu Nicolau @ 2021-10-18 14:58 UTC (permalink / raw)
  Cc: dev, gakhil, anoobj, konstantin.ananyev, Radu Nicolau

Add transmit segmentation offload support to the IPsec library and IPsec
Security GW sample app.
These patches were split from previously sent patchsets with feedback addressed

https://patchwork.dpdk.org/project/dpdk/patch/20211013121331.300245-7-radu.nicolau@intel.com/
https://patchwork.dpdk.org/project/dpdk/patch/20211001095202.3343782-5-radu.nicolau@intel.com/


Radu Nicolau (2):
  ipsec: add transmit segmentation offload support
  examples/ipsec-secgw: add support for TSO

 doc/guides/prog_guide/ipsec_lib.rst      |   2 +
 doc/guides/rel_notes/release_21_11.rst   |   5 +
 doc/guides/sample_app_ug/ipsec_secgw.rst |  11 ++
 examples/ipsec-secgw/ipsec-secgw.c       |   4 +
 examples/ipsec-secgw/ipsec.h             |   1 +
 examples/ipsec-secgw/ipsec_process.c     |  22 ++++
 examples/ipsec-secgw/sa.c                |  10 ++
 lib/ipsec/esp_outb.c                     | 131 ++++++++++++++++++-----
 8 files changed, 158 insertions(+), 28 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH 1/2] ipsec: add transmit segmentation offload support
  2021-10-18 14:58 [dpdk-dev] [PATCH 0/2] ipsec: add transmit segmentation offload support Radu Nicolau
@ 2021-10-18 14:58 ` Radu Nicolau
  2021-10-25  9:11   ` [dpdk-dev] [EXT] " Akhil Goyal
  2021-10-18 14:58 ` [dpdk-dev] [PATCH 2/2] examples/ipsec-secgw: add support for TSO Radu Nicolau
  1 sibling, 1 reply; 5+ messages in thread
From: Radu Nicolau @ 2021-10-18 14:58 UTC (permalink / raw)
  To: Konstantin Ananyev, Bernard Iremonger, Vladimir Medvedkin
  Cc: dev, gakhil, anoobj, Radu Nicolau, Declan Doherty, Abhijit Sinha,
	Daniel Martin Buckley, Fan Zhang

Add support for transmit segmentation offload to inline crypto processing
mode. This offload is not supported by other offload modes, as at a
minimum it requires inline crypto for IPsec to be supported on the
network interface.

Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 doc/guides/prog_guide/ipsec_lib.rst    |   2 +
 doc/guides/rel_notes/release_21_11.rst |   1 +
 lib/ipsec/esp_outb.c                   | 131 +++++++++++++++++++------
 3 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/doc/guides/prog_guide/ipsec_lib.rst b/doc/guides/prog_guide/ipsec_lib.rst
index 1bafdc608c..2a262f8c51 100644
--- a/doc/guides/prog_guide/ipsec_lib.rst
+++ b/doc/guides/prog_guide/ipsec_lib.rst
@@ -315,6 +315,8 @@ Supported features
 
 *  NAT-T / UDP encapsulated ESP.
 
+*  TSO support (only for inline crypto mode)
+
 *  algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, AES_CCM, CHACHA20_POLY1305,
    AES_GMAC, HMAC-SHA1, NULL.
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index f6d2bc6f48..955b0bd68f 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -201,6 +201,7 @@ New Features
   * Added support for NAT-T / UDP encapsulated ESP
   * Added support for SA telemetry.
   * Added support for setting a non default starting ESN value.
+  * Added support TSO offload support; only supported for inline crypto mode.
 
 
 Removed Items
diff --git a/lib/ipsec/esp_outb.c b/lib/ipsec/esp_outb.c
index b6c72f58a4..c9fba662f2 100644
--- a/lib/ipsec/esp_outb.c
+++ b/lib/ipsec/esp_outb.c
@@ -18,7 +18,7 @@
 
 typedef int32_t (*esp_outb_prepare_t)(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
-	union sym_op_data *icv, uint8_t sqh_len);
+	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso);
 
 /*
  * helper function to fill crypto_sym op for cipher+auth algorithms.
@@ -139,7 +139,7 @@ outb_cop_prepare(struct rte_crypto_op *cop,
 static inline int32_t
 outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
-	union sym_op_data *icv, uint8_t sqh_len)
+	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso)
 {
 	uint32_t clen, hlen, l2len, pdlen, pdofs, plen, tlen;
 	struct rte_mbuf *ml;
@@ -157,11 +157,20 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 
 	/* number of bytes to encrypt */
 	clen = plen + sizeof(*espt);
-	clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
+
+	/* We don't need to pad/align packet when using TSO offload */
+	if (!tso)
+		clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
+
 
 	/* pad length + esp tail */
 	pdlen = clen - plen;
-	tlen = pdlen + sa->icv_len + sqh_len;
+
+	/* We don't append ICV length when using TSO offload */
+	if (!tso)
+		tlen = pdlen + sa->icv_len + sqh_len;
+	else
+		tlen = pdlen + sqh_len;
 
 	/* do append and prepend */
 	ml = rte_pktmbuf_lastseg(mb);
@@ -309,7 +318,7 @@ esp_outb_tun_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],
 
 		/* try to update the packet itself */
 		rc = outb_tun_pkt_prepare(sa, sqc, iv, mb[i], &icv,
-					  sa->sqh_len);
+					  sa->sqh_len, 0);
 		/* success, setup crypto op */
 		if (rc >= 0) {
 			outb_pkt_xprepare(sa, sqc, &icv);
@@ -336,7 +345,7 @@ esp_outb_tun_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],
 static inline int32_t
 outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
-	union sym_op_data *icv, uint8_t sqh_len)
+	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso)
 {
 	uint8_t np;
 	uint32_t clen, hlen, pdlen, pdofs, plen, tlen, uhlen;
@@ -358,11 +367,19 @@ outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 
 	/* number of bytes to encrypt */
 	clen = plen + sizeof(*espt);
-	clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
+
+	/* We don't need to pad/align packet when using TSO offload */
+	if (!tso)
+		clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
 
 	/* pad length + esp tail */
 	pdlen = clen - plen;
-	tlen = pdlen + sa->icv_len + sqh_len;
+
+	/* We don't append ICV length when using TSO offload */
+	if (!tso)
+		tlen = pdlen + sa->icv_len + sqh_len;
+	else
+		tlen = pdlen + sqh_len;
 
 	/* do append and insert */
 	ml = rte_pktmbuf_lastseg(mb);
@@ -452,7 +469,7 @@ esp_outb_trs_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],
 
 		/* try to update the packet itself */
 		rc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv,
-				  sa->sqh_len);
+				  sa->sqh_len, 0);
 		/* success, setup crypto op */
 		if (rc >= 0) {
 			outb_pkt_xprepare(sa, sqc, &icv);
@@ -549,7 +566,7 @@ cpu_outb_pkt_prepare(const struct rte_ipsec_session *ss,
 		gen_iv(ivbuf[k], sqc);
 
 		/* try to update the packet itself */
-		rc = prepare(sa, sqc, ivbuf[k], mb[i], &icv, sa->sqh_len);
+		rc = prepare(sa, sqc, ivbuf[k], mb[i], &icv, sa->sqh_len, 0);
 
 		/* success, proceed with preparations */
 		if (rc >= 0) {
@@ -668,6 +685,20 @@ inline_outb_mbuf_prepare(const struct rte_ipsec_session *ss,
 	ss->sa->statistics.bytes += bytes;
 }
 
+
+static inline int
+esn_outb_nb_segments(struct rte_mbuf *m)
+{
+	if  (m->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_UDP_SEG)) {
+		uint16_t pkt_l3len = m->pkt_len - m->l2_len;
+		uint16_t segments =
+			(m->tso_segsz > 0 && pkt_l3len > m->tso_segsz) ?
+			(pkt_l3len + m->tso_segsz - 1) / m->tso_segsz : 1;
+		return segments;
+	}
+	return 1; /* no TSO */
+}
+
 /*
  * process group of ESP outbound tunnel packets destined for
  * INLINE_CRYPTO type of device.
@@ -677,29 +708,51 @@ inline_outb_tun_pkt_process(const struct rte_ipsec_session *ss,
 	struct rte_mbuf *mb[], uint16_t num)
 {
 	int32_t rc;
-	uint32_t i, k, n;
+	uint32_t i, k, nb_segs_t, n_sqn;
 	uint64_t sqn;
 	rte_be64_t sqc;
 	struct rte_ipsec_sa *sa;
 	union sym_op_data icv;
 	uint64_t iv[IPSEC_MAX_IV_QWORD];
 	uint32_t dr[num];
+	uint16_t nb_segs[num];
 
 	sa = ss->sa;
+	nb_segs_t = 0;
+	/* Calculate number of segments */
+	for (i = 0; i != num; i++) {
+		nb_segs[i] = esn_outb_nb_segments(mb[i]);
+		nb_segs_t += nb_segs[i];
+	}
 
-	n = num;
-	sqn = esn_outb_update_sqn(sa, &n);
-	if (n != num)
+	n_sqn = nb_segs_t;
+	sqn = esn_outb_update_sqn(sa, &n_sqn);
+	if (n_sqn != nb_segs_t) {
 		rte_errno = EOVERFLOW;
+		/* if there are segmented packets find out how many can be
+		 * sent until overflow occurs
+		 */
+		if (nb_segs_t > num) { /* there is at least 1 */
+			uint32_t seg_cnt = 0;
+			for (i = 0; i < num && seg_cnt < n_sqn; i++)
+				seg_cnt += nb_segs[i];
+			num = i - 1;
+		} else {
+			num = n_sqn; /* no segmented packets */
+		}
+	}
 
 	k = 0;
-	for (i = 0; i != n; i++) {
+	for (i = 0; i != num; i++) {
 
-		sqc = rte_cpu_to_be_64(sqn + i);
+		sqc = rte_cpu_to_be_64(sqn);
 		gen_iv(iv, sqc);
+		sqn += nb_segs[i];
 
 		/* try to update the packet itself */
-		rc = outb_tun_pkt_prepare(sa, sqc, iv, mb[i], &icv, 0);
+		rc = outb_tun_pkt_prepare(sa, sqc, iv, mb[i], &icv, 0,
+			(mb[i]->ol_flags &
+			(PKT_TX_TCP_SEG | PKT_TX_UDP_SEG)) != 0);
 
 		k += (rc >= 0);
 
@@ -711,8 +764,8 @@ inline_outb_tun_pkt_process(const struct rte_ipsec_session *ss,
 	}
 
 	/* copy not processed mbufs beyond good ones */
-	if (k != n && k != 0)
-		move_bad_mbufs(mb, dr, n, n - k);
+	if (k != num && k != 0)
+		move_bad_mbufs(mb, dr, num, num - k);
 
 	inline_outb_mbuf_prepare(ss, mb, k);
 	return k;
@@ -727,29 +780,51 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session *ss,
 	struct rte_mbuf *mb[], uint16_t num)
 {
 	int32_t rc;
-	uint32_t i, k, n;
+	uint32_t i, k, nb_segs_t, n_sqn;
 	uint64_t sqn;
 	rte_be64_t sqc;
 	struct rte_ipsec_sa *sa;
 	union sym_op_data icv;
 	uint64_t iv[IPSEC_MAX_IV_QWORD];
 	uint32_t dr[num];
+	uint16_t nb_segs[num];
 
 	sa = ss->sa;
+	nb_segs_t = 0;
+	/* Calculate number of segments */
+	for (i = 0; i != num; i++) {
+		nb_segs[i] = esn_outb_nb_segments(mb[i]);
+		nb_segs_t += nb_segs[i];
+	}
 
-	n = num;
-	sqn = esn_outb_update_sqn(sa, &n);
-	if (n != num)
+	n_sqn = nb_segs_t;
+	sqn = esn_outb_update_sqn(sa, &n_sqn);
+	if (n_sqn != nb_segs_t) {
 		rte_errno = EOVERFLOW;
+		/* if there are segmented packets find out how many can be
+		 * sent until overflow occurs
+		 */
+		if (nb_segs_t > num) { /* there is at least 1 */
+			uint32_t seg_cnt = 0;
+			for (i = 0; i < num && seg_cnt < n_sqn; i++)
+				seg_cnt += nb_segs[i];
+			num = i - 1;
+		} else {
+			num = n_sqn; /* no segmented packets */
+		}
+	}
 
 	k = 0;
-	for (i = 0; i != n; i++) {
+	for (i = 0; i != num; i++) {
 
-		sqc = rte_cpu_to_be_64(sqn + i);
+		sqc = rte_cpu_to_be_64(sqn);
 		gen_iv(iv, sqc);
+		sqn += nb_segs[i];
 
 		/* try to update the packet itself */
-		rc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv, 0);
+		rc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv, 0,
+				(mb[i]->ol_flags &
+				(PKT_TX_TCP_SEG | PKT_TX_UDP_SEG)) != 0);
 
 		k += (rc >= 0);
 
@@ -761,8 +836,8 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session *ss,
 	}
 
 	/* copy not processed mbufs beyond good ones */
-	if (k != n && k != 0)
-		move_bad_mbufs(mb, dr, n, n - k);
+	if (k != num && k != 0)
+		move_bad_mbufs(mb, dr, num, num - k);
 
 	inline_outb_mbuf_prepare(ss, mb, k);
 	return k;
-- 
2.25.1


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

* [dpdk-dev] [PATCH 2/2] examples/ipsec-secgw: add support for TSO
  2021-10-18 14:58 [dpdk-dev] [PATCH 0/2] ipsec: add transmit segmentation offload support Radu Nicolau
  2021-10-18 14:58 ` [dpdk-dev] [PATCH 1/2] " Radu Nicolau
@ 2021-10-18 14:58 ` Radu Nicolau
  1 sibling, 0 replies; 5+ messages in thread
From: Radu Nicolau @ 2021-10-18 14:58 UTC (permalink / raw)
  To: Radu Nicolau, Akhil Goyal; +Cc: dev, anoobj, konstantin.ananyev, Declan Doherty

Add support to allow user to specific MSS for TSO offload on a per SA
basis. MSS configuration in the context of IPsec is only supported for
outbound SA's in the context of an inline IPsec Crypto offload.

Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst   |  4 ++++
 doc/guides/sample_app_ug/ipsec_secgw.rst | 11 +++++++++++
 examples/ipsec-secgw/ipsec-secgw.c       |  4 ++++
 examples/ipsec-secgw/ipsec.h             |  1 +
 examples/ipsec-secgw/ipsec_process.c     | 22 ++++++++++++++++++++++
 examples/ipsec-secgw/sa.c                | 10 ++++++++++
 6 files changed, 52 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 955b0bd68f..c2563c6f63 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -203,6 +203,10 @@ New Features
   * Added support for setting a non default starting ESN value.
   * Added support TSO offload support; only supported for inline crypto mode.
 
+* **IPsec Security Gateway sample application new features.**
+
+  * Added support for TSO
+
 
 Removed Items
 -------------
diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst
index 6510456e31..2ff928e4dc 100644
--- a/doc/guides/sample_app_ug/ipsec_secgw.rst
+++ b/doc/guides/sample_app_ug/ipsec_secgw.rst
@@ -748,6 +748,17 @@ where each options means:
 
    * *esn N* N is the initial ESN value
 
+ ``<mss>``
+
+ * Maximum segment size for TSO offload, available for egress SAs only.
+
+ * Optional: Yes, TSO offload not set by default
+
+ * Syntax:
+
+   * *mss N* N is the segment size in bytes
+
+
 Example SA rules:
 
 .. code-block:: console
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 47c33661df..6aaaaa3a14 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -400,6 +400,10 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)
 		pkt->l2_len = 0;
 		pkt->l3_len = sizeof(*iph4);
 		pkt->packet_type |= RTE_PTYPE_L3_IPV4;
+		if  (pkt->packet_type & RTE_PTYPE_L4_TCP)
+			pkt->l4_len = sizeof(struct rte_tcp_hdr);
+		else if (pkt->packet_type & RTE_PTYPE_L4_UDP)
+			pkt->l4_len = sizeof(struct rte_udp_hdr);
 	} else if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) {
 		int next_proto;
 		size_t l3len, ext_len;
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 0dfb0d6acb..02855ce774 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -142,6 +142,7 @@ struct ipsec_sa {
 	enum rte_security_ipsec_sa_direction direction;
 	uint8_t udp_encap;
 	uint16_t portid;
+	uint16_t mss;
 	uint64_t esn;
 	uint8_t fdir_qid;
 	uint8_t fdir_flag;
diff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c
index 5012e1a6a4..333e3f1e74 100644
--- a/examples/ipsec-secgw/ipsec_process.c
+++ b/examples/ipsec-secgw/ipsec_process.c
@@ -222,6 +222,28 @@ prep_process_group(void *sa, struct rte_mbuf *mb[], uint32_t cnt)
 	for (j = 0; j != cnt; j++) {
 		priv = get_priv(mb[j]);
 		priv->sa = sa;
+		/* setup TSO related fields if TSO enabled*/
+		if (priv->sa->mss) {
+			mb[j]->tso_segsz = priv->sa->mss;
+
+			if ((IS_TUNNEL(priv->sa->flags))) {
+				mb[j]->outer_l3_len = mb[j]->l3_len;
+				mb[j]->outer_l2_len = mb[j]->l2_len;
+				mb[j]->ol_flags |=
+				(PKT_TX_OUTER_IP_CKSUM | PKT_TX_TUNNEL_ESP);
+			}
+			uint32_t ptype = mb[j]->packet_type;
+			if  (ptype & RTE_PTYPE_L4_TCP)
+				mb[j]->ol_flags |=
+					(PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM);
+			else
+				mb[j]->ol_flags |=
+					(PKT_TX_UDP_SEG | PKT_TX_UDP_CKSUM);
+			if (RTE_ETH_IS_IPV4_HDR(ptype))
+				mb[j]->ol_flags |= PKT_TX_OUTER_IPV4;
+			else
+				mb[j]->ol_flags |= PKT_TX_OUTER_IPV6;
+		}
 	}
 }
 
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index de06f24d01..3690e0a7eb 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -778,6 +778,16 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			continue;
 		}
 
+		if (strcmp(tokens[ti], "mss") == 0) {
+			INCREMENT_TOKEN_INDEX(ti, n_tokens, status);
+			if (status->status < 0)
+				return;
+			rule->mss = atoi(tokens[ti]);
+			if (status->status < 0)
+				return;
+			continue;
+		}
+
 		if (strcmp(tokens[ti], "fallback") == 0) {
 			struct rte_ipsec_session *fb;
 
-- 
2.25.1


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

* Re: [dpdk-dev] [EXT] [PATCH 1/2] ipsec: add transmit segmentation offload support
  2021-10-18 14:58 ` [dpdk-dev] [PATCH 1/2] " Radu Nicolau
@ 2021-10-25  9:11   ` Akhil Goyal
  2021-10-26 15:50     ` Nicolau, Radu
  0 siblings, 1 reply; 5+ messages in thread
From: Akhil Goyal @ 2021-10-25  9:11 UTC (permalink / raw)
  To: Radu Nicolau, Konstantin Ananyev, Bernard Iremonger, Vladimir Medvedkin
  Cc: dev, Anoob Joseph, Declan Doherty, Abhijit Sinha,
	Daniel Martin Buckley, Fan Zhang

> Subject: [EXT] [PATCH 1/2] ipsec: add transmit segmentation offload support
> 
Title should be ipsec: support TSO

> Add support for transmit segmentation offload to inline crypto processing
> mode. This offload is not supported by other offload modes, as at a
> minimum it requires inline crypto for IPsec to be supported on the
> network interface.
> 
> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
> Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
> Signed-off-by: Abhijit Sinha <abhijit.sinha@intel.com>
> Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
> Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
> ---
>  doc/guides/prog_guide/ipsec_lib.rst    |   2 +
>  doc/guides/rel_notes/release_21_11.rst |   1 +
>  lib/ipsec/esp_outb.c                   | 131 +++++++++++++++++++------
>  3 files changed, 106 insertions(+), 28 deletions(-)
> 
> diff --git a/doc/guides/prog_guide/ipsec_lib.rst
> b/doc/guides/prog_guide/ipsec_lib.rst
> index 1bafdc608c..2a262f8c51 100644
> --- a/doc/guides/prog_guide/ipsec_lib.rst
> +++ b/doc/guides/prog_guide/ipsec_lib.rst
> @@ -315,6 +315,8 @@ Supported features
> 
>  *  NAT-T / UDP encapsulated ESP.
> 
> +*  TSO support (only for inline crypto mode)
> +
The word support can be dropped here as it is a list of supported features.

>  *  algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, AES_CCM,
> CHACHA20_POLY1305,
>     AES_GMAC, HMAC-SHA1, NULL.
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index f6d2bc6f48..955b0bd68f 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -201,6 +201,7 @@ New Features
>    * Added support for NAT-T / UDP encapsulated ESP
>    * Added support for SA telemetry.
>    * Added support for setting a non default starting ESN value.
> +  * Added support TSO offload support; only supported for inline crypto
> mode.

The word support is added three times in a single sentence.
It can be rephrased as
* Added support for TSO in inline crypto mode.


> 
> 
>  Removed Items
> diff --git a/lib/ipsec/esp_outb.c b/lib/ipsec/esp_outb.c
> index b6c72f58a4..c9fba662f2 100644
> --- a/lib/ipsec/esp_outb.c
> +++ b/lib/ipsec/esp_outb.c
> @@ -18,7 +18,7 @@
> 
>  typedef int32_t (*esp_outb_prepare_t)(struct rte_ipsec_sa *sa, rte_be64_t
> sqc,
>  	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
> -	union sym_op_data *icv, uint8_t sqh_len);
> +	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso);
> 
>  /*
>   * helper function to fill crypto_sym op for cipher+auth algorithms.
> @@ -139,7 +139,7 @@ outb_cop_prepare(struct rte_crypto_op *cop,
>  static inline int32_t
>  outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
>  	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
> -	union sym_op_data *icv, uint8_t sqh_len)
> +	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso)
>  {
>  	uint32_t clen, hlen, l2len, pdlen, pdofs, plen, tlen;
>  	struct rte_mbuf *ml;
> @@ -157,11 +157,20 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa,
> rte_be64_t sqc,
> 
>  	/* number of bytes to encrypt */
>  	clen = plen + sizeof(*espt);
> -	clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
> +
> +	/* We don't need to pad/align packet when using TSO offload */
> +	if (!tso)
> +		clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
> +
> 
>  	/* pad length + esp tail */
>  	pdlen = clen - plen;
> -	tlen = pdlen + sa->icv_len + sqh_len;
> +
> +	/* We don't append ICV length when using TSO offload */
> +	if (!tso)
> +		tlen = pdlen + sa->icv_len + sqh_len;
> +	else
> +		tlen = pdlen + sqh_len;
This is a data path function, 2 extra checks are added for tso in the same function
if (tso) {
	pdlen = clen - plen;
	tlen = pdlen + sqh_len;
} else {
	clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
	pdlen = clen - plen;
	tlen = pdlen + sa->icv_len + sqh_len;
}


> 
>  	/* do append and prepend */
>  	ml = rte_pktmbuf_lastseg(mb);
> @@ -309,7 +318,7 @@ esp_outb_tun_prepare(const struct
> rte_ipsec_session *ss, struct rte_mbuf *mb[],
> 
>  		/* try to update the packet itself */
>  		rc = outb_tun_pkt_prepare(sa, sqc, iv, mb[i], &icv,
> -					  sa->sqh_len);
> +					  sa->sqh_len, 0);
>  		/* success, setup crypto op */
>  		if (rc >= 0) {
>  			outb_pkt_xprepare(sa, sqc, &icv);
> @@ -336,7 +345,7 @@ esp_outb_tun_prepare(const struct
> rte_ipsec_session *ss, struct rte_mbuf *mb[],
>  static inline int32_t
>  outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
>  	const uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,
> -	union sym_op_data *icv, uint8_t sqh_len)
> +	union sym_op_data *icv, uint8_t sqh_len, uint8_t tso)
>  {
>  	uint8_t np;
>  	uint32_t clen, hlen, pdlen, pdofs, plen, tlen, uhlen;
> @@ -358,11 +367,19 @@ outb_trs_pkt_prepare(struct rte_ipsec_sa *sa,
> rte_be64_t sqc,
> 
>  	/* number of bytes to encrypt */
>  	clen = plen + sizeof(*espt);
> -	clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
> +
> +	/* We don't need to pad/align packet when using TSO offload */
> +	if (!tso)
> +		clen = RTE_ALIGN_CEIL(clen, sa->pad_align);
> 
>  	/* pad length + esp tail */
>  	pdlen = clen - plen;
> -	tlen = pdlen + sa->icv_len + sqh_len;
> +
> +	/* We don't append ICV length when using TSO offload */
> +	if (!tso)
> +		tlen = pdlen + sa->icv_len + sqh_len;
> +	else
> +		tlen = pdlen + sqh_len;

Same comment as above.

> 
>  	/* do append and insert */
>  	ml = rte_pktmbuf_lastseg(mb);
> @@ -452,7 +469,7 @@ esp_outb_trs_prepare(const struct rte_ipsec_session
> *ss, struct rte_mbuf *mb[],
> 
>  		/* try to update the packet itself */
>  		rc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv,
> -				  sa->sqh_len);
> +				  sa->sqh_len, 0);
>  		/* success, setup crypto op */
>  		if (rc >= 0) {
>  			outb_pkt_xprepare(sa, sqc, &icv);
> @@ -549,7 +566,7 @@ cpu_outb_pkt_prepare(const struct
> rte_ipsec_session *ss,
>  		gen_iv(ivbuf[k], sqc);
> 
>  		/* try to update the packet itself */
> -		rc = prepare(sa, sqc, ivbuf[k], mb[i], &icv, sa->sqh_len);
> +		rc = prepare(sa, sqc, ivbuf[k], mb[i], &icv, sa->sqh_len, 0);
> 
>  		/* success, proceed with preparations */
>  		if (rc >= 0) {
> @@ -668,6 +685,20 @@ inline_outb_mbuf_prepare(const struct
> rte_ipsec_session *ss,
>  	ss->sa->statistics.bytes += bytes;
>  }
> 
> +
> +static inline int
> +esn_outb_nb_segments(struct rte_mbuf *m)
> +{
> +	if  (m->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_UDP_SEG)) {
> +		uint16_t pkt_l3len = m->pkt_len - m->l2_len;
> +		uint16_t segments =
> +			(m->tso_segsz > 0 && pkt_l3len > m->tso_segsz) ?
> +			(pkt_l3len + m->tso_segsz - 1) / m->tso_segsz : 1;
> +		return segments;

Directly return, no need for defining segments.

> +	}
> +	return 1; /* no TSO */
> +}
> +
>  /*
>   * process group of ESP outbound tunnel packets destined for
>   * INLINE_CRYPTO type of device.
> @@ -677,29 +708,51 @@ inline_outb_tun_pkt_process(const struct
> rte_ipsec_session *ss,
>  	struct rte_mbuf *mb[], uint16_t num)
>  {
>  	int32_t rc;
> -	uint32_t i, k, n;
> +	uint32_t i, k, nb_segs_t, n_sqn;

_t is normally used for typedefs. Can we rename it?

>  	uint64_t sqn;
>  	rte_be64_t sqc;
>  	struct rte_ipsec_sa *sa;
>  	union sym_op_data icv;
>  	uint64_t iv[IPSEC_MAX_IV_QWORD];
>  	uint32_t dr[num];
> +	uint16_t nb_segs[num];
> 
>  	sa = ss->sa;
> +	nb_segs_t = 0;
> +	/* Calculate number of segments */
> +	for (i = 0; i != num; i++) {
> +		nb_segs[i] = esn_outb_nb_segments(mb[i]);
> +		nb_segs_t += nb_segs[i];
> +	}
> 
> -	n = num;
> -	sqn = esn_outb_update_sqn(sa, &n);
> -	if (n != num)
> +	n_sqn = nb_segs_t;
> +	sqn = esn_outb_update_sqn(sa, &n_sqn);
> +	if (n_sqn != nb_segs_t) {
>  		rte_errno = EOVERFLOW;

If it is an error condition, shouldn't we return.
Also, I do not see rte_errno being checked anywhere in the app/test or ipsec-secgw.

> +		/* if there are segmented packets find out how many can be
> +		 * sent until overflow occurs
> +		 */
> +		if (nb_segs_t > num) { /* there is at least 1 */
> +			uint32_t seg_cnt = 0;
> +			for (i = 0; i < num && seg_cnt < n_sqn; i++)
> +				seg_cnt += nb_segs[i];
> +			num = i - 1;
> +		} else {
> +			num = n_sqn; /* no segmented packets */
> +		}
> +	}
> 


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

* Re: [dpdk-dev] [EXT] [PATCH 1/2] ipsec: add transmit segmentation offload support
  2021-10-25  9:11   ` [dpdk-dev] [EXT] " Akhil Goyal
@ 2021-10-26 15:50     ` Nicolau, Radu
  0 siblings, 0 replies; 5+ messages in thread
From: Nicolau, Radu @ 2021-10-26 15:50 UTC (permalink / raw)
  To: Akhil Goyal, Konstantin Ananyev, Bernard Iremonger, Vladimir Medvedkin
  Cc: dev, Anoob Joseph, Declan Doherty, Abhijit Sinha,
	Daniel Martin Buckley, Fan Zhang

Hi Akhil, I will address all issues except the last one with a comment 
below:

>> -	n = num;
>> -	sqn = esn_outb_update_sqn(sa, &n);
>> -	if (n != num)
>> +	n_sqn = nb_segs_t;
>> +	sqn = esn_outb_update_sqn(sa, &n_sqn);
>> +	if (n_sqn != nb_segs_t) {
>>   		rte_errno = EOVERFLOW;
> If it is an error condition, shouldn't we return.
> Also, I do not see rte_errno being checked anywhere in the app/test or ipsec-secgw.
We are sending all packets that don't cause a SN overflow, and we set 
the error flag. The user will see that not all packets were sent and and 
rte_errno, and this is the behaviour that was in place before this patch.
>
>> +		/* if there are segmented packets find out how many can be
>> +		 * sent until overflow occurs
>> +		 */
>> +		if (nb_segs_t > num) { /* there is at least 1 */
>> +			uint32_t seg_cnt = 0;
>> +			for (i = 0; i < num && seg_cnt < n_sqn; i++)
>> +				seg_cnt += nb_segs[i];
>> +			num = i - 1;
>> +		} else {
>> +			num = n_sqn; /* no segmented packets */
>> +		}
>> +	}
>>

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

end of thread, other threads:[~2021-10-26 15:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-18 14:58 [dpdk-dev] [PATCH 0/2] ipsec: add transmit segmentation offload support Radu Nicolau
2021-10-18 14:58 ` [dpdk-dev] [PATCH 1/2] " Radu Nicolau
2021-10-25  9:11   ` [dpdk-dev] [EXT] " Akhil Goyal
2021-10-26 15:50     ` Nicolau, Radu
2021-10-18 14:58 ` [dpdk-dev] [PATCH 2/2] examples/ipsec-secgw: add support for TSO Radu Nicolau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).