crypto/octeontx2: support lookaside IPsec IPv6
authorTejasree Kondoj <ktejasree@marvell.com>
Fri, 9 Oct 2020 10:03:28 +0000 (15:33 +0530)
committerAkhil Goyal <akhil.goyal@nxp.com>
Wed, 14 Oct 2020 19:35:22 +0000 (21:35 +0200)
Adding IPv6 tunnel mode support in lookaside IPsec PMD.

Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
Acked-by: Anoob Joseph <anoobj@marvell.com>
doc/guides/cryptodevs/octeontx2.rst
doc/guides/rel_notes/release_20_11.rst
drivers/crypto/octeontx2/otx2_cryptodev.h
drivers/crypto/octeontx2/otx2_cryptodev_ops.c
drivers/crypto/octeontx2/otx2_cryptodev_sec.c
drivers/crypto/octeontx2/otx2_cryptodev_sec.h
drivers/crypto/octeontx2/otx2_ipsec_po.h
drivers/crypto/octeontx2/otx2_ipsec_po_ops.h

index 432146d..b927c8f 100644 (file)
@@ -176,6 +176,7 @@ Features supported
 ~~~~~~~~~~~~~~~~~~
 
 * IPv4
+* IPv6
 * ESP
 * Tunnel mode
 * AES-128/192/256-GCM
index 27e68f3..bdadc44 100644 (file)
@@ -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
index fba7222..7b1b648 100644 (file)
@@ -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;
index d38365a..21ac122 100644 (file)
@@ -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;
index 72e6c41..b80ec7b 100644 (file)
@@ -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;
 
index b989251..b4a39d2 100644 (file)
@@ -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);
index 0207486..da24f6a 100644 (file)
@@ -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;
index dd29c41..5dd0b39 100644 (file)
@@ -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;