]> git.droids-corp.org - dpdk.git/commitdiff
crypto/cnxk: move IPsec SA creation to common
authorVidya Sagar Velumuri <vvelumuri@marvell.com>
Mon, 20 Jun 2022 07:18:05 +0000 (12:48 +0530)
committerAkhil Goyal <gakhil@marvell.com>
Tue, 21 Jun 2022 18:04:50 +0000 (20:04 +0200)
Move the IPsec SA creation to common.
The code can be used by fastpath also to create the SAs
Add changes to support new full context microcode

Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Archana Muniganti <marchana@marvell.com>
Acked-by: Akhil Goyal <gakhil@marvell.com>
drivers/common/cnxk/cnxk_security.c
drivers/common/cnxk/cnxk_security.h
drivers/common/cnxk/roc_cpt.c
drivers/common/cnxk/roc_cpt.h
drivers/common/cnxk/roc_ie_on.h
drivers/common/cnxk/version.map
drivers/crypto/cnxk/cn9k_cryptodev_ops.c
drivers/crypto/cnxk/cn9k_ipsec.c
drivers/crypto/cnxk/cn9k_ipsec_la_ops.h
drivers/crypto/cnxk/cnxk_cryptodev_ops.h

index 72ee5ee91f8812681425f0ded52a9960e0b6ada8..dca8742be3d259e50a0bfde584362c8709b4f92e 100644 (file)
@@ -971,3 +971,401 @@ cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens,
        rlens->max_extended_len = partial_len + roundup_len + roundup_byte;
        return 0;
 }
+
+static inline int
+on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
+                   struct rte_crypto_sym_xform *crypto_xform,
+                   struct roc_ie_on_sa_ctl *ctl)
+{
+       struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
+       int aes_key_len = 0;
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+               auth_xform = crypto_xform;
+               cipher_xform = crypto_xform->next;
+       } else {
+               cipher_xform = crypto_xform;
+               auth_xform = crypto_xform->next;
+       }
+
+       if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
+               ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
+       else
+               ctl->direction = ROC_IE_SA_DIR_INBOUND;
+
+       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
+               if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
+                       ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
+               else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
+                       ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
+               else
+                       return -EINVAL;
+       }
+
+       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
+               ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
+               ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
+       } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
+               ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
+       else
+               return -EINVAL;
+
+       if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
+               ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH;
+       else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
+               ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
+       else
+               return -EINVAL;
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+               switch (crypto_xform->aead.algo) {
+               case RTE_CRYPTO_AEAD_AES_GCM:
+                       ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
+                       aes_key_len = crypto_xform->aead.key.length;
+                       break;
+               default:
+                       plt_err("Unsupported AEAD algorithm");
+                       return -ENOTSUP;
+               }
+       } else {
+               if (cipher_xform != NULL) {
+                       switch (cipher_xform->cipher.algo) {
+                       case RTE_CRYPTO_CIPHER_NULL:
+                               ctl->enc_type = ROC_IE_ON_SA_ENC_NULL;
+                               break;
+                       case RTE_CRYPTO_CIPHER_AES_CBC:
+                               ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC;
+                               aes_key_len = cipher_xform->cipher.key.length;
+                               break;
+                       case RTE_CRYPTO_CIPHER_AES_CTR:
+                               ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR;
+                               aes_key_len = cipher_xform->cipher.key.length;
+                               break;
+                       default:
+                               plt_err("Unsupported cipher algorithm");
+                               return -ENOTSUP;
+                       }
+               }
+
+               switch (auth_xform->auth.algo) {
+               case RTE_CRYPTO_AUTH_NULL:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
+                       break;
+               case RTE_CRYPTO_AUTH_MD5_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5;
+                       break;
+               case RTE_CRYPTO_AUTH_SHA1_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1;
+                       break;
+               case RTE_CRYPTO_AUTH_SHA224_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224;
+                       break;
+               case RTE_CRYPTO_AUTH_SHA256_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256;
+                       break;
+               case RTE_CRYPTO_AUTH_SHA384_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384;
+                       break;
+               case RTE_CRYPTO_AUTH_SHA512_HMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512;
+                       break;
+               case RTE_CRYPTO_AUTH_AES_GMAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC;
+                       aes_key_len = auth_xform->auth.key.length;
+                       break;
+               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+                       ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128;
+                       break;
+               default:
+                       plt_err("Unsupported auth algorithm");
+                       return -ENOTSUP;
+               }
+       }
+
+       /* Set AES key length */
+       if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CBC ||
+           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
+           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR ||
+           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
+           ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
+               switch (aes_key_len) {
+               case 16:
+                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
+                       break;
+               case 24:
+                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
+                       break;
+               case 32:
+                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
+                       break;
+               default:
+                       plt_err("Invalid AES key length");
+                       return -EINVAL;
+               }
+       }
+
+       if (ipsec->options.esn)
+               ctl->esn_en = 1;
+
+       if (ipsec->options.udp_encap == 1)
+               ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP;
+
+       ctl->copy_df = ipsec->options.copy_df;
+
+       ctl->spi = rte_cpu_to_be_32(ipsec->spi);
+
+       rte_io_wmb();
+
+       ctl->valid = 1;
+
+       return 0;
+}
+
+static inline int
+on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
+                       struct rte_crypto_sym_xform *crypto_xform,
+                       struct roc_ie_on_common_sa *common_sa)
+{
+       struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
+       const uint8_t *cipher_key;
+       int cipher_key_len = 0;
+       int ret;
+
+       ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl);
+       if (ret)
+               return ret;
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+               auth_xform = crypto_xform;
+               cipher_xform = crypto_xform->next;
+       } else {
+               cipher_xform = crypto_xform;
+               auth_xform = crypto_xform->next;
+       }
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+               if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
+                       memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
+               cipher_key = crypto_xform->aead.key.data;
+               cipher_key_len = crypto_xform->aead.key.length;
+       } else {
+               if (cipher_xform) {
+                       cipher_key = cipher_xform->cipher.key.data;
+                       cipher_key_len = cipher_xform->cipher.key.length;
+               }
+
+               if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
+                       memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
+                       cipher_key = auth_xform->auth.key.data;
+                       cipher_key_len = auth_xform->auth.key.length;
+               }
+       }
+
+       if (cipher_key_len != 0)
+               memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
+
+       return 0;
+}
+
+int
+cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
+                            struct rte_crypto_sym_xform *crypto_xform,
+                            struct roc_ie_on_outb_sa *out_sa)
+{
+       struct roc_ie_on_ip_template *template = NULL;
+       struct rte_crypto_sym_xform *auth_xform;
+       struct roc_ie_on_sa_ctl *ctl;
+       struct rte_ipv6_hdr *ip6;
+       struct rte_ipv4_hdr *ip4;
+       const uint8_t *auth_key;
+       int auth_key_len = 0;
+       size_t ctx_len;
+       int ret;
+
+       ctl = &out_sa->common_sa.ctl;
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
+               auth_xform = crypto_xform;
+       else
+               auth_xform = crypto_xform->next;
+
+       ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa);
+       if (ret)
+               return ret;
+
+       if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
+           ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL ||
+           ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
+               template = &out_sa->aes_gcm.template;
+               ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template);
+       } else {
+               switch (ctl->auth_type) {
+               case ROC_IE_ON_SA_AUTH_SHA1:
+                       template = &out_sa->sha1.template;
+                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
+                                          sha1.template);
+                       break;
+               case ROC_IE_ON_SA_AUTH_SHA2_256:
+               case ROC_IE_ON_SA_AUTH_SHA2_384:
+               case ROC_IE_ON_SA_AUTH_SHA2_512:
+                       template = &out_sa->sha2.template;
+                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
+                                          sha2.template);
+                       break;
+               case ROC_IE_ON_SA_AUTH_AES_XCBC_128:
+                       template = &out_sa->aes_xcbc.template;
+                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
+                                          aes_xcbc.template);
+                       break;
+               default:
+                       plt_err("Unsupported auth algorithm");
+                       return -EINVAL;
+               }
+       }
+
+       ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr;
+       if (ipsec->options.udp_encap) {
+               ip4->next_proto_id = IPPROTO_UDP;
+               template->ip4.udp_src = rte_be_to_cpu_16(4500);
+               template->ip4.udp_dst = rte_be_to_cpu_16(4500);
+       } else {
+               if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
+                       ip4->next_proto_id = IPPROTO_AH;
+               else
+                       ip4->next_proto_id = IPPROTO_ESP;
+       }
+
+       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
+               if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
+                       uint16_t frag_off = 0;
+
+                       ctx_len += sizeof(template->ip4);
+
+                       ip4->version_ihl = RTE_IPV4_VHL_DEF;
+                       ip4->time_to_live = ipsec->tunnel.ipv4.ttl;
+                       ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
+                       if (ipsec->tunnel.ipv4.df)
+                               frag_off |= RTE_IPV4_HDR_DF_FLAG;
+                       ip4->fragment_offset = rte_cpu_to_be_16(frag_off);
+
+                       memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip,
+                              sizeof(struct in_addr));
+                       memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip,
+                              sizeof(struct in_addr));
+               } else if (ipsec->tunnel.type ==
+                          RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
+                       ctx_len += sizeof(template->ip6);
+
+                       ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr;
+                       if (ipsec->options.udp_encap) {
+                               ip6->proto = IPPROTO_UDP;
+                               template->ip6.udp_src = rte_be_to_cpu_16(4500);
+                               template->ip6.udp_dst = rte_be_to_cpu_16(4500);
+                       } else {
+                               ip6->proto = (ipsec->proto ==
+                                             RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
+                                                    IPPROTO_ESP :
+                                                    IPPROTO_AH;
+                       }
+                       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;
+                       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
+               ctx_len += sizeof(template->ip4);
+
+       ctx_len += RTE_ALIGN_CEIL(ctx_len, 8);
+
+       if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
+               auth_key = auth_xform->auth.key.data;
+               auth_key_len = auth_xform->auth.key.length;
+
+               switch (auth_xform->auth.algo) {
+               case RTE_CRYPTO_AUTH_AES_GMAC:
+               case RTE_CRYPTO_AUTH_NULL:
+                       break;
+               case RTE_CRYPTO_AUTH_SHA1_HMAC:
+                       memcpy(out_sa->sha1.hmac_key, auth_key, auth_key_len);
+                       break;
+               case RTE_CRYPTO_AUTH_SHA256_HMAC:
+               case RTE_CRYPTO_AUTH_SHA384_HMAC:
+               case RTE_CRYPTO_AUTH_SHA512_HMAC:
+                       memcpy(out_sa->sha2.hmac_key, auth_key, auth_key_len);
+                       break;
+               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+                       memcpy(out_sa->aes_xcbc.key, auth_key, auth_key_len);
+                       break;
+               default:
+                       plt_err("Unsupported auth algorithm %u",
+                               auth_xform->auth.algo);
+                       return -ENOTSUP;
+               }
+       }
+
+       return ctx_len;
+}
+
+int
+cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec,
+                           struct rte_crypto_sym_xform *crypto_xform,
+                           struct roc_ie_on_inb_sa *in_sa)
+{
+       struct rte_crypto_sym_xform *auth_xform = crypto_xform;
+       const uint8_t *auth_key;
+       int auth_key_len = 0;
+       size_t ctx_len = 0;
+       int ret;
+
+       ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa);
+       if (ret)
+               return ret;
+
+       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD ||
+           auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL ||
+           auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
+               ctx_len = offsetof(struct roc_ie_on_inb_sa,
+                                  sha1_or_gcm.hmac_key[0]);
+       } else {
+               auth_key = auth_xform->auth.key.data;
+               auth_key_len = auth_xform->auth.key.length;
+
+               switch (auth_xform->auth.algo) {
+               case RTE_CRYPTO_AUTH_NULL:
+                       break;
+               case RTE_CRYPTO_AUTH_SHA1_HMAC:
+                       memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key,
+                              auth_key_len);
+                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
+                                          sha1_or_gcm.selector);
+                       break;
+               case RTE_CRYPTO_AUTH_SHA256_HMAC:
+               case RTE_CRYPTO_AUTH_SHA384_HMAC:
+               case RTE_CRYPTO_AUTH_SHA512_HMAC:
+                       memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len);
+                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
+                                          sha2.selector);
+                       break;
+               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+                       memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len);
+                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
+                                          aes_xcbc.selector);
+                       break;
+               default:
+                       plt_err("Unsupported auth algorithm %u",
+                               auth_xform->auth.algo);
+                       return -ENOTSUP;
+               }
+       }
+
+       return ctx_len;
+}
index 02cdad269c90eef566561ff3a6dcec095512f618..4e477ec53ff2031eda3456d30f06c8260c2339e2 100644 (file)
@@ -59,4 +59,15 @@ cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa,
 bool __roc_api cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa);
 bool __roc_api cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa);
 
+/* [CN9K] */
+int __roc_api
+cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec,
+                           struct rte_crypto_sym_xform *crypto_xform,
+                           struct roc_ie_on_inb_sa *in_sa);
+
+int __roc_api
+cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
+                            struct rte_crypto_sym_xform *crypto_xform,
+                            struct roc_ie_on_outb_sa *out_sa);
+
 #endif /* _CNXK_SECURITY_H__ */
index 742723ad1d40424233509c3b870c8c0f1872a516..e5b179e8e1173f70e3ce2f99fc3ab5bc934583b3 100644 (file)
@@ -981,3 +981,96 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
 
        return 0;
 }
+
+int
+roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa, uint8_t opcode,
+                    uint16_t ctx_len, uint8_t egrp)
+{
+       union cpt_res_s res, *hw_res;
+       struct cpt_inst_s inst;
+       uint64_t lmt_status;
+       int ret = 0;
+
+       hw_res = plt_zmalloc(sizeof(*hw_res), ROC_CPT_RES_ALIGN);
+       if (unlikely(hw_res == NULL)) {
+               plt_err("Couldn't allocate memory for result address");
+               return -ENOMEM;
+       }
+
+       hw_res->cn9k.compcode = CPT_COMP_NOT_DONE;
+
+       inst.w4.s.opcode_major = opcode;
+       inst.w4.s.opcode_minor = ctx_len >> 3;
+       inst.w4.s.param1 = 0;
+       inst.w4.s.param2 = 0;
+       inst.w4.s.dlen = ctx_len;
+       inst.dptr = rte_mempool_virt2iova(sa);
+       inst.rptr = 0;
+       inst.w7.s.cptr = rte_mempool_virt2iova(sa);
+       inst.w7.s.egrp = egrp;
+
+       inst.w0.u64 = 0;
+       inst.w2.u64 = 0;
+       inst.w3.u64 = 0;
+       inst.res_addr = (uintptr_t)hw_res;
+
+       rte_io_wmb();
+
+       do {
+               /* Copy CPT command to LMTLINE */
+               roc_lmt_mov64((void *)lf->lmt_base, &inst);
+               lmt_status = roc_lmt_submit_ldeor(lf->io_addr);
+       } while (lmt_status == 0);
+
+       const uint64_t timeout = plt_tsc_cycles() + 60 * plt_tsc_hz();
+
+       /* Wait until CPT instruction completes */
+       do {
+               res.u64[0] = __atomic_load_n(&hw_res->u64[0], __ATOMIC_RELAXED);
+               if (unlikely(plt_tsc_cycles() > timeout)) {
+                       plt_err("Request timed out");
+                       ret = -ETIMEDOUT;
+                       goto free;
+               }
+       } while (res.cn9k.compcode == CPT_COMP_NOT_DONE);
+
+       if (unlikely(res.cn9k.compcode != CPT_COMP_GOOD)) {
+               ret = res.cn9k.compcode;
+               switch (ret) {
+               case CPT_COMP_INSTERR:
+                       plt_err("Request failed with instruction error");
+                       break;
+               case CPT_COMP_FAULT:
+                       plt_err("Request failed with DMA fault");
+                       break;
+               case CPT_COMP_HWERR:
+                       plt_err("Request failed with hardware error");
+                       break;
+               default:
+                       plt_err("Request failed with unknown hardware completion code : 0x%x",
+                               ret);
+               }
+               ret = -EINVAL;
+               goto free;
+       }
+
+       if (unlikely(res.cn9k.uc_compcode != ROC_IE_ON_UCC_SUCCESS)) {
+               ret = res.cn9k.uc_compcode;
+               switch (ret) {
+               case ROC_IE_ON_AUTH_UNSUPPORTED:
+                       plt_err("Invalid auth type");
+                       break;
+               case ROC_IE_ON_ENCRYPT_UNSUPPORTED:
+                       plt_err("Invalid encrypt type");
+                       break;
+               default:
+                       plt_err("Request failed with unknown microcode completion code : 0x%x",
+                               ret);
+               }
+               ret = -ENOTSUP;
+       }
+
+free:
+       plt_free(hw_res);
+       return ret;
+}
index 99cb8b2862591f10561f2a342676223d19a548ef..1b2032b547769e2c2ac7d2df48f77e374c11b082 100644 (file)
@@ -181,4 +181,7 @@ void __roc_api roc_cpt_parse_hdr_dump(const struct cpt_parse_hdr_s *cpth);
 int __roc_api roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr,
                                void *sa_cptr, uint16_t sa_len);
 
+int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa,
+                                  uint8_t opcode, uint16_t ctx_len,
+                                  uint8_t egrp);
 #endif /* _ROC_CPT_H_ */
index 7dd7b6595f970f0aba57e200451c42321839f4d5..37f711c643d0e9042d5769950caf82a380715fce 100644 (file)
@@ -23,7 +23,7 @@ enum roc_ie_on_ucc_ipsec {
 };
 
 /* Helper macros */
-#define ROC_IE_ON_INB_RPTR_HDR 0x8
+#define ROC_IE_ON_INB_RPTR_HDR 16
 #define ROC_IE_ON_MAX_IV_LEN   16
 #define ROC_IE_ON_PER_PKT_IV   BIT(43)
 
@@ -67,9 +67,17 @@ enum {
 struct roc_ie_on_outb_hdr {
        uint32_t ip_id;
        uint32_t seq;
+       uint32_t esn;
+       uint32_t df_tos;
        uint8_t iv[16];
 };
 
+struct roc_ie_on_inb_hdr {
+       uint32_t sa_index;
+       uint64_t seq;
+       uint32_t pad;
+};
+
 union roc_ie_on_bit_perfect_iv {
        uint8_t aes_iv[16];
        uint8_t des_iv[8];
@@ -113,7 +121,7 @@ struct roc_ie_on_ip_template {
 union roc_on_ipsec_outb_param1 {
        uint16_t u16;
        struct {
-               uint16_t frag_num : 4;
+               uint16_t l2hdr_len : 4;
                uint16_t rsvd_4_6 : 3;
                uint16_t gre_select : 1;
                uint16_t dsiv : 1;
@@ -171,8 +179,13 @@ struct roc_ie_on_common_sa {
        union roc_ie_on_bit_perfect_iv iv;
 
        /* w7 */
-       uint32_t esn_hi;
-       uint32_t esn_low;
+       union {
+               uint64_t u64;
+               struct {
+                       uint32_t th;
+                       uint32_t tl;
+               };
+       } seq_t;
 };
 
 struct roc_ie_on_outb_sa {
index d5fd1f41c25aaae38cd6f7f22b1eb7885b4c5d87..19cfd007083910630d1acdbe1dd02d6bfd47879f 100644 (file)
@@ -23,6 +23,8 @@ INTERNAL {
        cnxk_ot_ipsec_outb_sa_fill;
        cnxk_ot_ipsec_inb_sa_valid;
        cnxk_ot_ipsec_outb_sa_valid;
+       cnxk_on_ipsec_inb_sa_create;
+       cnxk_on_ipsec_outb_sa_create;
        roc_ae_ec_grp_get;
        roc_ae_ec_grp_put;
        roc_ae_fpm_get;
@@ -75,6 +77,7 @@ INTERNAL {
        roc_cpt_parse_hdr_dump;
        roc_cpt_rxc_time_cfg;
        roc_cpt_ctx_write;
+       roc_on_cpt_ctx_write;
        roc_dpi_configure;
        roc_dpi_dev_fini;
        roc_dpi_dev_init;
index eccaf398dfd35e729f3652fb2843d656c0eaed07..77207301204ad1742ae70f5367d4dc12a649f179 100644 (file)
@@ -43,7 +43,9 @@ cn9k_cpt_sec_inst_fill(struct rte_crypto_op *op,
                       struct cpt_inst_s *inst)
 {
        struct rte_crypto_sym_op *sym_op = op->sym;
+       struct roc_ie_on_common_sa *common_sa;
        struct cn9k_sec_session *priv;
+       struct roc_ie_on_sa_ctl *ctl;
        struct cn9k_ipsec_sa *sa;
 
        if (unlikely(sym_op->m_dst && sym_op->m_dst != sym_op->m_src)) {
@@ -64,6 +66,12 @@ cn9k_cpt_sec_inst_fill(struct rte_crypto_op *op,
 
        infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_DIR_INBOUND;
 
+       common_sa = &sa->in_sa.common_sa;
+       ctl = &common_sa->ctl;
+
+       if (ctl->esn_en)
+               infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_INB_ESN;
+
        return process_inb_sa(op, sa, inst);
 }
 
@@ -491,14 +499,28 @@ cn9k_cpt_sec_post_process(struct rte_crypto_op *cop,
 {
        struct rte_crypto_sym_op *sym_op = cop->sym;
        struct rte_mbuf *m = sym_op->m_src;
+       struct cn9k_sec_session *priv;
+       struct cn9k_ipsec_sa *sa;
        struct rte_ipv6_hdr *ip6;
        struct rte_ipv4_hdr *ip;
        uint16_t m_len = 0;
        char *data;
 
+       priv = get_sec_session_private_data(cop->sym->sec_session);
+       sa = &priv->sa;
+
        if (infl_req->op_flags & CPT_OP_FLAGS_IPSEC_DIR_INBOUND) {
+               struct roc_ie_on_common_sa *common_sa = &sa->in_sa.common_sa;
+
                data = rte_pktmbuf_mtod(m, char *);
+               if (infl_req->op_flags == CPT_OP_FLAGS_IPSEC_INB_ESN) {
+                       struct roc_ie_on_inb_hdr *inb_hdr =
+                               (struct roc_ie_on_inb_hdr *)data;
+                       uint64_t seq = rte_be_to_cpu_64(inb_hdr->seq);
 
+                       if (seq > common_sa->seq_t.u64)
+                               common_sa->seq_t.u64 = seq;
+               }
                ip = (struct rte_ipv4_hdr *)(data + ROC_IE_ON_INB_RPTR_HDR);
 
                if (((ip->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER) ==
@@ -515,6 +537,8 @@ cn9k_cpt_sec_post_process(struct rte_crypto_op *cop,
                m->data_len = m_len;
                m->pkt_len = m_len;
                m->data_off += ROC_IE_ON_INB_RPTR_HDR;
+       } else {
+               rte_pktmbuf_adj(m, sa->custom_hdr_len);
        }
 }
 
index 82b8dae78653d2e93a8568170b754bc74c92bfcd..85f3f26c325bbb87fb61bac24017886804d9190f 100644 (file)
 
 #include "roc_api.h"
 
-static inline int
-cn9k_cpt_enq_sa_write(struct cn9k_ipsec_sa *sa, struct cnxk_cpt_qp *qp,
-                     uint8_t opcode, size_t ctx_len)
-{
-       struct roc_cpt *roc_cpt = qp->lf.roc_cpt;
-       uint64_t lmtline = qp->lmtline.lmt_base;
-       uint64_t io_addr = qp->lmtline.io_addr;
-       uint64_t lmt_status, time_out;
-       struct cpt_cn9k_res_s *res;
-       struct cpt_inst_s inst;
-       uint64_t *mdata;
-       int ret = 0;
-
-       if (unlikely(rte_mempool_get(qp->meta_info.pool, (void **)&mdata) < 0))
-               return -ENOMEM;
-
-       res = (struct cpt_cn9k_res_s *)RTE_PTR_ALIGN(mdata, 16);
-       res->compcode = CPT_COMP_NOT_DONE;
-
-       inst.w4.s.opcode_major = opcode;
-       inst.w4.s.opcode_minor = ctx_len >> 3;
-       inst.w4.s.param1 = 0;
-       inst.w4.s.param2 = 0;
-       inst.w4.s.dlen = ctx_len;
-       inst.dptr = rte_mempool_virt2iova(sa);
-       inst.rptr = 0;
-       inst.w7.s.cptr = rte_mempool_virt2iova(sa);
-       inst.w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
-
-       inst.w0.u64 = 0;
-       inst.w2.u64 = 0;
-       inst.w3.u64 = 0;
-       inst.res_addr = rte_mempool_virt2iova(res);
-
-       rte_io_wmb();
-
-       do {
-               /* Copy CPT command to LMTLINE */
-               roc_lmt_mov64((void *)lmtline, &inst);
-               lmt_status = roc_lmt_submit_ldeor(io_addr);
-       } while (lmt_status == 0);
-
-       time_out = rte_get_timer_cycles() +
-                  DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
-
-       while (res->compcode == CPT_COMP_NOT_DONE) {
-               if (rte_get_timer_cycles() > time_out) {
-                       rte_mempool_put(qp->meta_info.pool, mdata);
-                       plt_err("Request timed out");
-                       return -ETIMEDOUT;
-               }
-               rte_io_rmb();
-       }
-
-       if (unlikely(res->compcode != CPT_COMP_GOOD)) {
-               ret = res->compcode;
-               switch (ret) {
-               case CPT_COMP_INSTERR:
-                       plt_err("Request failed with instruction error");
-                       break;
-               case CPT_COMP_FAULT:
-                       plt_err("Request failed with DMA fault");
-                       break;
-               case CPT_COMP_HWERR:
-                       plt_err("Request failed with hardware error");
-                       break;
-               default:
-                       plt_err("Request failed with unknown hardware "
-                               "completion code : 0x%x",
-                               ret);
-               }
-               ret = -EINVAL;
-               goto mempool_put;
-       }
-
-       if (unlikely(res->uc_compcode != ROC_IE_ON_UCC_SUCCESS)) {
-               ret = res->uc_compcode;
-               switch (ret) {
-               case ROC_IE_ON_AUTH_UNSUPPORTED:
-                       plt_err("Invalid auth type");
-                       break;
-               case ROC_IE_ON_ENCRYPT_UNSUPPORTED:
-                       plt_err("Invalid encrypt type");
-                       break;
-               default:
-                       plt_err("Request failed with unknown microcode "
-                               "completion code : 0x%x",
-                               ret);
-               }
-               ret = -ENOTSUP;
-       }
-
-mempool_put:
-       rte_mempool_put(qp->meta_info.pool, mdata);
-       return ret;
-}
-
-static inline int
-ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
-                struct rte_crypto_sym_xform *crypto_xform,
-                struct roc_ie_on_sa_ctl *ctl)
-{
-       struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
-       int aes_key_len = 0;
-
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
-               auth_xform = crypto_xform;
-               cipher_xform = crypto_xform->next;
-       } else {
-               cipher_xform = crypto_xform;
-               auth_xform = crypto_xform->next;
-       }
-
-       if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
-               ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
-       else
-               ctl->direction = ROC_IE_SA_DIR_INBOUND;
-
-       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
-               if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
-                       ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
-               else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
-                       ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
-               else
-                       return -EINVAL;
-       }
-
-       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
-               ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
-               ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
-       } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
-               ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
-       else
-               return -EINVAL;
-
-       if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
-               ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH;
-       else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
-               ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
-       else
-               return -EINVAL;
-
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
-               switch (crypto_xform->aead.algo) {
-               case RTE_CRYPTO_AEAD_AES_GCM:
-                       ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
-                       aes_key_len = crypto_xform->aead.key.length;
-                       break;
-               default:
-                       plt_err("Unsupported AEAD algorithm");
-                       return -ENOTSUP;
-               }
-       } else {
-               if (cipher_xform != NULL) {
-                       switch (cipher_xform->cipher.algo) {
-                       case RTE_CRYPTO_CIPHER_NULL:
-                               ctl->enc_type = ROC_IE_ON_SA_ENC_NULL;
-                               break;
-                       case RTE_CRYPTO_CIPHER_AES_CBC:
-                               ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC;
-                               aes_key_len = cipher_xform->cipher.key.length;
-                               break;
-                       case RTE_CRYPTO_CIPHER_AES_CTR:
-                               ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR;
-                               aes_key_len = cipher_xform->cipher.key.length;
-                               break;
-                       default:
-                               plt_err("Unsupported cipher algorithm");
-                               return -ENOTSUP;
-                       }
-               }
-
-               switch (auth_xform->auth.algo) {
-               case RTE_CRYPTO_AUTH_NULL:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
-                       break;
-               case RTE_CRYPTO_AUTH_MD5_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5;
-                       break;
-               case RTE_CRYPTO_AUTH_SHA1_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1;
-                       break;
-               case RTE_CRYPTO_AUTH_SHA224_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224;
-                       break;
-               case RTE_CRYPTO_AUTH_SHA256_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256;
-                       break;
-               case RTE_CRYPTO_AUTH_SHA384_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384;
-                       break;
-               case RTE_CRYPTO_AUTH_SHA512_HMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512;
-                       break;
-               case RTE_CRYPTO_AUTH_AES_GMAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC;
-                       aes_key_len = auth_xform->auth.key.length;
-                       break;
-               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
-                       ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128;
-                       break;
-               default:
-                       plt_err("Unsupported auth algorithm");
-                       return -ENOTSUP;
-               }
-       }
-
-       /* Set AES key length */
-       if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CBC ||
-           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
-           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR ||
-           ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
-           ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
-               switch (aes_key_len) {
-               case 16:
-                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
-                       break;
-               case 24:
-                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
-                       break;
-               case 32:
-                       ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
-                       break;
-               default:
-                       plt_err("Invalid AES key length");
-                       return -EINVAL;
-               }
-       }
-
-       if (ipsec->options.esn)
-               ctl->esn_en = 1;
-
-       if (ipsec->options.udp_encap == 1)
-               ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP;
-
-       ctl->copy_df = ipsec->options.copy_df;
-
-       ctl->spi = rte_cpu_to_be_32(ipsec->spi);
-
-       rte_io_wmb();
-
-       ctl->valid = 1;
-
-       return 0;
-}
-
-static inline int
-fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
-                    struct rte_crypto_sym_xform *crypto_xform,
-                    struct roc_ie_on_common_sa *common_sa)
-{
-       struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
-       const uint8_t *cipher_key;
-       int cipher_key_len = 0;
-       int ret;
-
-       ret = ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl);
-       if (ret)
-               return ret;
-
-       if (ipsec->esn.value) {
-               common_sa->esn_low = ipsec->esn.low;
-               common_sa->esn_hi = ipsec->esn.hi;
-       }
-
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
-               auth_xform = crypto_xform;
-               cipher_xform = crypto_xform->next;
-       } else {
-               cipher_xform = crypto_xform;
-               auth_xform = crypto_xform->next;
-       }
-
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
-               if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
-                       memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
-               cipher_key = crypto_xform->aead.key.data;
-               cipher_key_len = crypto_xform->aead.key.length;
-       } else {
-               if (cipher_xform) {
-                       cipher_key = cipher_xform->cipher.key.data;
-                       cipher_key_len = cipher_xform->cipher.key.length;
-               }
-
-               if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
-                       memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
-                       cipher_key = auth_xform->auth.key.data;
-                       cipher_key_len = auth_xform->auth.key.length;
-               }
-       }
-
-       if (cipher_key_len != 0)
-               memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
-
-       return 0;
-}
-
 static int
 cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
                          struct rte_security_ipsec_xform *ipsec,
                          struct rte_crypto_sym_xform *crypto_xform,
                          struct rte_security_session *sec_sess)
 {
-       struct roc_ie_on_ip_template *template = NULL;
        struct roc_cpt *roc_cpt = qp->lf.roc_cpt;
-       struct rte_crypto_sym_xform *auth_xform;
        union roc_on_ipsec_outb_param1 param1;
        struct cnxk_cpt_inst_tmpl *inst_tmpl;
-       struct roc_ie_on_outb_sa *out_sa;
        struct cn9k_sec_session *sess;
-       struct roc_ie_on_sa_ctl *ctl;
        struct cn9k_ipsec_sa *sa;
-       struct rte_ipv6_hdr *ip6;
-       struct rte_ipv4_hdr *ip4;
-       const uint8_t *auth_key;
        union cpt_inst_w4 w4;
        union cpt_inst_w7 w7;
-       int auth_key_len = 0;
        size_t ctx_len;
+       uint8_t opcode;
+       uint8_t egrp;
        int ret;
 
        sess = get_sec_session_private_data(sec_sess);
        sa = &sess->sa;
-       out_sa = &sa->out_sa;
-       ctl = &out_sa->common_sa.ctl;
 
        memset(sa, 0, sizeof(struct cn9k_ipsec_sa));
 
@@ -353,153 +48,16 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
        if (ipsec->esn.value)
                sa->esn = ipsec->esn.value;
 
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
-               auth_xform = crypto_xform;
-       else
-               auth_xform = crypto_xform->next;
-
-       ret = fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa);
-       if (ret)
-               return ret;
-
        ret = cnxk_ipsec_outb_rlens_get(&sa->rlens, ipsec, crypto_xform);
        if (ret)
                return ret;
 
-       if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
-           ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL ||
-           ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
-               template = &out_sa->aes_gcm.template;
-               ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template);
-       } else {
-               switch (ctl->auth_type) {
-               case ROC_IE_ON_SA_AUTH_SHA1:
-                       template = &out_sa->sha1.template;
-                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
-                                          sha1.template);
-                       break;
-               case ROC_IE_ON_SA_AUTH_SHA2_256:
-               case ROC_IE_ON_SA_AUTH_SHA2_384:
-               case ROC_IE_ON_SA_AUTH_SHA2_512:
-                       template = &out_sa->sha2.template;
-                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
-                                          sha2.template);
-                       break;
-               case ROC_IE_ON_SA_AUTH_AES_XCBC_128:
-                       template = &out_sa->aes_xcbc.template;
-                       ctx_len = offsetof(struct roc_ie_on_outb_sa,
-                                          aes_xcbc.template);
-                       break;
-               default:
-                       plt_err("Unsupported auth algorithm");
-                       return -EINVAL;
-               }
-       }
-
-       ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr;
-       if (ipsec->options.udp_encap) {
-               ip4->next_proto_id = IPPROTO_UDP;
-               template->ip4.udp_src = rte_be_to_cpu_16(4500);
-               template->ip4.udp_dst = rte_be_to_cpu_16(4500);
-       } else {
-               if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
-                       ip4->next_proto_id = IPPROTO_AH;
-               else
-                       ip4->next_proto_id = IPPROTO_ESP;
-       }
-
-       if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
-               if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
-                       uint16_t frag_off = 0;
-                       ctx_len += sizeof(template->ip4);
-
-                       ip4->version_ihl = RTE_IPV4_VHL_DEF;
-                       ip4->time_to_live = ipsec->tunnel.ipv4.ttl;
-                       ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
-                       if (ipsec->tunnel.ipv4.df)
-                               frag_off |= RTE_IPV4_HDR_DF_FLAG;
-                       ip4->fragment_offset = rte_cpu_to_be_16(frag_off);
-
-                       memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip,
-                              sizeof(struct in_addr));
-                       memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip,
-                              sizeof(struct in_addr));
-               } else if (ipsec->tunnel.type ==
-                          RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
-                       ctx_len += sizeof(template->ip6);
-
-                       ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr;
-                       if (ipsec->options.udp_encap) {
-                               ip6->proto = IPPROTO_UDP;
-                               template->ip6.udp_src = rte_be_to_cpu_16(4500);
-                               template->ip6.udp_dst = rte_be_to_cpu_16(4500);
-                       } else {
-                               ip6->proto = (ipsec->proto ==
-                                             RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
-                                                    IPPROTO_ESP :
-                                                    IPPROTO_AH;
-                       }
-                       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;
-                       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
-               ctx_len += sizeof(template->ip4);
-
-       ctx_len += RTE_ALIGN_CEIL(ctx_len, 8);
-
-       if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
-               auth_key = auth_xform->auth.key.data;
-               auth_key_len = auth_xform->auth.key.length;
-
-               switch (auth_xform->auth.algo) {
-               case RTE_CRYPTO_AUTH_AES_GMAC:
-               case RTE_CRYPTO_AUTH_NULL:
-                       break;
-               case RTE_CRYPTO_AUTH_SHA1_HMAC:
-                       memcpy(out_sa->sha1.hmac_key, auth_key, auth_key_len);
-                       break;
-               case RTE_CRYPTO_AUTH_SHA256_HMAC:
-               case RTE_CRYPTO_AUTH_SHA384_HMAC:
-               case RTE_CRYPTO_AUTH_SHA512_HMAC:
-                       memcpy(out_sa->sha2.hmac_key, auth_key, auth_key_len);
-                       break;
-               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
-                       memcpy(out_sa->aes_xcbc.key, auth_key, auth_key_len);
-                       break;
-               default:
-                       plt_err("Unsupported auth algorithm %u",
-                               auth_xform->auth.algo);
-                       return -ENOTSUP;
-               }
-       }
-
-       inst_tmpl = &sa->inst;
-
-       w4.u64 = 0;
-       w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC;
-       w4.s.opcode_minor = ctx_len >> 3;
-
-       param1.u16 = 0;
-       param1.s.ikev2 = 1;
-
-       sa->custom_hdr_len = sizeof(struct roc_ie_on_outb_hdr) -
-                            ROC_IE_ON_MAX_IV_LEN;
+       sa->custom_hdr_len =
+               sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN;
 
 #ifdef LA_IPSEC_DEBUG
        /* Use IV from application in debug mode */
        if (ipsec->options.iv_gen_disable == 1) {
-               param1.s.per_pkt_iv = ROC_IE_ON_IV_SRC_FROM_DPTR;
                sa->custom_hdr_len = sizeof(struct roc_ie_on_outb_hdr);
 
                if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
@@ -520,17 +78,49 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp,
        }
 #endif
 
-       w4.s.param1 = param1.u16;
+       ret = cnxk_on_ipsec_outb_sa_create(ipsec, crypto_xform, &sa->out_sa);
 
-       inst_tmpl->w4 = w4.u64;
+       if (ret < 0)
+               return ret;
+
+       ctx_len = ret;
+       opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND;
+       egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
+       ret = roc_on_cpt_ctx_write(&qp->lf, (void *)&sa->out_sa, opcode,
+                                  ctx_len, egrp);
+
+       if (ret)
+               return ret;
+
+       w4.u64 = 0;
+       w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC;
+       w4.s.opcode_minor = ctx_len >> 3;
+
+       param1.u16 = 0;
+       param1.s.ikev2 = 1;
+
+#ifdef LA_IPSEC_DEBUG
+       /* Use IV from application in debug mode */
+       if (ipsec->options.iv_gen_disable == 1)
+               param1.s.per_pkt_iv = ROC_IE_ON_IV_SRC_FROM_DPTR;
+#else
+       if (ipsec->options.iv_gen_disable != 0) {
+               plt_err("Application provided IV is not supported");
+               return -ENOTSUP;
+       }
+#endif
+
+       w4.s.param1 = param1.u16;
 
        w7.u64 = 0;
-       w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
-       w7.s.cptr = rte_mempool_virt2iova(out_sa);
+       w7.s.egrp = egrp;
+       w7.s.cptr = rte_mempool_virt2iova(&sa->out_sa);
+
+       inst_tmpl = &sa->inst;
+       inst_tmpl->w4 = w4.u64;
        inst_tmpl->w7 = w7.u64;
 
-       return cn9k_cpt_enq_sa_write(
-               sa, qp, ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND, ctx_len);
+       return 0;
 }
 
 static int
@@ -539,71 +129,54 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
                         struct rte_crypto_sym_xform *crypto_xform,
                         struct rte_security_session *sec_sess)
 {
-       struct rte_crypto_sym_xform *auth_xform = crypto_xform;
        struct roc_cpt *roc_cpt = qp->lf.roc_cpt;
-       union roc_on_ipsec_inb_param2 param2;
        struct cnxk_cpt_inst_tmpl *inst_tmpl;
-       struct roc_ie_on_inb_sa *in_sa;
+       union roc_on_ipsec_inb_param2 param2;
        struct cn9k_sec_session *sess;
        struct cn9k_ipsec_sa *sa;
-       const uint8_t *auth_key;
        union cpt_inst_w4 w4;
        union cpt_inst_w7 w7;
-       int auth_key_len = 0;
        size_t ctx_len = 0;
-       int ret;
+       uint8_t opcode;
+       uint8_t egrp;
+       int ret = 0;
 
        sess = get_sec_session_private_data(sec_sess);
        sa = &sess->sa;
-       in_sa = &sa->in_sa;
 
        memset(sa, 0, sizeof(struct cn9k_ipsec_sa));
 
        sa->dir = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
        sa->replay_win_sz = ipsec->replay_win_sz;
 
-       ret = fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa);
-       if (ret)
-               return ret;
-
-       if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD ||
-           auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL ||
-           auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
-               ctx_len = offsetof(struct roc_ie_on_inb_sa,
-                                  sha1_or_gcm.hmac_key[0]);
-       } else {
-               auth_key = auth_xform->auth.key.data;
-               auth_key_len = auth_xform->auth.key.length;
-
-               switch (auth_xform->auth.algo) {
-               case RTE_CRYPTO_AUTH_NULL:
-                       break;
-               case RTE_CRYPTO_AUTH_SHA1_HMAC:
-                       memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key,
-                              auth_key_len);
-                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
-                                          sha1_or_gcm.selector);
-                       break;
-               case RTE_CRYPTO_AUTH_SHA256_HMAC:
-               case RTE_CRYPTO_AUTH_SHA384_HMAC:
-               case RTE_CRYPTO_AUTH_SHA512_HMAC:
-                       memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len);
-                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
-                                          sha2.selector);
-                       break;
-               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
-                       memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len);
-                       ctx_len = offsetof(struct roc_ie_on_inb_sa,
-                                          aes_xcbc.selector);
-                       break;
-               default:
-                       plt_err("Unsupported auth algorithm %u",
-                               auth_xform->auth.algo);
+       if (sa->replay_win_sz) {
+               if (sa->replay_win_sz > CNXK_ON_AR_WIN_SIZE_MAX) {
+                       plt_err("Replay window size:%u is not supported",
+                               sa->replay_win_sz);
                        return -ENOTSUP;
                }
+
+               /* Set window bottom to 1, base and top to size of window */
+               sa->ar.winb = 1;
+               sa->ar.wint = sa->replay_win_sz;
+               sa->ar.base = sa->replay_win_sz;
+
+               sa->in_sa.common_sa.seq_t.tl = sa->seq_lo;
+               sa->in_sa.common_sa.seq_t.th = sa->seq_hi;
        }
 
-       inst_tmpl = &sa->inst;
+       ret = cnxk_on_ipsec_inb_sa_create(ipsec, crypto_xform, &sa->in_sa);
+
+       if (ret < 0)
+               return ret;
+
+       ctx_len = ret;
+       opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND;
+       egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
+       ret = roc_on_cpt_ctx_write(&qp->lf, (void *)&sa->in_sa, opcode, ctx_len,
+                                  egrp);
+       if (ret)
+               return ret;
 
        w4.u64 = 0;
        w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC;
@@ -613,31 +186,14 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp,
        param2.s.ikev2 = 1;
        w4.s.param2 = param2.u16;
 
-       inst_tmpl->w4 = w4.u64;
+       w7.s.egrp = egrp;
+       w7.s.cptr = rte_mempool_virt2iova(&sa->in_sa);
 
-       w7.u64 = 0;
-       w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
-       w7.s.cptr = rte_mempool_virt2iova(in_sa);
+       inst_tmpl = &sa->inst;
+       inst_tmpl->w4 = w4.u64;
        inst_tmpl->w7 = w7.u64;
 
-       if (sa->replay_win_sz) {
-               if (sa->replay_win_sz > CNXK_ON_AR_WIN_SIZE_MAX) {
-                       plt_err("Replay window size:%u is not supported",
-                               sa->replay_win_sz);
-                       return -ENOTSUP;
-               }
-
-               /* Set window bottom to 1, base and top to size of window */
-               sa->ar.winb = 1;
-               sa->ar.wint = sa->replay_win_sz;
-               sa->ar.base = sa->replay_win_sz;
-
-               in_sa->common_sa.esn_low = sa->seq_lo;
-               in_sa->common_sa.esn_hi = sa->seq_hi;
-       }
-
-       return cn9k_cpt_enq_sa_write(
-               sa, qp, ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND, ctx_len);
+       return 0;
 }
 
 static inline int
index df89aaca4e5e9a57494b5bad090cfbba56e85066..bbb4404a89e3697e5807c6436e0ca19dc415feb2 100644 (file)
@@ -20,7 +20,7 @@ ipsec_po_out_rlen_get(struct cn9k_ipsec_sa *sa, uint32_t plen)
        enc_payload_len = RTE_ALIGN_CEIL(plen + sa->rlens.roundup_len,
                                         sa->rlens.roundup_byte);
 
-       return sa->rlens.partial_len + enc_payload_len;
+       return sa->custom_hdr_len + sa->rlens.partial_len + enc_payload_len;
 }
 
 static __rte_always_inline int
@@ -41,8 +41,8 @@ ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz,
        ctl = &common_sa->ctl;
 
        esn = ctl->esn_en;
-       esn_low = rte_be_to_cpu_32(common_sa->esn_low);
-       esn_hi = rte_be_to_cpu_32(common_sa->esn_hi);
+       esn_low = rte_be_to_cpu_32(common_sa->seq_t.tl);
+       esn_hi = rte_be_to_cpu_32(common_sa->seq_t.th);
 
        esp = rte_pktmbuf_mtod_offset(m, void *, sizeof(struct rte_ipv4_hdr));
        seql = rte_be_to_cpu_32(esp->seq);
@@ -62,8 +62,8 @@ ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz,
        if (esn && !ret) {
                seq_in_sa = ((uint64_t)esn_hi << 32) | esn_low;
                if (seq > seq_in_sa) {
-                       common_sa->esn_low = rte_cpu_to_be_32(seql);
-                       common_sa->esn_hi = rte_cpu_to_be_32(seqh);
+                       common_sa->seq_t.tl = rte_cpu_to_be_32(seql);
+                       common_sa->seq_t.th = rte_cpu_to_be_32(seqh);
                }
        }
 
@@ -77,13 +77,10 @@ process_outb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa,
        const unsigned int hdr_len = sa->custom_hdr_len;
        struct rte_crypto_sym_op *sym_op = cop->sym;
        struct rte_mbuf *m_src = sym_op->m_src;
-       struct roc_ie_on_outb_sa *out_sa;
        struct roc_ie_on_outb_hdr *hdr;
        uint32_t dlen, rlen;
        int32_t extend_tail;
 
-       out_sa = &sa->out_sa;
-
        dlen = rte_pktmbuf_pkt_len(m_src) + hdr_len;
        rlen = ipsec_po_out_rlen_get(sa, dlen - hdr_len);
 
@@ -114,8 +111,7 @@ process_outb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa,
 
        hdr->seq = rte_cpu_to_be_32(sa->seq_lo);
        hdr->ip_id = rte_cpu_to_be_32(sa->ip_id);
-
-       out_sa->common_sa.esn_hi = sa->seq_hi;
+       hdr->esn = rte_cpu_to_be_32(sa->seq_hi);
 
        sa->ip_id++;
        sa->esn++;
index 7ece0214dc1917a913cec38b716803193a114d26..ec99e6d660e03de9e84bee9837a6fb2d305fedc0 100644 (file)
@@ -33,6 +33,7 @@ struct cpt_qp_meta_info {
 #define CPT_OP_FLAGS_METABUF          (1 << 1)
 #define CPT_OP_FLAGS_AUTH_VERIFY       (1 << 0)
 #define CPT_OP_FLAGS_IPSEC_DIR_INBOUND (1 << 2)
+#define CPT_OP_FLAGS_IPSEC_INB_ESN     (1 << 3)
 
 struct cpt_inflight_req {
        union cpt_res_s res;