From 4edede7bc6ee15d2d563c91c5ce47bd7567b1c90 Mon Sep 17 00:00:00 2001 From: Tejasree Kondoj Date: Fri, 9 Oct 2020 15:33:28 +0530 Subject: [PATCH] crypto/octeontx2: support lookaside IPsec IPv6 Adding IPv6 tunnel mode support in lookaside IPsec PMD. Signed-off-by: Tejasree Kondoj Acked-by: Anoob Joseph --- doc/guides/cryptodevs/octeontx2.rst | 1 + doc/guides/rel_notes/release_20_11.rst | 5 ++++ drivers/crypto/octeontx2/otx2_cryptodev.h | 2 +- drivers/crypto/octeontx2/otx2_cryptodev_ops.c | 13 +++++++-- drivers/crypto/octeontx2/otx2_cryptodev_sec.c | 28 ++++++++++++++++++- drivers/crypto/octeontx2/otx2_cryptodev_sec.h | 2 ++ drivers/crypto/octeontx2/otx2_ipsec_po.h | 2 +- drivers/crypto/octeontx2/otx2_ipsec_po_ops.h | 10 +++++-- 8 files changed, 55 insertions(+), 8 deletions(-) diff --git a/doc/guides/cryptodevs/octeontx2.rst b/doc/guides/cryptodevs/octeontx2.rst index 432146db04..b927c8f21d 100644 --- a/doc/guides/cryptodevs/octeontx2.rst +++ b/doc/guides/cryptodevs/octeontx2.rst @@ -176,6 +176,7 @@ Features supported ~~~~~~~~~~~~~~~~~~ * IPv4 +* IPv6 * ESP * Tunnel mode * AES-128/192/256-GCM diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst index 27e68f396e..bdadc44618 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -156,6 +156,11 @@ New Features * Added support for AES-ECB 128, 192 and 256 in aesni_mb PMD. +* **Updated the OCTEON TX2 crypto PMD.** + + * Updated the OCTEON TX2 crypto PMD lookaside protocol offload for IPsec with + IPv6 support. + * **Added Intel ACC100 bbdev PMD.** Added a new ``acc100`` bbdev driver for the Intel\ |reg| ACC100 accelerator diff --git a/drivers/crypto/octeontx2/otx2_cryptodev.h b/drivers/crypto/octeontx2/otx2_cryptodev.h index fba7222108..7b1b648639 100644 --- a/drivers/crypto/octeontx2/otx2_cryptodev.h +++ b/drivers/crypto/octeontx2/otx2_cryptodev.h @@ -36,7 +36,7 @@ struct otx2_cpt_vf { }; struct cpt_meta_info { - uint64_t deq_op_info[4]; + uint64_t deq_op_info[5]; uint64_t comp_code_sz; union cpt_res_s cpt_res __rte_aligned(16); struct cpt_request_info cpt_req; diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c index d38365a331..21ac122a64 100644 --- a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c +++ b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c @@ -842,6 +842,7 @@ otx2_cpt_sec_post_process(struct rte_crypto_op *cop, uintptr_t *rsp) vq_cmd_word0_t *word0 = (vq_cmd_word0_t *)&req->ist.ei0; struct rte_crypto_sym_op *sym_op = cop->sym; struct rte_mbuf *m = sym_op->m_src; + struct rte_ipv6_hdr *ip6; struct rte_ipv4_hdr *ip; uint16_t m_len; int mdata_len; @@ -852,9 +853,17 @@ otx2_cpt_sec_post_process(struct rte_crypto_op *cop, uintptr_t *rsp) if ((word0->s.opcode & 0xff) == OTX2_IPSEC_PO_PROCESS_IPSEC_INB) { data = rte_pktmbuf_mtod(m, char *); - ip = (struct rte_ipv4_hdr *)(data + OTX2_IPSEC_PO_INB_RPTR_HDR); - m_len = rte_be_to_cpu_16(ip->total_length); + if (rsp[4] == RTE_SECURITY_IPSEC_TUNNEL_IPV4) { + ip = (struct rte_ipv4_hdr *)(data + + OTX2_IPSEC_PO_INB_RPTR_HDR); + m_len = rte_be_to_cpu_16(ip->total_length); + } else { + ip6 = (struct rte_ipv6_hdr *)(data + + OTX2_IPSEC_PO_INB_RPTR_HDR); + m_len = rte_be_to_cpu_16(ip6->payload_len) + + sizeof(struct rte_ipv6_hdr); + } m->data_len = m_len; m->pkt_len = m_len; diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_sec.c b/drivers/crypto/octeontx2/otx2_cryptodev_sec.c index 72e6c418e8..b80ec7bff2 100644 --- a/drivers/crypto/octeontx2/otx2_cryptodev_sec.c +++ b/drivers/crypto/octeontx2/otx2_cryptodev_sec.c @@ -25,7 +25,12 @@ ipsec_lp_len_precalc(struct rte_security_ipsec_xform *ipsec, { struct rte_crypto_sym_xform *cipher_xform, *auth_xform; - lp->partial_len = sizeof(struct rte_ipv4_hdr); + if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + lp->partial_len = sizeof(struct rte_ipv4_hdr); + else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) + lp->partial_len = sizeof(struct rte_ipv6_hdr); + else + return -EINVAL; if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) { lp->partial_len += sizeof(struct rte_esp_hdr); @@ -203,6 +208,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev, struct otx2_ipsec_po_out_sa *sa; struct otx2_sec_session *sess; struct otx2_cpt_inst_s inst; + struct rte_ipv6_hdr *ip6; struct rte_ipv4_hdr *ip; int ret; @@ -222,6 +228,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev, lp->ip_id = 0; lp->seq_lo = 1; lp->seq_hi = 0; + lp->tunnel_type = ipsec->tunnel.type; ret = ipsec_po_sa_ctl_set(ipsec, crypto_xform, ctl); if (ret) @@ -254,6 +261,24 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev, sizeof(struct in_addr)); memcpy(&ip->dst_addr, &ipsec->tunnel.ipv4.dst_ip, sizeof(struct in_addr)); + } else if (ipsec->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV6) { + ip6 = &sa->template.ipv6_hdr; + ip6->vtc_flow = rte_cpu_to_be_32(0x60000000 | + ((ipsec->tunnel.ipv6.dscp << + RTE_IPV6_HDR_TC_SHIFT) & + RTE_IPV6_HDR_TC_MASK) | + ((ipsec->tunnel.ipv6.flabel << + RTE_IPV6_HDR_FL_SHIFT) & + RTE_IPV6_HDR_FL_MASK)); + ip6->hop_limits = ipsec->tunnel.ipv6.hlimit; + ip6->proto = (ipsec->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : IPPROTO_AH; + memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr, + sizeof(struct in6_addr)); + memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr, + sizeof(struct in6_addr)); } else { return -EINVAL; } @@ -342,6 +367,7 @@ crypto_sec_ipsec_inb_session_create(struct rte_cryptodev *crypto_dev, if (ret) return ret; + lp->tunnel_type = ipsec->tunnel.type; auth_xform = crypto_xform; cipher_xform = crypto_xform->next; diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_sec.h b/drivers/crypto/octeontx2/otx2_cryptodev_sec.h index b989251e71..b4a39d2fe4 100644 --- a/drivers/crypto/octeontx2/otx2_cryptodev_sec.h +++ b/drivers/crypto/octeontx2/otx2_cryptodev_sec.h @@ -55,6 +55,8 @@ struct otx2_sec_session_ipsec_lp { uint8_t iv_length; /** Auth IV length in bytes */ uint8_t auth_iv_length; + /** IPsec tunnel type */ + enum rte_security_ipsec_tunnel_type tunnel_type; }; int otx2_crypto_sec_ctx_create(struct rte_cryptodev *crypto_dev); diff --git a/drivers/crypto/octeontx2/otx2_ipsec_po.h b/drivers/crypto/octeontx2/otx2_ipsec_po.h index 020748609e..da24f6a5d4 100644 --- a/drivers/crypto/octeontx2/otx2_ipsec_po.h +++ b/drivers/crypto/octeontx2/otx2_ipsec_po.h @@ -319,7 +319,7 @@ ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, return -EINVAL; } - ctl->inner_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_4; + ctl->inner_ip_ver = ctl->outer_ip_ver; if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TRANSPORT; diff --git a/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h b/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h index dd29c413d3..5dd0b391a9 100644 --- a/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h +++ b/drivers/crypto/octeontx2/otx2_ipsec_po_ops.h @@ -25,7 +25,8 @@ otx2_ipsec_po_out_rlen_get(struct otx2_sec_session_ipsec_lp *sess, } static __rte_always_inline struct cpt_request_info * -alloc_request_struct(char *maddr, void *cop, int mdata_len) +alloc_request_struct(char *maddr, void *cop, int mdata_len, + enum rte_security_ipsec_tunnel_type tunnel_type) { struct cpt_request_info *req; struct cpt_meta_info *meta; @@ -47,6 +48,7 @@ alloc_request_struct(char *maddr, void *cop, int mdata_len) op[1] = (uintptr_t)cop; op[2] = (uintptr_t)req; op[3] = mdata_len; + op[4] = tunnel_type; return req; } @@ -86,7 +88,8 @@ process_outb_sa(struct rte_crypto_op *cop, } mdata += extend_tail; /* mdata follows encrypted data */ - req = alloc_request_struct(mdata, (void *)cop, mdata_len); + req = alloc_request_struct(mdata, (void *)cop, mdata_len, + sess->tunnel_type); data = rte_pktmbuf_prepend(m_src, extend_head); if (unlikely(data == NULL)) { @@ -157,7 +160,8 @@ process_inb_sa(struct rte_crypto_op *cop, goto exit; } - req = alloc_request_struct(mdata, (void *)cop, mdata_len); + req = alloc_request_struct(mdata, (void *)cop, mdata_len, + sess->tunnel_type); /* Prepare CPT instruction */ word0.u64 = sess->ucmd_w0; -- 2.20.1