@@ -559,7 +559,8 @@ trs_process_step3(struct rte_mbuf *mb)
* - tx_offload
*/
static inline void
-tun_process_step3(struct rte_mbuf *mb, uint64_t txof_msk, uint64_t txof_val)
+tun_process_step3(struct rte_mbuf *mb, uint8_t is_ipv4, uint64_t txof_msk,
+ uint64_t txof_val)
{
/* reset mbuf metatdata: L2/L3 len, packet type */
mb->packet_type = RTE_PTYPE_UNKNOWN;
@@ -567,6 +568,14 @@ tun_process_step3(struct rte_mbuf *mb, uint64_t txof_msk, uint64_t txof_val)
/* clear the PKT_RX_SEC_OFFLOAD flag if set */
mb->ol_flags &= ~PKT_RX_SEC_OFFLOAD;
+
+ if (is_ipv4) {
+ mb->l3_len = sizeof(struct rte_ipv4_hdr);
+ mb->ol_flags |= (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
+ } else {
+ mb->l3_len = sizeof(struct rte_ipv6_hdr);
+ mb->ol_flags |= PKT_TX_IPV6;
+ }
}
/*
@@ -618,8 +627,12 @@ tun_process(const struct rte_ipsec_sa *sa, struct rte_mbuf *mb[],
update_tun_inb_l3hdr(sa, outh, inh);
/* update mbuf's metadata */
- tun_process_step3(mb[i], sa->tx_offload.msk,
+ tun_process_step3(mb[i],
+ (sa->type & RTE_IPSEC_SATP_IPV_MASK) ==
+ RTE_IPSEC_SATP_IPV4 ? 1 : 0,
+ sa->tx_offload.msk,
sa->tx_offload.val);
+
k++;
} else
dr[i - k] = i;
@@ -19,7 +19,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 icrypto);
/*
* helper function to fill crypto_sym op for cipher+auth algorithms.
@@ -140,9 +140,9 @@ 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 icrypto)
{
- uint32_t clen, hlen, l2len, pdlen, pdofs, plen, tlen;
+ uint32_t clen, hlen, l2len, l3len, pdlen, pdofs, plen, tlen;
struct rte_mbuf *ml;
struct rte_esp_hdr *esph;
struct rte_esp_tail *espt;
@@ -154,6 +154,8 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
/* size of ipsec protected data */
l2len = mb->l2_len;
+ l3len = mb->l3_len;
+
plen = mb->pkt_len - l2len;
/* number of bytes to encrypt */
@@ -190,8 +192,26 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
pt = rte_pktmbuf_mtod_offset(ml, typeof(pt), pdofs);
/* update pkt l2/l3 len */
- mb->tx_offload = (mb->tx_offload & sa->tx_offload.msk) |
- sa->tx_offload.val;
+ if (icrypto) {
+ mb->tx_offload =
+ (mb->tx_offload & sa->inline_crypto.tx_offload.msk) |
+ sa->inline_crypto.tx_offload.val;
+ mb->l3_len = l3len;
+
+ mb->ol_flags |= sa->inline_crypto.tx_ol_flags;
+
+ /* set ip checksum offload for inner */
+ if ((sa->type & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)
+ mb->ol_flags |= (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
+ else if ((sa->type & RTE_IPSEC_SATP_IPV_MASK)
+ == RTE_IPSEC_SATP_IPV6)
+ mb->ol_flags |= PKT_TX_IPV6;
+ } else {
+ mb->tx_offload = (mb->tx_offload & sa->tx_offload.msk) |
+ sa->tx_offload.val;
+
+ mb->ol_flags |= sa->tx_ol_flags;
+ }
/* copy tunnel pkt header */
rte_memcpy(ph, sa->hdr, sa->hdr_len);
@@ -311,7 +331,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);
@@ -338,7 +358,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 icrypto __rte_unused)
{
uint8_t np;
uint32_t clen, hlen, pdlen, pdofs, plen, tlen, uhlen;
@@ -394,10 +414,16 @@ outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
/* shift L2/L3 headers */
insert_esph(ph, ph + hlen, uhlen);
+ if ((sa->type & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)
+ mb->ol_flags |= (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
+ else if ((sa->type & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV6)
+ mb->ol_flags |= PKT_TX_IPV6;
+
/* update ip header fields */
np = update_trs_l34hdrs(sa, ph + l2len, mb->pkt_len - sqh_len, l2len,
l3len, IPPROTO_ESP, tso);
+
/* update spi, seqn and iv */
esph = (struct rte_esp_hdr *)(ph + uhlen);
iv = (uint64_t *)(esph + 1);
@@ -463,7 +489,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);
@@ -560,7 +586,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) {
@@ -741,7 +767,7 @@ inline_outb_tun_pkt_process(const struct rte_ipsec_session *ss,
gen_iv(iv, sqc);
/* 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, 1);
k += (rc >= 0);
@@ -808,7 +834,7 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session *ss,
gen_iv(iv, sqc);
/* 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, 0);
k += (rc >= 0);
@@ -38,7 +38,8 @@ struct rte_ipsec_sa_prm {
union {
struct {
uint8_t hdr_len; /**< tunnel header len */
- uint8_t hdr_l3_off; /**< offset for IPv4/IPv6 header */
+ uint8_t hdr_l3_off; /**< tunnel l3 header len */
+ uint8_t hdr_l3_len; /**< tunnel l3 header len */
uint8_t next_proto; /**< next header protocol */
const void *hdr; /**< tunnel header template */
} tun; /**< tunnel mode related parameters */
@@ -17,6 +17,8 @@
#define MBUF_MAX_L2_LEN RTE_LEN2MASK(RTE_MBUF_L2_LEN_BITS, uint64_t)
#define MBUF_MAX_L3_LEN RTE_LEN2MASK(RTE_MBUF_L3_LEN_BITS, uint64_t)
+#define MBUF_MAX_TSO_LEN RTE_LEN2MASK(RTE_MBUF_TSO_SEGSZ_BITS, uint64_t)
+#define MBUF_MAX_OL3_LEN RTE_LEN2MASK(RTE_MBUF_OUTL3_LEN_BITS, uint64_t)
/* some helper structures */
struct crypto_xform {
@@ -348,6 +350,11 @@ esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen, uint64_t sqn)
sa->cofs.ofs.cipher.head = sa->ctp.cipher.offset - sa->ctp.auth.offset;
sa->cofs.ofs.cipher.tail = (sa->ctp.auth.offset + sa->ctp.auth.length) -
(sa->ctp.cipher.offset + sa->ctp.cipher.length);
+
+ if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4)
+ sa->tx_ol_flags |= (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
+ else if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV6)
+ sa->tx_ol_flags |= PKT_TX_IPV6;
}
/*
@@ -362,9 +369,43 @@ esp_outb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
sa->hdr_len = prm->tun.hdr_len;
sa->hdr_l3_off = prm->tun.hdr_l3_off;
+
+ /* update l2_len and l3_len fields for outbound mbuf */
+ sa->inline_crypto.tx_offload.val = rte_mbuf_tx_offload(
+ 0, /* iL2_LEN */
+ 0, /* iL3_LEN */
+ 0, /* iL4_LEN */
+ 0, /* TSO_SEG_SZ */
+ prm->tun.hdr_l3_len, /* oL3_LEN */
+ prm->tun.hdr_l3_off, /* oL2_LEN */
+ 0);
+
+ sa->inline_crypto.tx_ol_flags |= PKT_TX_TUNNEL_ESP;
+
+ if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4)
+ sa->inline_crypto.tx_ol_flags |= PKT_TX_OUTER_IPV4;
+ else if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV6)
+ sa->inline_crypto.tx_ol_flags |= PKT_TX_OUTER_IPV6;
+
+ if (sa->inline_crypto.tx_ol_flags & PKT_TX_OUTER_IPV4)
+ sa->inline_crypto.tx_ol_flags |= PKT_TX_OUTER_IP_CKSUM;
+ if (sa->tx_ol_flags & PKT_TX_IPV4)
+ sa->inline_crypto.tx_ol_flags |= PKT_TX_IP_CKSUM;
+
/* update l2_len and l3_len fields for outbound mbuf */
- sa->tx_offload.val = rte_mbuf_tx_offload(sa->hdr_l3_off,
- sa->hdr_len - sa->hdr_l3_off, 0, 0, 0, 0, 0);
+ sa->tx_offload.val = rte_mbuf_tx_offload(
+ prm->tun.hdr_l3_off, /* iL2_LEN */
+ prm->tun.hdr_l3_len, /* iL3_LEN */
+ 0, /* iL4_LEN */
+ 0, /* TSO_SEG_SZ */
+ 0, /* oL3_LEN */
+ 0, /* oL2_LEN */
+ 0);
+
+ if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4)
+ sa->tx_ol_flags |= (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
+ else if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV6)
+ sa->tx_ol_flags |= PKT_TX_IPV6;
memcpy(sa->hdr, prm->tun.hdr, sa->hdr_len);
@@ -473,6 +514,10 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
sa->salt = prm->ipsec_xform.salt;
/* preserve all values except l2_len and l3_len */
+ sa->inline_crypto.tx_offload.msk =
+ ~rte_mbuf_tx_offload(MBUF_MAX_L2_LEN, MBUF_MAX_L3_LEN,
+ 0, 0, MBUF_MAX_OL3_LEN, 0, 0);
+
sa->tx_offload.msk =
~rte_mbuf_tx_offload(MBUF_MAX_L2_LEN, MBUF_MAX_L3_LEN,
0, 0, 0, 0, 0);
@@ -101,6 +101,14 @@ struct rte_ipsec_sa {
uint64_t msk;
uint64_t val;
} tx_offload;
+ uint64_t tx_ol_flags;
+ struct {
+ uint64_t tx_ol_flags;
+ struct {
+ uint64_t msk;
+ uint64_t val;
+ } tx_offload;
+ } inline_crypto;
struct {
uint16_t sport;
uint16_t dport;