13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 25139d5d9SMarcin Smoczynski * Copyright(c) 2016-2020 Intel Corporation 3d299106eSSergio Gonzalez Monroy */ 455d4c775SDaniel Mrzyglod #include <sys/types.h> 5d299106eSSergio Gonzalez Monroy #include <netinet/in.h> 6d299106eSSergio Gonzalez Monroy #include <netinet/ip.h> 7d299106eSSergio Gonzalez Monroy 8d299106eSSergio Gonzalez Monroy #include <rte_branch_prediction.h> 96938fc92SVolodymyr Fialko #include <rte_event_crypto_adapter.h> 10d299106eSSergio Gonzalez Monroy #include <rte_log.h> 11d299106eSSergio Gonzalez Monroy #include <rte_crypto.h> 12ec17993aSAkhil Goyal #include <rte_security.h> 13d299106eSSergio Gonzalez Monroy #include <rte_cryptodev.h> 145139d5d9SMarcin Smoczynski #include <rte_ipsec.h> 15ec17993aSAkhil Goyal #include <rte_ethdev.h> 16d299106eSSergio Gonzalez Monroy #include <rte_mbuf.h> 17d299106eSSergio Gonzalez Monroy #include <rte_hash.h> 18d299106eSSergio Gonzalez Monroy 19d299106eSSergio Gonzalez Monroy #include "ipsec.h" 20c64278c0SSergio Gonzalez Monroy #include "esp.h" 21d299106eSSergio Gonzalez Monroy 220ccfd14bSAnoob Joseph static inline void 230ccfd14bSAnoob Joseph set_ipsec_conf(struct ipsec_sa *sa, struct rte_security_ipsec_xform *ipsec) 240ccfd14bSAnoob Joseph { 250ccfd14bSAnoob Joseph if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 260ccfd14bSAnoob Joseph struct rte_security_ipsec_tunnel_param *tunnel = 270ccfd14bSAnoob Joseph &ipsec->tunnel; 28b1a3ac78SMariusz Drost if (IS_IP4_TUNNEL(sa->flags)) { 290ccfd14bSAnoob Joseph tunnel->type = 300ccfd14bSAnoob Joseph RTE_SECURITY_IPSEC_TUNNEL_IPV4; 310ccfd14bSAnoob Joseph tunnel->ipv4.ttl = IPDEFTTL; 320ccfd14bSAnoob Joseph 330ccfd14bSAnoob Joseph memcpy((uint8_t *)&tunnel->ipv4.src_ip, 340ccfd14bSAnoob Joseph (uint8_t *)&sa->src.ip.ip4, 4); 350ccfd14bSAnoob Joseph 360ccfd14bSAnoob Joseph memcpy((uint8_t *)&tunnel->ipv4.dst_ip, 370ccfd14bSAnoob Joseph (uint8_t *)&sa->dst.ip.ip4, 4); 380d9b0263SAkhil Goyal } else if (IS_IP6_TUNNEL(sa->flags)) { 390d9b0263SAkhil Goyal tunnel->type = 400d9b0263SAkhil Goyal RTE_SECURITY_IPSEC_TUNNEL_IPV6; 410d9b0263SAkhil Goyal tunnel->ipv6.hlimit = IPDEFTTL; 420d9b0263SAkhil Goyal tunnel->ipv6.dscp = 0; 430d9b0263SAkhil Goyal tunnel->ipv6.flabel = 0; 440d9b0263SAkhil Goyal 450d9b0263SAkhil Goyal memcpy((uint8_t *)&tunnel->ipv6.src_addr, 460d9b0263SAkhil Goyal (uint8_t *)&sa->src.ip.ip6.ip6_b, 16); 470d9b0263SAkhil Goyal 480d9b0263SAkhil Goyal memcpy((uint8_t *)&tunnel->ipv6.dst_addr, 490d9b0263SAkhil Goyal (uint8_t *)&sa->dst.ip.ip6.ip6_b, 16); 500ccfd14bSAnoob Joseph } 510d9b0263SAkhil Goyal /* TODO support for Transport */ 520ccfd14bSAnoob Joseph } 530f56ca1aSHemant Agrawal ipsec->replay_win_sz = app_sa_prm.window_size; 540f56ca1aSHemant Agrawal ipsec->options.esn = app_sa_prm.enable_esn; 559a1cc8f1STejasree Kondoj ipsec->options.udp_encap = sa->udp_encap; 56d8d51d4fSRahul Bhansali if (IS_HW_REASSEMBLY_EN(sa->flags)) 57d8d51d4fSRahul Bhansali ipsec->options.ip_reassembly_en = 1; 580ccfd14bSAnoob Joseph } 590ccfd14bSAnoob Joseph 60a8781df8SAkhil Goyal static inline int 61a8781df8SAkhil Goyal verify_crypto_xform(const struct rte_cryptodev_capabilities *capabilities, 62a8781df8SAkhil Goyal struct rte_crypto_sym_xform *crypto_xform) 63a8781df8SAkhil Goyal { 64a8781df8SAkhil Goyal const struct rte_cryptodev_capabilities *crypto_cap; 65a8781df8SAkhil Goyal int j = 0; 66a8781df8SAkhil Goyal 67a8781df8SAkhil Goyal while ((crypto_cap = &capabilities[j++])->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 68a8781df8SAkhil Goyal if (crypto_cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && 69a8781df8SAkhil Goyal crypto_cap->sym.xform_type == crypto_xform->type) { 70a8781df8SAkhil Goyal if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD && 71a8781df8SAkhil Goyal crypto_cap->sym.aead.algo == crypto_xform->aead.algo) { 72a8781df8SAkhil Goyal if (rte_cryptodev_sym_capability_check_aead(&crypto_cap->sym, 73a8781df8SAkhil Goyal crypto_xform->aead.key.length, 74a8781df8SAkhil Goyal crypto_xform->aead.digest_length, 75a8781df8SAkhil Goyal crypto_xform->aead.aad_length, 76a8781df8SAkhil Goyal crypto_xform->aead.iv.length) == 0) 77a8781df8SAkhil Goyal return 0; 78a8781df8SAkhil Goyal } 79a8781df8SAkhil Goyal if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 80a8781df8SAkhil Goyal crypto_cap->sym.cipher.algo == crypto_xform->cipher.algo) { 81a8781df8SAkhil Goyal if (rte_cryptodev_sym_capability_check_cipher(&crypto_cap->sym, 82a8781df8SAkhil Goyal crypto_xform->cipher.key.length, 83a8781df8SAkhil Goyal crypto_xform->cipher.iv.length) == 0) 84a8781df8SAkhil Goyal return 0; 85a8781df8SAkhil Goyal } 86a8781df8SAkhil Goyal if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 87a8781df8SAkhil Goyal crypto_cap->sym.auth.algo == crypto_xform->auth.algo) { 88a8781df8SAkhil Goyal if (rte_cryptodev_sym_capability_check_auth(&crypto_cap->sym, 89a8781df8SAkhil Goyal crypto_xform->auth.key.length, 90a8781df8SAkhil Goyal crypto_xform->auth.digest_length, 91a8781df8SAkhil Goyal crypto_xform->auth.iv.length) == 0) 92a8781df8SAkhil Goyal return 0; 93a8781df8SAkhil Goyal } 94a8781df8SAkhil Goyal } 95a8781df8SAkhil Goyal } 96a8781df8SAkhil Goyal 97a8781df8SAkhil Goyal return -ENOTSUP; 98a8781df8SAkhil Goyal } 99a8781df8SAkhil Goyal 100a8781df8SAkhil Goyal static inline int 101a8781df8SAkhil Goyal verify_crypto_capabilities(const struct rte_cryptodev_capabilities *capabilities, 102a8781df8SAkhil Goyal struct rte_crypto_sym_xform *crypto_xform) 103a8781df8SAkhil Goyal { 104a8781df8SAkhil Goyal if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) 105a8781df8SAkhil Goyal return verify_crypto_xform(capabilities, crypto_xform); 106a8781df8SAkhil Goyal else if (crypto_xform->next != NULL) 107a8781df8SAkhil Goyal return (verify_crypto_xform(capabilities, crypto_xform) || 108a8781df8SAkhil Goyal verify_crypto_xform(capabilities, crypto_xform->next)); 109a8781df8SAkhil Goyal else 110a8781df8SAkhil Goyal return -ENOTSUP; 111a8781df8SAkhil Goyal } 112a8781df8SAkhil Goyal 113a8781df8SAkhil Goyal static inline int 114a8781df8SAkhil Goyal verify_ipsec_capabilities(struct rte_security_ipsec_xform *ipsec_xform, 115a8781df8SAkhil Goyal const struct rte_security_capability *sec_cap) 116a8781df8SAkhil Goyal { 117a8781df8SAkhil Goyal /* Verify security capabilities */ 118a8781df8SAkhil Goyal 119a8781df8SAkhil Goyal if (ipsec_xform->options.esn == 1 && sec_cap->ipsec.options.esn == 0) { 120a8781df8SAkhil Goyal RTE_LOG(INFO, USER1, "ESN is not supported\n"); 121a8781df8SAkhil Goyal return -ENOTSUP; 122a8781df8SAkhil Goyal } 123a8781df8SAkhil Goyal 124a8781df8SAkhil Goyal if (ipsec_xform->options.udp_encap == 1 && 125a8781df8SAkhil Goyal sec_cap->ipsec.options.udp_encap == 0) { 126a8781df8SAkhil Goyal RTE_LOG(INFO, USER1, "UDP encapsulation is not supported\n"); 127a8781df8SAkhil Goyal return -ENOTSUP; 128a8781df8SAkhil Goyal } 129a8781df8SAkhil Goyal 130a8781df8SAkhil Goyal if (ipsec_xform->options.udp_ports_verify == 1 && 131a8781df8SAkhil Goyal sec_cap->ipsec.options.udp_ports_verify == 0) { 132a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, 133a8781df8SAkhil Goyal "UDP encapsulation ports verification is not supported\n"); 134a8781df8SAkhil Goyal return -ENOTSUP; 135a8781df8SAkhil Goyal } 136a8781df8SAkhil Goyal 137a8781df8SAkhil Goyal if (ipsec_xform->options.copy_dscp == 1 && 138a8781df8SAkhil Goyal sec_cap->ipsec.options.copy_dscp == 0) { 139a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Copy DSCP is not supported\n"); 140a8781df8SAkhil Goyal return -ENOTSUP; 141a8781df8SAkhil Goyal } 142a8781df8SAkhil Goyal 143a8781df8SAkhil Goyal if (ipsec_xform->options.copy_flabel == 1 && 144a8781df8SAkhil Goyal sec_cap->ipsec.options.copy_flabel == 0) { 145a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Copy Flow Label is not supported\n"); 146a8781df8SAkhil Goyal return -ENOTSUP; 147a8781df8SAkhil Goyal } 148a8781df8SAkhil Goyal 149a8781df8SAkhil Goyal if (ipsec_xform->options.copy_df == 1 && 150a8781df8SAkhil Goyal sec_cap->ipsec.options.copy_df == 0) { 151a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Copy DP bit is not supported\n"); 152a8781df8SAkhil Goyal return -ENOTSUP; 153a8781df8SAkhil Goyal } 154a8781df8SAkhil Goyal 155a8781df8SAkhil Goyal if (ipsec_xform->options.dec_ttl == 1 && 156a8781df8SAkhil Goyal sec_cap->ipsec.options.dec_ttl == 0) { 157a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Decrement TTL is not supported\n"); 158a8781df8SAkhil Goyal return -ENOTSUP; 159a8781df8SAkhil Goyal } 160a8781df8SAkhil Goyal 161a8781df8SAkhil Goyal if (ipsec_xform->options.ecn == 1 && sec_cap->ipsec.options.ecn == 0) { 162a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "ECN is not supported\n"); 163a8781df8SAkhil Goyal return -ENOTSUP; 164a8781df8SAkhil Goyal } 165a8781df8SAkhil Goyal 166a8781df8SAkhil Goyal if (ipsec_xform->options.stats == 1 && 167a8781df8SAkhil Goyal sec_cap->ipsec.options.stats == 0) { 168a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Stats is not supported\n"); 169a8781df8SAkhil Goyal return -ENOTSUP; 170a8781df8SAkhil Goyal } 171a8781df8SAkhil Goyal 172a8781df8SAkhil Goyal if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) && 173a8781df8SAkhil Goyal (ipsec_xform->options.iv_gen_disable == 1) && 174a8781df8SAkhil Goyal (sec_cap->ipsec.options.iv_gen_disable != 1)) { 175a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Application provided IV is not supported\n"); 176a8781df8SAkhil Goyal return -ENOTSUP; 177a8781df8SAkhil Goyal } 178a8781df8SAkhil Goyal 179a8781df8SAkhil Goyal if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 180a8781df8SAkhil Goyal (ipsec_xform->options.tunnel_hdr_verify > 181a8781df8SAkhil Goyal sec_cap->ipsec.options.tunnel_hdr_verify)) { 182a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Tunnel header verify is not supported\n"); 183a8781df8SAkhil Goyal return -ENOTSUP; 184a8781df8SAkhil Goyal } 185a8781df8SAkhil Goyal 186a8781df8SAkhil Goyal if (ipsec_xform->options.ip_csum_enable == 1 && 187a8781df8SAkhil Goyal sec_cap->ipsec.options.ip_csum_enable == 0) { 188a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Inner IP checksum is not supported\n"); 189a8781df8SAkhil Goyal return -ENOTSUP; 190a8781df8SAkhil Goyal } 191a8781df8SAkhil Goyal 192a8781df8SAkhil Goyal if (ipsec_xform->options.l4_csum_enable == 1 && 193a8781df8SAkhil Goyal sec_cap->ipsec.options.l4_csum_enable == 0) { 194a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Inner L4 checksum is not supported\n"); 195a8781df8SAkhil Goyal return -ENOTSUP; 196a8781df8SAkhil Goyal } 197a8781df8SAkhil Goyal 198a8781df8SAkhil Goyal if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 199a8781df8SAkhil Goyal if (ipsec_xform->replay_win_sz > sec_cap->ipsec.replay_win_sz_max) { 200a8781df8SAkhil Goyal RTE_LOG(DEBUG, USER1, "Replay window size is not supported\n"); 201a8781df8SAkhil Goyal return -ENOTSUP; 202a8781df8SAkhil Goyal } 203a8781df8SAkhil Goyal } 204a8781df8SAkhil Goyal 205a8781df8SAkhil Goyal return 0; 206a8781df8SAkhil Goyal } 207a8781df8SAkhil Goyal 208a8781df8SAkhil Goyal 209a8781df8SAkhil Goyal static inline int 210a8781df8SAkhil Goyal verify_security_capabilities(struct rte_security_ctx *ctx, 211*8a77c1b7SAkhil Goyal struct rte_security_session_conf *sess_conf, 212*8a77c1b7SAkhil Goyal uint32_t *ol_flags) 213a8781df8SAkhil Goyal { 214a8781df8SAkhil Goyal struct rte_security_capability_idx sec_cap_idx; 215a8781df8SAkhil Goyal const struct rte_security_capability *sec_cap; 216a8781df8SAkhil Goyal 217a8781df8SAkhil Goyal sec_cap_idx.action = sess_conf->action_type; 218a8781df8SAkhil Goyal sec_cap_idx.protocol = sess_conf->protocol; 219a8781df8SAkhil Goyal sec_cap_idx.ipsec.proto = sess_conf->ipsec.proto; 220a8781df8SAkhil Goyal sec_cap_idx.ipsec.mode = sess_conf->ipsec.mode; 221a8781df8SAkhil Goyal sec_cap_idx.ipsec.direction = sess_conf->ipsec.direction; 222a8781df8SAkhil Goyal 223a8781df8SAkhil Goyal sec_cap = rte_security_capability_get(ctx, &sec_cap_idx); 224a8781df8SAkhil Goyal if (sec_cap == NULL) 225a8781df8SAkhil Goyal return -ENOTSUP; 226a8781df8SAkhil Goyal 227a8781df8SAkhil Goyal if (verify_crypto_capabilities(sec_cap->crypto_capabilities, 228a8781df8SAkhil Goyal sess_conf->crypto_xform)) 229a8781df8SAkhil Goyal return -ENOTSUP; 230a8781df8SAkhil Goyal 231a8781df8SAkhil Goyal if (verify_ipsec_capabilities(&sess_conf->ipsec, sec_cap)) 232a8781df8SAkhil Goyal return -ENOTSUP; 233a8781df8SAkhil Goyal 234*8a77c1b7SAkhil Goyal if (ol_flags != NULL) 235*8a77c1b7SAkhil Goyal *ol_flags = sec_cap->ol_flags; 236*8a77c1b7SAkhil Goyal 237a8781df8SAkhil Goyal return 0; 238a8781df8SAkhil Goyal } 239a8781df8SAkhil Goyal 2403e5f4625SKonstantin Ananyev int 241a8ade121SVolodymyr Fialko create_lookaside_session(struct ipsec_ctx *ipsec_ctx_lcore[], 2426938fc92SVolodymyr Fialko struct socket_ctx *skt_ctx, const struct eventmode_conf *em_conf, 2436938fc92SVolodymyr Fialko struct ipsec_sa *sa, struct rte_ipsec_session *ips) 244d299106eSSergio Gonzalez Monroy { 245a8ade121SVolodymyr Fialko uint16_t cdev_id = RTE_CRYPTO_MAX_DEVS; 2466938fc92SVolodymyr Fialko enum rte_crypto_op_sess_type sess_type; 247c5aa9617SAkhil Goyal struct rte_cryptodev_info cdev_info; 2486938fc92SVolodymyr Fialko enum rte_crypto_op_type op_type; 2494e942500SSergio Gonzalez Monroy unsigned long cdev_id_qp = 0; 250a8ade121SVolodymyr Fialko struct ipsec_ctx *ipsec_ctx; 2516938fc92SVolodymyr Fialko struct cdev_key key = { 0 }; 2526938fc92SVolodymyr Fialko void *sess = NULL; 253a8ade121SVolodymyr Fialko uint32_t lcore_id; 254a8ade121SVolodymyr Fialko int32_t ret = 0; 255d299106eSSergio Gonzalez Monroy 256a8ade121SVolodymyr Fialko RTE_LCORE_FOREACH(lcore_id) { 257a8ade121SVolodymyr Fialko ipsec_ctx = ipsec_ctx_lcore[lcore_id]; 258d299106eSSergio Gonzalez Monroy 259a8ade121SVolodymyr Fialko /* Core is not bound to any cryptodev, skip it */ 260a8ade121SVolodymyr Fialko if (ipsec_ctx->cdev_map == NULL) 261a8ade121SVolodymyr Fialko continue; 262a8ade121SVolodymyr Fialko 263a8ade121SVolodymyr Fialko /* Looking for cryptodev, which can handle this SA */ 264a8ade121SVolodymyr Fialko key.lcore_id = (uint8_t)lcore_id; 265d299106eSSergio Gonzalez Monroy key.cipher_algo = (uint8_t)sa->cipher_algo; 266d299106eSSergio Gonzalez Monroy key.auth_algo = (uint8_t)sa->auth_algo; 267d00f3890SAviad Yehezkel key.aead_algo = (uint8_t)sa->aead_algo; 268d299106eSSergio Gonzalez Monroy 269d299106eSSergio Gonzalez Monroy ret = rte_hash_lookup_data(ipsec_ctx->cdev_map, &key, 270d299106eSSergio Gonzalez Monroy (void **)&cdev_id_qp); 271a8ade121SVolodymyr Fialko if (ret == -ENOENT) 272a8ade121SVolodymyr Fialko continue; 273d299106eSSergio Gonzalez Monroy if (ret < 0) { 274ec17993aSAkhil Goyal RTE_LOG(ERR, IPSEC, 275ec17993aSAkhil Goyal "No cryptodev: core %u, cipher_algo %u, " 276d00f3890SAviad Yehezkel "auth_algo %u, aead_algo %u\n", 277d00f3890SAviad Yehezkel key.lcore_id, 278d00f3890SAviad Yehezkel key.cipher_algo, 279d00f3890SAviad Yehezkel key.auth_algo, 280d00f3890SAviad Yehezkel key.aead_algo); 281a8ade121SVolodymyr Fialko return ret; 282d299106eSSergio Gonzalez Monroy } 283d299106eSSergio Gonzalez Monroy 284a8ade121SVolodymyr Fialko /* Verify that all cores are using same cryptodev for current 285a8ade121SVolodymyr Fialko * algorithm combination, required by SA. 286a8ade121SVolodymyr Fialko * Current cryptodev mapping process will map SA to the first 287a8ade121SVolodymyr Fialko * cryptodev that matches requirements, so it's a double check, 288a8ade121SVolodymyr Fialko * not an additional restriction. 289a8ade121SVolodymyr Fialko */ 290a8ade121SVolodymyr Fialko if (cdev_id == RTE_CRYPTO_MAX_DEVS) 291a8ade121SVolodymyr Fialko cdev_id = ipsec_ctx->tbl[cdev_id_qp].id; 292a8ade121SVolodymyr Fialko else if (cdev_id != ipsec_ctx->tbl[cdev_id_qp].id) { 293a8ade121SVolodymyr Fialko RTE_LOG(ERR, IPSEC, 294a8ade121SVolodymyr Fialko "SA mapping to multiple cryptodevs is " 295a8ade121SVolodymyr Fialko "not supported!"); 296a8ade121SVolodymyr Fialko return -EINVAL; 297a8ade121SVolodymyr Fialko } 298a8ade121SVolodymyr Fialko 299a8ade121SVolodymyr Fialko /* Store per core queue pair information */ 300a8ade121SVolodymyr Fialko sa->cqp[lcore_id] = &ipsec_ctx->tbl[cdev_id_qp]; 301a8ade121SVolodymyr Fialko } 302a8ade121SVolodymyr Fialko if (cdev_id == RTE_CRYPTO_MAX_DEVS) { 303a8ade121SVolodymyr Fialko RTE_LOG(WARNING, IPSEC, "No cores found to handle SA\n"); 304a8ade121SVolodymyr Fialko return 0; 305a8ade121SVolodymyr Fialko } 306a8ade121SVolodymyr Fialko 307a8ade121SVolodymyr Fialko RTE_LOG(DEBUG, IPSEC, "Create session for SA spi %u on cryptodev " 308a8ade121SVolodymyr Fialko "%u\n", sa->spi, cdev_id); 309d299106eSSergio Gonzalez Monroy 3105139d5d9SMarcin Smoczynski if (ips->type != RTE_SECURITY_ACTION_TYPE_NONE && 3115139d5d9SMarcin Smoczynski ips->type != RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO) { 312ec17993aSAkhil Goyal struct rte_security_session_conf sess_conf = { 3134a67af84SMarcin Smoczynski .action_type = ips->type, 314ec17993aSAkhil Goyal .protocol = RTE_SECURITY_PROTOCOL_IPSEC, 315376ee1deSRadu Nicolau {.ipsec = { 316ec17993aSAkhil Goyal .spi = sa->spi, 317ec17993aSAkhil Goyal .salt = sa->salt, 318ec17993aSAkhil Goyal .options = { 0 }, 3190f56ca1aSHemant Agrawal .replay_win_sz = 0, 320ec17993aSAkhil Goyal .direction = sa->direction, 321ec17993aSAkhil Goyal .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, 322b1a3ac78SMariusz Drost .mode = (IS_TUNNEL(sa->flags)) ? 323ec17993aSAkhil Goyal RTE_SECURITY_IPSEC_SA_MODE_TUNNEL : 324ec17993aSAkhil Goyal RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT, 325376ee1deSRadu Nicolau } }, 3260ccfd14bSAnoob Joseph .crypto_xform = sa->xforms, 3270ccfd14bSAnoob Joseph .userdata = NULL, 328ec17993aSAkhil Goyal 329ec17993aSAkhil Goyal }; 330ec17993aSAkhil Goyal 3314a67af84SMarcin Smoczynski if (ips->type == RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) { 332ec17993aSAkhil Goyal struct rte_security_ctx *ctx = (struct rte_security_ctx *) 333ec17993aSAkhil Goyal rte_cryptodev_get_sec_ctx( 334a8ade121SVolodymyr Fialko cdev_id); 335ec17993aSAkhil Goyal 3360ccfd14bSAnoob Joseph /* Set IPsec parameters in conf */ 3370ccfd14bSAnoob Joseph set_ipsec_conf(sa, &(sess_conf.ipsec)); 338ec17993aSAkhil Goyal 339*8a77c1b7SAkhil Goyal if (verify_security_capabilities(ctx, &sess_conf, NULL)) { 340a8781df8SAkhil Goyal RTE_LOG(ERR, IPSEC, 341a8781df8SAkhil Goyal "Requested security session config not supported\n"); 342a8781df8SAkhil Goyal return -1; 343a8781df8SAkhil Goyal } 344a8781df8SAkhil Goyal 3454a67af84SMarcin Smoczynski ips->security.ses = rte_security_session_create(ctx, 3463f3fc330SAkhil Goyal &sess_conf, skt_ctx->session_pool); 3474a67af84SMarcin Smoczynski if (ips->security.ses == NULL) { 348ec17993aSAkhil Goyal RTE_LOG(ERR, IPSEC, 349ec17993aSAkhil Goyal "SEC Session init failed: err: %d\n", ret); 350ec17993aSAkhil Goyal return -1; 351ec17993aSAkhil Goyal } 3528e814e18SVolodymyr Fialko ips->security.ctx = ctx; 3536938fc92SVolodymyr Fialko 3546938fc92SVolodymyr Fialko sess = ips->security.ses; 3556938fc92SVolodymyr Fialko op_type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 3566938fc92SVolodymyr Fialko sess_type = RTE_CRYPTO_OP_SECURITY_SESSION; 3573a690d5aSBernard Iremonger } else { 3583a690d5aSBernard Iremonger RTE_LOG(ERR, IPSEC, "Inline not supported\n"); 3593a690d5aSBernard Iremonger return -1; 3603a690d5aSBernard Iremonger } 3613a690d5aSBernard Iremonger } else { 3625139d5d9SMarcin Smoczynski struct rte_cryptodev_info info; 3635139d5d9SMarcin Smoczynski 3645139d5d9SMarcin Smoczynski rte_cryptodev_info_get(cdev_id, &info); 365a8781df8SAkhil Goyal 366a8781df8SAkhil Goyal if (ips->type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO) { 3675139d5d9SMarcin Smoczynski if (!(info.feature_flags & 3685139d5d9SMarcin Smoczynski RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO)) 3695139d5d9SMarcin Smoczynski return -ENOTSUP; 3705139d5d9SMarcin Smoczynski 3715139d5d9SMarcin Smoczynski } 372a8781df8SAkhil Goyal 373a8781df8SAkhil Goyal if (verify_crypto_capabilities(info.capabilities, sa->xforms)) { 374a8781df8SAkhil Goyal RTE_LOG(ERR, IPSEC, 375a8781df8SAkhil Goyal "Requested crypto session config not supported\n"); 376a8781df8SAkhil Goyal return -1; 377a8781df8SAkhil Goyal } 378a8781df8SAkhil Goyal 3798e814e18SVolodymyr Fialko ips->crypto.dev_id = cdev_id; 380bdce2564SAkhil Goyal ips->crypto.ses = rte_cryptodev_sym_session_create(cdev_id, 381bdce2564SAkhil Goyal sa->xforms, skt_ctx->session_pool); 3823a690d5aSBernard Iremonger 3838e814e18SVolodymyr Fialko rte_cryptodev_info_get(cdev_id, &cdev_info); 3843a690d5aSBernard Iremonger } 3853a690d5aSBernard Iremonger 3866938fc92SVolodymyr Fialko /* Setup meta data required by event crypto adapter */ 3876938fc92SVolodymyr Fialko if (em_conf->enable_event_crypto_adapter && sess != NULL) { 3886938fc92SVolodymyr Fialko union rte_event_crypto_metadata m_data; 3896938fc92SVolodymyr Fialko const struct eventdev_params *eventdev_conf; 3906938fc92SVolodymyr Fialko 3916938fc92SVolodymyr Fialko eventdev_conf = &(em_conf->eventdev_config[0]); 3926938fc92SVolodymyr Fialko memset(&m_data, 0, sizeof(m_data)); 3936938fc92SVolodymyr Fialko 3946938fc92SVolodymyr Fialko /* Fill in response information */ 3956938fc92SVolodymyr Fialko m_data.response_info.sched_type = em_conf->ext_params.sched_type; 3966938fc92SVolodymyr Fialko m_data.response_info.op = RTE_EVENT_OP_NEW; 3976938fc92SVolodymyr Fialko m_data.response_info.queue_id = eventdev_conf->ev_cpt_queue_id; 3986938fc92SVolodymyr Fialko 3996938fc92SVolodymyr Fialko /* Fill in request information */ 4006938fc92SVolodymyr Fialko m_data.request_info.cdev_id = cdev_id; 4016938fc92SVolodymyr Fialko m_data.request_info.queue_pair_id = 0; 4026938fc92SVolodymyr Fialko 4036938fc92SVolodymyr Fialko /* Attach meta info to session */ 4046938fc92SVolodymyr Fialko rte_cryptodev_session_event_mdata_set(cdev_id, sess, op_type, 4056938fc92SVolodymyr Fialko sess_type, &m_data, sizeof(m_data)); 4066938fc92SVolodymyr Fialko } 4076938fc92SVolodymyr Fialko 4083a690d5aSBernard Iremonger return 0; 4093a690d5aSBernard Iremonger } 4103a690d5aSBernard Iremonger 4113a690d5aSBernard Iremonger int 4124a67af84SMarcin Smoczynski create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, 4134a67af84SMarcin Smoczynski struct rte_ipsec_session *ips) 4143a690d5aSBernard Iremonger { 4153a690d5aSBernard Iremonger int32_t ret = 0; 4163a690d5aSBernard Iremonger struct rte_security_ctx *sec_ctx; 4173a690d5aSBernard Iremonger struct rte_security_session_conf sess_conf = { 4184a67af84SMarcin Smoczynski .action_type = ips->type, 4193a690d5aSBernard Iremonger .protocol = RTE_SECURITY_PROTOCOL_IPSEC, 4203a690d5aSBernard Iremonger {.ipsec = { 4213a690d5aSBernard Iremonger .spi = sa->spi, 4223a690d5aSBernard Iremonger .salt = sa->salt, 4233a690d5aSBernard Iremonger .options = { 0 }, 4240f56ca1aSHemant Agrawal .replay_win_sz = 0, 4253a690d5aSBernard Iremonger .direction = sa->direction, 4266019feadSRadu Nicolau .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP 4273a690d5aSBernard Iremonger } }, 4283a690d5aSBernard Iremonger .crypto_xform = sa->xforms, 4293a690d5aSBernard Iremonger .userdata = NULL, 4303a690d5aSBernard Iremonger }; 4313a690d5aSBernard Iremonger 4326019feadSRadu Nicolau if (IS_TRANSPORT(sa->flags)) { 4336019feadSRadu Nicolau sess_conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT; 4346019feadSRadu Nicolau if (IS_IP4(sa->flags)) { 4356019feadSRadu Nicolau sess_conf.ipsec.tunnel.type = 4366019feadSRadu Nicolau RTE_SECURITY_IPSEC_TUNNEL_IPV4; 4376019feadSRadu Nicolau 4386019feadSRadu Nicolau sess_conf.ipsec.tunnel.ipv4.src_ip.s_addr = 4396019feadSRadu Nicolau sa->src.ip.ip4; 4406019feadSRadu Nicolau sess_conf.ipsec.tunnel.ipv4.dst_ip.s_addr = 4416019feadSRadu Nicolau sa->dst.ip.ip4; 4426019feadSRadu Nicolau } else if (IS_IP6(sa->flags)) { 4436019feadSRadu Nicolau sess_conf.ipsec.tunnel.type = 4446019feadSRadu Nicolau RTE_SECURITY_IPSEC_TUNNEL_IPV6; 4456019feadSRadu Nicolau 4466019feadSRadu Nicolau memcpy(sess_conf.ipsec.tunnel.ipv6.src_addr.s6_addr, 4476019feadSRadu Nicolau sa->src.ip.ip6.ip6_b, 16); 4486019feadSRadu Nicolau memcpy(sess_conf.ipsec.tunnel.ipv6.dst_addr.s6_addr, 4496019feadSRadu Nicolau sa->dst.ip.ip6.ip6_b, 16); 4506019feadSRadu Nicolau } 4516019feadSRadu Nicolau } else if (IS_TUNNEL(sa->flags)) { 4526019feadSRadu Nicolau sess_conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; 4536019feadSRadu Nicolau 4546019feadSRadu Nicolau if (IS_IP4(sa->flags)) { 4556019feadSRadu Nicolau sess_conf.ipsec.tunnel.type = 4566019feadSRadu Nicolau RTE_SECURITY_IPSEC_TUNNEL_IPV4; 4576019feadSRadu Nicolau 4586019feadSRadu Nicolau sess_conf.ipsec.tunnel.ipv4.src_ip.s_addr = 4596019feadSRadu Nicolau sa->src.ip.ip4; 4606019feadSRadu Nicolau sess_conf.ipsec.tunnel.ipv4.dst_ip.s_addr = 4616019feadSRadu Nicolau sa->dst.ip.ip4; 4626019feadSRadu Nicolau } else if (IS_IP6(sa->flags)) { 4636019feadSRadu Nicolau sess_conf.ipsec.tunnel.type = 4646019feadSRadu Nicolau RTE_SECURITY_IPSEC_TUNNEL_IPV6; 4656019feadSRadu Nicolau 4666019feadSRadu Nicolau memcpy(sess_conf.ipsec.tunnel.ipv6.src_addr.s6_addr, 4676019feadSRadu Nicolau sa->src.ip.ip6.ip6_b, 16); 4686019feadSRadu Nicolau memcpy(sess_conf.ipsec.tunnel.ipv6.dst_addr.s6_addr, 4696019feadSRadu Nicolau sa->dst.ip.ip6.ip6_b, 16); 4706019feadSRadu Nicolau } else { 4716019feadSRadu Nicolau RTE_LOG(ERR, IPSEC, "invalid tunnel type\n"); 4726019feadSRadu Nicolau return -1; 4736019feadSRadu Nicolau } 4746019feadSRadu Nicolau } 4756019feadSRadu Nicolau 4769ae86b4cSRadu Nicolau if (sa->udp_encap) { 4779ae86b4cSRadu Nicolau sess_conf.ipsec.options.udp_encap = 1; 4789ae86b4cSRadu Nicolau sess_conf.ipsec.udp.sport = htons(sa->udp.sport); 4799ae86b4cSRadu Nicolau sess_conf.ipsec.udp.dport = htons(sa->udp.dport); 4809ae86b4cSRadu Nicolau } 4819ae86b4cSRadu Nicolau 482560029d5SRadu Nicolau if (sa->esn > 0) { 483560029d5SRadu Nicolau sess_conf.ipsec.options.esn = 1; 484560029d5SRadu Nicolau sess_conf.ipsec.esn.value = sa->esn; 485560029d5SRadu Nicolau } 486560029d5SRadu Nicolau 487560029d5SRadu Nicolau 4883a690d5aSBernard Iremonger RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n", 4893a690d5aSBernard Iremonger sa->spi, sa->portid); 4903a690d5aSBernard Iremonger 4914a67af84SMarcin Smoczynski if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) { 492ec17993aSAkhil Goyal struct rte_flow_error err; 493a4677f78SNélio Laranjeiro int ret = 0; 494ec17993aSAkhil Goyal 4953a690d5aSBernard Iremonger sec_ctx = (struct rte_security_ctx *) 4963a690d5aSBernard Iremonger rte_eth_dev_get_sec_ctx( 4973a690d5aSBernard Iremonger sa->portid); 4983a690d5aSBernard Iremonger if (sec_ctx == NULL) { 4993a690d5aSBernard Iremonger RTE_LOG(ERR, IPSEC, 5003a690d5aSBernard Iremonger " rte_eth_dev_get_sec_ctx failed\n"); 5013a690d5aSBernard Iremonger return -1; 5023a690d5aSBernard Iremonger } 5033a690d5aSBernard Iremonger 504*8a77c1b7SAkhil Goyal if (verify_security_capabilities(sec_ctx, &sess_conf, 505*8a77c1b7SAkhil Goyal &ips->security.ol_flags)) { 506a8781df8SAkhil Goyal RTE_LOG(ERR, IPSEC, 507a8781df8SAkhil Goyal "Requested security session config not supported\n"); 508a8781df8SAkhil Goyal return -1; 509a8781df8SAkhil Goyal } 510a8781df8SAkhil Goyal 5114a67af84SMarcin Smoczynski ips->security.ses = rte_security_session_create(sec_ctx, 5123f3fc330SAkhil Goyal &sess_conf, skt_ctx->session_pool); 5134a67af84SMarcin Smoczynski if (ips->security.ses == NULL) { 514ec17993aSAkhil Goyal RTE_LOG(ERR, IPSEC, 515ec17993aSAkhil Goyal "SEC Session init failed: err: %d\n", ret); 516ec17993aSAkhil Goyal return -1; 517ec17993aSAkhil Goyal } 518ec17993aSAkhil Goyal 5194a67af84SMarcin Smoczynski ips->security.ctx = sec_ctx; 520ec17993aSAkhil Goyal sa->pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 521ec17993aSAkhil Goyal 522b1a3ac78SMariusz Drost if (IS_IP6(sa->flags)) { 523b1a3ac78SMariusz Drost sa->pattern[1].mask = &rte_flow_item_ipv6_mask; 524b1a3ac78SMariusz Drost sa->pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6; 525ec17993aSAkhil Goyal sa->pattern[1].spec = &sa->ipv6_spec; 526b1a3ac78SMariusz Drost 527ec17993aSAkhil Goyal memcpy(sa->ipv6_spec.hdr.dst_addr, 528ec17993aSAkhil Goyal sa->dst.ip.ip6.ip6_b, 16); 529ec17993aSAkhil Goyal memcpy(sa->ipv6_spec.hdr.src_addr, 530ec17993aSAkhil Goyal sa->src.ip.ip6.ip6_b, 16); 531b1a3ac78SMariusz Drost } else if (IS_IP4(sa->flags)) { 532b1a3ac78SMariusz Drost sa->pattern[1].mask = &rte_flow_item_ipv4_mask; 533b1a3ac78SMariusz Drost sa->pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; 534ec17993aSAkhil Goyal sa->pattern[1].spec = &sa->ipv4_spec; 535b1a3ac78SMariusz Drost 536ec17993aSAkhil Goyal sa->ipv4_spec.hdr.dst_addr = sa->dst.ip.ip4; 537ec17993aSAkhil Goyal sa->ipv4_spec.hdr.src_addr = sa->src.ip.ip4; 538ec17993aSAkhil Goyal } 539ec17993aSAkhil Goyal 5409ae86b4cSRadu Nicolau sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi); 5419ae86b4cSRadu Nicolau 5429ae86b4cSRadu Nicolau if (sa->udp_encap) { 5439ae86b4cSRadu Nicolau 5449ae86b4cSRadu Nicolau sa->udp_spec.hdr.dst_port = 5459ae86b4cSRadu Nicolau rte_cpu_to_be_16(sa->udp.dport); 5469ae86b4cSRadu Nicolau sa->udp_spec.hdr.src_port = 5479ae86b4cSRadu Nicolau rte_cpu_to_be_16(sa->udp.sport); 5489ae86b4cSRadu Nicolau 5499ae86b4cSRadu Nicolau sa->pattern[2].mask = &rte_flow_item_udp_mask; 5509ae86b4cSRadu Nicolau sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP; 5519ae86b4cSRadu Nicolau sa->pattern[2].spec = &sa->udp_spec; 5529ae86b4cSRadu Nicolau 5539ae86b4cSRadu Nicolau sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_ESP; 5549ae86b4cSRadu Nicolau sa->pattern[3].spec = &sa->esp_spec; 5559ae86b4cSRadu Nicolau sa->pattern[3].mask = &rte_flow_item_esp_mask; 5569ae86b4cSRadu Nicolau 5579ae86b4cSRadu Nicolau sa->pattern[4].type = RTE_FLOW_ITEM_TYPE_END; 5589ae86b4cSRadu Nicolau } else { 559ec17993aSAkhil Goyal sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP; 560ec17993aSAkhil Goyal sa->pattern[2].spec = &sa->esp_spec; 561ec17993aSAkhil Goyal sa->pattern[2].mask = &rte_flow_item_esp_mask; 562ec17993aSAkhil Goyal 563ec17993aSAkhil Goyal sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END; 5649ae86b4cSRadu Nicolau } 565ec17993aSAkhil Goyal 566ec17993aSAkhil Goyal sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY; 5674a67af84SMarcin Smoczynski sa->action[0].conf = ips->security.ses; 568ec17993aSAkhil Goyal 569ec17993aSAkhil Goyal sa->action[1].type = RTE_FLOW_ACTION_TYPE_END; 570ec17993aSAkhil Goyal 571ec17993aSAkhil Goyal sa->attr.egress = (sa->direction == 572ec17993aSAkhil Goyal RTE_SECURITY_IPSEC_SA_DIR_EGRESS); 573a4cde424SNélio Laranjeiro sa->attr.ingress = (sa->direction == 574a4cde424SNélio Laranjeiro RTE_SECURITY_IPSEC_SA_DIR_INGRESS); 575a4677f78SNélio Laranjeiro if (sa->attr.ingress) { 5766019feadSRadu Nicolau uint8_t rss_key[64]; 577a4677f78SNélio Laranjeiro struct rte_eth_rss_conf rss_conf = { 578a4677f78SNélio Laranjeiro .rss_key = rss_key, 5796019feadSRadu Nicolau .rss_key_len = sizeof(rss_key), 580a4677f78SNélio Laranjeiro }; 5810109baf1SMarcin Zapolski struct rte_eth_dev_info dev_info; 582a4677f78SNélio Laranjeiro uint16_t queue[RTE_MAX_QUEUES_PER_PORT]; 58319b3bc47SAdrien Mazarguil struct rte_flow_action_rss action_rss; 584a4677f78SNélio Laranjeiro unsigned int i; 585a4677f78SNélio Laranjeiro unsigned int j; 586a4677f78SNélio Laranjeiro 587513f192bSAnkur Dwivedi /* Don't create flow if default flow is created */ 588513f192bSAnkur Dwivedi if (flow_info_tbl[sa->portid].rx_def_flow) 589513f192bSAnkur Dwivedi return 0; 590513f192bSAnkur Dwivedi 59103ad0e5cSIvan Ilchenko ret = rte_eth_dev_info_get(sa->portid, &dev_info); 59203ad0e5cSIvan Ilchenko if (ret != 0) { 59303ad0e5cSIvan Ilchenko RTE_LOG(ERR, IPSEC, 59403ad0e5cSIvan Ilchenko "Error during getting device (port %u) info: %s\n", 59503ad0e5cSIvan Ilchenko sa->portid, strerror(-ret)); 59603ad0e5cSIvan Ilchenko return ret; 59703ad0e5cSIvan Ilchenko } 59803ad0e5cSIvan Ilchenko 599a4677f78SNélio Laranjeiro sa->action[2].type = RTE_FLOW_ACTION_TYPE_END; 600a4677f78SNélio Laranjeiro /* Try RSS. */ 601a4677f78SNélio Laranjeiro sa->action[1].type = RTE_FLOW_ACTION_TYPE_RSS; 602a4677f78SNélio Laranjeiro sa->action[1].conf = &action_rss; 60323742f21SBernard Iremonger ret = rte_eth_dev_rss_hash_conf_get(sa->portid, 60423742f21SBernard Iremonger &rss_conf); 60523742f21SBernard Iremonger if (ret != 0) { 60623742f21SBernard Iremonger RTE_LOG(ERR, IPSEC, 60723742f21SBernard Iremonger "rte_eth_dev_rss_hash_conf_get:ret=%d\n", 60823742f21SBernard Iremonger ret); 60923742f21SBernard Iremonger return -1; 61023742f21SBernard Iremonger } 6113a690d5aSBernard Iremonger for (i = 0, j = 0; i < dev_info.nb_rx_queues; ++i) 61219b3bc47SAdrien Mazarguil queue[j++] = i; 6133a690d5aSBernard Iremonger 614ac8d22deSAdrien Mazarguil action_rss = (struct rte_flow_action_rss){ 615ac8d22deSAdrien Mazarguil .types = rss_conf.rss_hf, 616ac8d22deSAdrien Mazarguil .key_len = rss_conf.rss_key_len, 617ac8d22deSAdrien Mazarguil .queue_num = j, 618ac8d22deSAdrien Mazarguil .key = rss_key, 619ac8d22deSAdrien Mazarguil .queue = queue, 620ac8d22deSAdrien Mazarguil }; 621a4677f78SNélio Laranjeiro ret = rte_flow_validate(sa->portid, &sa->attr, 622a4677f78SNélio Laranjeiro sa->pattern, sa->action, 623a4677f78SNélio Laranjeiro &err); 624a4677f78SNélio Laranjeiro if (!ret) 625a4677f78SNélio Laranjeiro goto flow_create; 626a4677f78SNélio Laranjeiro /* Try Queue. */ 627a4677f78SNélio Laranjeiro sa->action[1].type = RTE_FLOW_ACTION_TYPE_QUEUE; 628a4677f78SNélio Laranjeiro sa->action[1].conf = 629a4677f78SNélio Laranjeiro &(struct rte_flow_action_queue){ 630a4677f78SNélio Laranjeiro .index = 0, 631a4677f78SNélio Laranjeiro }; 632a4677f78SNélio Laranjeiro ret = rte_flow_validate(sa->portid, &sa->attr, 633a4677f78SNélio Laranjeiro sa->pattern, sa->action, 634a4677f78SNélio Laranjeiro &err); 6356138c2daSRadu Nicolau /* Try End. */ 6366138c2daSRadu Nicolau sa->action[1].type = RTE_FLOW_ACTION_TYPE_END; 6376138c2daSRadu Nicolau sa->action[1].conf = NULL; 6386138c2daSRadu Nicolau ret = rte_flow_validate(sa->portid, &sa->attr, 6396138c2daSRadu Nicolau sa->pattern, sa->action, 6406138c2daSRadu Nicolau &err); 641a4677f78SNélio Laranjeiro if (ret) 642a4677f78SNélio Laranjeiro goto flow_create_failure; 643a90e6ce6SNélio Laranjeiro } else if (sa->attr.egress && 6444a67af84SMarcin Smoczynski (ips->security.ol_flags & 645a90e6ce6SNélio Laranjeiro RTE_SECURITY_TX_HW_TRAILER_OFFLOAD)) { 646a90e6ce6SNélio Laranjeiro sa->action[1].type = 647a90e6ce6SNélio Laranjeiro RTE_FLOW_ACTION_TYPE_PASSTHRU; 648a90e6ce6SNélio Laranjeiro sa->action[2].type = 649a90e6ce6SNélio Laranjeiro RTE_FLOW_ACTION_TYPE_END; 650a4677f78SNélio Laranjeiro } 651a4677f78SNélio Laranjeiro flow_create: 652ec17993aSAkhil Goyal sa->flow = rte_flow_create(sa->portid, 653ec17993aSAkhil Goyal &sa->attr, sa->pattern, sa->action, &err); 654ec17993aSAkhil Goyal if (sa->flow == NULL) { 655a4677f78SNélio Laranjeiro flow_create_failure: 656ec17993aSAkhil Goyal RTE_LOG(ERR, IPSEC, 657ec17993aSAkhil Goyal "Failed to create ipsec flow msg: %s\n", 658ec17993aSAkhil Goyal err.message); 659ec17993aSAkhil Goyal return -1; 660ec17993aSAkhil Goyal } 6614a67af84SMarcin Smoczynski } else if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) { 6623a690d5aSBernard Iremonger sec_ctx = (struct rte_security_ctx *) 6633a690d5aSBernard Iremonger rte_eth_dev_get_sec_ctx(sa->portid); 6643a690d5aSBernard Iremonger 6653a690d5aSBernard Iremonger if (sec_ctx == NULL) { 6660ccfd14bSAnoob Joseph RTE_LOG(ERR, IPSEC, 6670ccfd14bSAnoob Joseph "Ethernet device doesn't have security features registered\n"); 6680ccfd14bSAnoob Joseph return -1; 6690ccfd14bSAnoob Joseph } 6700ccfd14bSAnoob Joseph 6710ccfd14bSAnoob Joseph /* Set IPsec parameters in conf */ 6720ccfd14bSAnoob Joseph set_ipsec_conf(sa, &(sess_conf.ipsec)); 6730ccfd14bSAnoob Joseph 6740ccfd14bSAnoob Joseph /* Save SA as userdata for the security session. When 6750ccfd14bSAnoob Joseph * the packet is received, this userdata will be 6760ccfd14bSAnoob Joseph * retrieved using the metadata from the packet. 6770ccfd14bSAnoob Joseph * 678fa4de2ccSAnoob Joseph * The PMD is expected to set similar metadata for other 679fa4de2ccSAnoob Joseph * operations, like rte_eth_event, which are tied to 680fa4de2ccSAnoob Joseph * security session. In such cases, the userdata could 681fa4de2ccSAnoob Joseph * be obtained to uniquely identify the security 682fa4de2ccSAnoob Joseph * parameters denoted. 6830ccfd14bSAnoob Joseph */ 6840ccfd14bSAnoob Joseph 6850ccfd14bSAnoob Joseph sess_conf.userdata = (void *) sa; 6860ccfd14bSAnoob Joseph 687*8a77c1b7SAkhil Goyal if (verify_security_capabilities(sec_ctx, &sess_conf, 688*8a77c1b7SAkhil Goyal &ips->security.ol_flags)) { 689a8781df8SAkhil Goyal RTE_LOG(ERR, IPSEC, 690a8781df8SAkhil Goyal "Requested security session config not supported\n"); 691a8781df8SAkhil Goyal return -1; 692a8781df8SAkhil Goyal } 693a8781df8SAkhil Goyal 6944a67af84SMarcin Smoczynski ips->security.ses = rte_security_session_create(sec_ctx, 6953f3fc330SAkhil Goyal &sess_conf, skt_ctx->session_pool); 6964a67af84SMarcin Smoczynski if (ips->security.ses == NULL) { 6970ccfd14bSAnoob Joseph RTE_LOG(ERR, IPSEC, 6980ccfd14bSAnoob Joseph "SEC Session init failed: err: %d\n", ret); 6990ccfd14bSAnoob Joseph return -1; 7000ccfd14bSAnoob Joseph } 7010ccfd14bSAnoob Joseph 7024a67af84SMarcin Smoczynski ips->security.ctx = sec_ctx; 703ec17993aSAkhil Goyal } 704d299106eSSergio Gonzalez Monroy 705d299106eSSergio Gonzalez Monroy return 0; 706d299106eSSergio Gonzalez Monroy } 707d299106eSSergio Gonzalez Monroy 7086738c0a9SPraveen Shetty int 7096738c0a9SPraveen Shetty create_ipsec_esp_flow(struct ipsec_sa *sa) 7106738c0a9SPraveen Shetty { 7116738c0a9SPraveen Shetty int ret = 0; 7120b512a92SVolodymyr Fialko struct rte_flow_error err = {}; 7136738c0a9SPraveen Shetty if (sa->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 7146738c0a9SPraveen Shetty RTE_LOG(ERR, IPSEC, 7156738c0a9SPraveen Shetty "No Flow director rule for Egress traffic\n"); 7166738c0a9SPraveen Shetty return -1; 7176738c0a9SPraveen Shetty } 7186738c0a9SPraveen Shetty if (sa->flags == TRANSPORT) { 7196738c0a9SPraveen Shetty RTE_LOG(ERR, IPSEC, 7206738c0a9SPraveen Shetty "No Flow director rule for transport mode\n"); 7216738c0a9SPraveen Shetty return -1; 7226738c0a9SPraveen Shetty } 7236738c0a9SPraveen Shetty sa->action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; 7246738c0a9SPraveen Shetty sa->pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 7256738c0a9SPraveen Shetty sa->action[0].conf = &(struct rte_flow_action_queue) { 7266738c0a9SPraveen Shetty .index = sa->fdir_qid, 7276738c0a9SPraveen Shetty }; 7286738c0a9SPraveen Shetty sa->attr.egress = 0; 7296738c0a9SPraveen Shetty sa->attr.ingress = 1; 7306738c0a9SPraveen Shetty if (IS_IP6(sa->flags)) { 7316738c0a9SPraveen Shetty sa->pattern[1].mask = &rte_flow_item_ipv6_mask; 7326738c0a9SPraveen Shetty sa->pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6; 7336738c0a9SPraveen Shetty sa->pattern[1].spec = &sa->ipv6_spec; 7346738c0a9SPraveen Shetty memcpy(sa->ipv6_spec.hdr.dst_addr, 7356738c0a9SPraveen Shetty sa->dst.ip.ip6.ip6_b, sizeof(sa->dst.ip.ip6.ip6_b)); 7366738c0a9SPraveen Shetty memcpy(sa->ipv6_spec.hdr.src_addr, 7376738c0a9SPraveen Shetty sa->src.ip.ip6.ip6_b, sizeof(sa->src.ip.ip6.ip6_b)); 7386738c0a9SPraveen Shetty sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP; 7396738c0a9SPraveen Shetty sa->pattern[2].spec = &sa->esp_spec; 7406738c0a9SPraveen Shetty sa->pattern[2].mask = &rte_flow_item_esp_mask; 7416738c0a9SPraveen Shetty sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi); 7426738c0a9SPraveen Shetty sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END; 7436738c0a9SPraveen Shetty } else if (IS_IP4(sa->flags)) { 7446738c0a9SPraveen Shetty sa->pattern[1].mask = &rte_flow_item_ipv4_mask; 7456738c0a9SPraveen Shetty sa->pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; 7466738c0a9SPraveen Shetty sa->pattern[1].spec = &sa->ipv4_spec; 7476738c0a9SPraveen Shetty sa->ipv4_spec.hdr.dst_addr = sa->dst.ip.ip4; 7486738c0a9SPraveen Shetty sa->ipv4_spec.hdr.src_addr = sa->src.ip.ip4; 7496738c0a9SPraveen Shetty sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP; 7506738c0a9SPraveen Shetty sa->pattern[2].spec = &sa->esp_spec; 7516738c0a9SPraveen Shetty sa->pattern[2].mask = &rte_flow_item_esp_mask; 7526738c0a9SPraveen Shetty sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi); 7536738c0a9SPraveen Shetty sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END; 7546738c0a9SPraveen Shetty } 7556738c0a9SPraveen Shetty sa->action[1].type = RTE_FLOW_ACTION_TYPE_END; 7566738c0a9SPraveen Shetty 7576738c0a9SPraveen Shetty ret = rte_flow_validate(sa->portid, &sa->attr, sa->pattern, sa->action, 7586738c0a9SPraveen Shetty &err); 7596738c0a9SPraveen Shetty if (ret < 0) { 7606738c0a9SPraveen Shetty RTE_LOG(ERR, IPSEC, "Flow validation failed %s\n", err.message); 7616738c0a9SPraveen Shetty return ret; 7626738c0a9SPraveen Shetty } 7636738c0a9SPraveen Shetty 7646738c0a9SPraveen Shetty sa->flow = rte_flow_create(sa->portid, &sa->attr, sa->pattern, 7656738c0a9SPraveen Shetty sa->action, &err); 7666738c0a9SPraveen Shetty if (!sa->flow) { 7676738c0a9SPraveen Shetty RTE_LOG(ERR, IPSEC, "Flow creation failed %s\n", err.message); 7686738c0a9SPraveen Shetty return -1; 7696738c0a9SPraveen Shetty } 7706738c0a9SPraveen Shetty 7716738c0a9SPraveen Shetty return 0; 7726738c0a9SPraveen Shetty } 7736738c0a9SPraveen Shetty 774d87152e7SKonstantin Ananyev /* 775d87152e7SKonstantin Ananyev * queue crypto-ops into PMD queue. 776d87152e7SKonstantin Ananyev */ 777d87152e7SKonstantin Ananyev void 778d87152e7SKonstantin Ananyev enqueue_cop_burst(struct cdev_qp *cqp) 779d299106eSSergio Gonzalez Monroy { 780d87152e7SKonstantin Ananyev uint32_t i, len, ret; 781d299106eSSergio Gonzalez Monroy 782d87152e7SKonstantin Ananyev len = cqp->len; 783d87152e7SKonstantin Ananyev ret = rte_cryptodev_enqueue_burst(cqp->id, cqp->qp, cqp->buf, len); 784d87152e7SKonstantin Ananyev if (ret < len) { 7855d8f0bafSOlivier Matz RTE_LOG_DP(DEBUG, IPSEC, "Cryptodev %u queue %u:" 786d299106eSSergio Gonzalez Monroy " enqueued %u crypto ops out of %u\n", 787d87152e7SKonstantin Ananyev cqp->id, cqp->qp, ret, len); 788d87152e7SKonstantin Ananyev /* drop packets that we fail to enqueue */ 789d87152e7SKonstantin Ananyev for (i = ret; i < len; i++) 7901329602bSAnoob Joseph free_pkts(&cqp->buf[i]->sym->m_src, 1); 791d299106eSSergio Gonzalez Monroy } 792d299106eSSergio Gonzalez Monroy cqp->in_flight += ret; 793d299106eSSergio Gonzalez Monroy cqp->len = 0; 794d299106eSSergio Gonzalez Monroy } 795d87152e7SKonstantin Ananyev 796d87152e7SKonstantin Ananyev static inline void 797d87152e7SKonstantin Ananyev enqueue_cop(struct cdev_qp *cqp, struct rte_crypto_op *cop) 798d87152e7SKonstantin Ananyev { 799d87152e7SKonstantin Ananyev cqp->buf[cqp->len++] = cop; 800d87152e7SKonstantin Ananyev 801d87152e7SKonstantin Ananyev if (cqp->len == MAX_PKT_BURST) 802d87152e7SKonstantin Ananyev enqueue_cop_burst(cqp); 803d299106eSSergio Gonzalez Monroy } 804d299106eSSergio Gonzalez Monroy 805c64278c0SSergio Gonzalez Monroy static inline void 806c64278c0SSergio Gonzalez Monroy ipsec_enqueue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx, 807ba66534fSMarcin Smoczynski struct rte_mbuf *pkts[], void *sas[], 808c64278c0SSergio Gonzalez Monroy uint16_t nb_pkts) 809d299106eSSergio Gonzalez Monroy { 810906257e9SSergio Gonzalez Monroy int32_t ret = 0, i; 811d299106eSSergio Gonzalez Monroy struct ipsec_mbuf_metadata *priv; 812ec17993aSAkhil Goyal struct rte_crypto_sym_op *sym_cop; 813d299106eSSergio Gonzalez Monroy struct ipsec_sa *sa; 8144a67af84SMarcin Smoczynski struct rte_ipsec_session *ips; 815d299106eSSergio Gonzalez Monroy 816d299106eSSergio Gonzalez Monroy for (i = 0; i < nb_pkts; i++) { 81785f84767SSergio Gonzalez Monroy if (unlikely(sas[i] == NULL)) { 8181329602bSAnoob Joseph free_pkts(&pkts[i], 1); 81985f84767SSergio Gonzalez Monroy continue; 82085f84767SSergio Gonzalez Monroy } 82185f84767SSergio Gonzalez Monroy 822d299106eSSergio Gonzalez Monroy rte_prefetch0(sas[i]); 823d299106eSSergio Gonzalez Monroy rte_prefetch0(pkts[i]); 824d299106eSSergio Gonzalez Monroy 825d299106eSSergio Gonzalez Monroy priv = get_priv(pkts[i]); 826ba66534fSMarcin Smoczynski sa = ipsec_mask_saptr(sas[i]); 827d299106eSSergio Gonzalez Monroy priv->sa = sa; 828ba66534fSMarcin Smoczynski ips = ipsec_get_primary_session(sa); 829d299106eSSergio Gonzalez Monroy 8304a67af84SMarcin Smoczynski switch (ips->type) { 831ec17993aSAkhil Goyal case RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL: 832ec17993aSAkhil Goyal priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 833ec17993aSAkhil Goyal priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 834ec17993aSAkhil Goyal 835ec17993aSAkhil Goyal rte_prefetch0(&priv->sym_cop); 836ec17993aSAkhil Goyal 837a8ade121SVolodymyr Fialko if (unlikely(ips->security.ses == NULL)) { 8381329602bSAnoob Joseph free_pkts(&pkts[i], 1); 839ec17993aSAkhil Goyal continue; 840ec17993aSAkhil Goyal } 841ec17993aSAkhil Goyal 8429a1cc8f1STejasree Kondoj if (unlikely((pkts[i]->packet_type & 8439a1cc8f1STejasree Kondoj (RTE_PTYPE_TUNNEL_MASK | 8449a1cc8f1STejasree Kondoj RTE_PTYPE_L4_MASK)) == 8459a1cc8f1STejasree Kondoj MBUF_PTYPE_TUNNEL_ESP_IN_UDP && 8469a1cc8f1STejasree Kondoj sa->udp_encap != 1)) { 8479a1cc8f1STejasree Kondoj free_pkts(&pkts[i], 1); 8489a1cc8f1STejasree Kondoj continue; 8499a1cc8f1STejasree Kondoj } 8509a1cc8f1STejasree Kondoj 851ec17993aSAkhil Goyal sym_cop = get_sym_cop(&priv->cop); 852ec17993aSAkhil Goyal sym_cop->m_src = pkts[i]; 853ec17993aSAkhil Goyal 854ec17993aSAkhil Goyal rte_security_attach_session(&priv->cop, 8554a67af84SMarcin Smoczynski ips->security.ses); 856ec17993aSAkhil Goyal break; 8575139d5d9SMarcin Smoczynski 8585139d5d9SMarcin Smoczynski case RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO: 8595139d5d9SMarcin Smoczynski RTE_LOG(ERR, IPSEC, "CPU crypto is not supported by the" 8605139d5d9SMarcin Smoczynski " legacy mode."); 8611329602bSAnoob Joseph free_pkts(&pkts[i], 1); 8625139d5d9SMarcin Smoczynski continue; 8635139d5d9SMarcin Smoczynski 864ec17993aSAkhil Goyal case RTE_SECURITY_ACTION_TYPE_NONE: 865ec17993aSAkhil Goyal 866d299106eSSergio Gonzalez Monroy priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 867a60c05b5SSergio Gonzalez Monroy priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 868d299106eSSergio Gonzalez Monroy 869d299106eSSergio Gonzalez Monroy rte_prefetch0(&priv->sym_cop); 870d299106eSSergio Gonzalez Monroy 871a8ade121SVolodymyr Fialko if (unlikely(ips->crypto.ses == NULL)) { 8721329602bSAnoob Joseph free_pkts(&pkts[i], 1); 873d299106eSSergio Gonzalez Monroy continue; 874d299106eSSergio Gonzalez Monroy } 875d299106eSSergio Gonzalez Monroy 876d299106eSSergio Gonzalez Monroy rte_crypto_op_attach_sym_session(&priv->cop, 8774a67af84SMarcin Smoczynski ips->crypto.ses); 878d299106eSSergio Gonzalez Monroy 879c64278c0SSergio Gonzalez Monroy ret = xform_func(pkts[i], sa, &priv->cop); 880d299106eSSergio Gonzalez Monroy if (unlikely(ret)) { 8811329602bSAnoob Joseph free_pkts(&pkts[i], 1); 882d299106eSSergio Gonzalez Monroy continue; 883d299106eSSergio Gonzalez Monroy } 884ec17993aSAkhil Goyal break; 885ec17993aSAkhil Goyal case RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL: 8864a67af84SMarcin Smoczynski RTE_ASSERT(ips->security.ses != NULL); 8873da37f68SRadu Nicolau ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i]; 8884a67af84SMarcin Smoczynski if (ips->security.ol_flags & 8894a67af84SMarcin Smoczynski RTE_SECURITY_TX_OLOAD_NEED_MDATA) 8900ccfd14bSAnoob Joseph rte_security_set_pkt_metadata( 8914a67af84SMarcin Smoczynski ips->security.ctx, ips->security.ses, 8924a67af84SMarcin Smoczynski pkts[i], NULL); 8930ccfd14bSAnoob Joseph continue; 894ec17993aSAkhil Goyal case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO: 8954a67af84SMarcin Smoczynski RTE_ASSERT(ips->security.ses != NULL); 896ec17993aSAkhil Goyal priv->cop.type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 897ec17993aSAkhil Goyal priv->cop.status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 898ec17993aSAkhil Goyal 899ec17993aSAkhil Goyal rte_prefetch0(&priv->sym_cop); 900ec17993aSAkhil Goyal rte_security_attach_session(&priv->cop, 9014a67af84SMarcin Smoczynski ips->security.ses); 902ec17993aSAkhil Goyal 903ec17993aSAkhil Goyal ret = xform_func(pkts[i], sa, &priv->cop); 904ec17993aSAkhil Goyal if (unlikely(ret)) { 9051329602bSAnoob Joseph free_pkts(&pkts[i], 1); 906ec17993aSAkhil Goyal continue; 907ec17993aSAkhil Goyal } 908ec17993aSAkhil Goyal 9093da37f68SRadu Nicolau ipsec_ctx->ol_pkts[ipsec_ctx->ol_pkts_cnt++] = pkts[i]; 9104a67af84SMarcin Smoczynski if (ips->security.ol_flags & 9114a67af84SMarcin Smoczynski RTE_SECURITY_TX_OLOAD_NEED_MDATA) 912ec17993aSAkhil Goyal rte_security_set_pkt_metadata( 9134a67af84SMarcin Smoczynski ips->security.ctx, ips->security.ses, 9144a67af84SMarcin Smoczynski pkts[i], NULL); 915ec17993aSAkhil Goyal continue; 916ec17993aSAkhil Goyal } 917d299106eSSergio Gonzalez Monroy 918a8ade121SVolodymyr Fialko enqueue_cop(sa->cqp[ipsec_ctx->lcore_id], &priv->cop); 919d299106eSSergio Gonzalez Monroy } 920c64278c0SSergio Gonzalez Monroy } 921d299106eSSergio Gonzalez Monroy 922d87152e7SKonstantin Ananyev static inline int32_t 923d87152e7SKonstantin Ananyev ipsec_inline_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx, 924d87152e7SKonstantin Ananyev struct rte_mbuf *pkts[], uint16_t max_pkts) 925d87152e7SKonstantin Ananyev { 926d87152e7SKonstantin Ananyev int32_t nb_pkts, ret; 927d87152e7SKonstantin Ananyev struct ipsec_mbuf_metadata *priv; 928d87152e7SKonstantin Ananyev struct ipsec_sa *sa; 929d87152e7SKonstantin Ananyev struct rte_mbuf *pkt; 930d87152e7SKonstantin Ananyev 931d87152e7SKonstantin Ananyev nb_pkts = 0; 932d87152e7SKonstantin Ananyev while (ipsec_ctx->ol_pkts_cnt > 0 && nb_pkts < max_pkts) { 933d87152e7SKonstantin Ananyev pkt = ipsec_ctx->ol_pkts[--ipsec_ctx->ol_pkts_cnt]; 934d87152e7SKonstantin Ananyev rte_prefetch0(pkt); 935d87152e7SKonstantin Ananyev priv = get_priv(pkt); 936d87152e7SKonstantin Ananyev sa = priv->sa; 937d87152e7SKonstantin Ananyev ret = xform_func(pkt, sa, &priv->cop); 938d87152e7SKonstantin Ananyev if (unlikely(ret)) { 9391329602bSAnoob Joseph free_pkts(&pkt, 1); 940d87152e7SKonstantin Ananyev continue; 941d87152e7SKonstantin Ananyev } 942d87152e7SKonstantin Ananyev pkts[nb_pkts++] = pkt; 943d87152e7SKonstantin Ananyev } 944d87152e7SKonstantin Ananyev 945d87152e7SKonstantin Ananyev return nb_pkts; 946d87152e7SKonstantin Ananyev } 947d87152e7SKonstantin Ananyev 948c64278c0SSergio Gonzalez Monroy static inline int 949c64278c0SSergio Gonzalez Monroy ipsec_dequeue(ipsec_xform_fn xform_func, struct ipsec_ctx *ipsec_ctx, 950c64278c0SSergio Gonzalez Monroy struct rte_mbuf *pkts[], uint16_t max_pkts) 951c64278c0SSergio Gonzalez Monroy { 952906257e9SSergio Gonzalez Monroy int32_t nb_pkts = 0, ret = 0, i, j, nb_cops; 953c64278c0SSergio Gonzalez Monroy struct ipsec_mbuf_metadata *priv; 954c64278c0SSergio Gonzalez Monroy struct rte_crypto_op *cops[max_pkts]; 955c64278c0SSergio Gonzalez Monroy struct ipsec_sa *sa; 956c64278c0SSergio Gonzalez Monroy struct rte_mbuf *pkt; 957c64278c0SSergio Gonzalez Monroy 958833e36b8SRadu Nicolau for (i = 0; i < ipsec_ctx->nb_qps && nb_pkts < max_pkts; i++) { 959d299106eSSergio Gonzalez Monroy struct cdev_qp *cqp; 960833e36b8SRadu Nicolau 961833e36b8SRadu Nicolau cqp = &ipsec_ctx->tbl[ipsec_ctx->last_qp++]; 962833e36b8SRadu Nicolau if (ipsec_ctx->last_qp == ipsec_ctx->nb_qps) 963833e36b8SRadu Nicolau ipsec_ctx->last_qp %= ipsec_ctx->nb_qps; 964d299106eSSergio Gonzalez Monroy 965833e36b8SRadu Nicolau if (cqp->in_flight == 0) 966d299106eSSergio Gonzalez Monroy continue; 967d299106eSSergio Gonzalez Monroy 968d299106eSSergio Gonzalez Monroy nb_cops = rte_cryptodev_dequeue_burst(cqp->id, cqp->qp, 969d299106eSSergio Gonzalez Monroy cops, max_pkts - nb_pkts); 970d299106eSSergio Gonzalez Monroy 971d299106eSSergio Gonzalez Monroy cqp->in_flight -= nb_cops; 972d299106eSSergio Gonzalez Monroy 973d299106eSSergio Gonzalez Monroy for (j = 0; j < nb_cops; j++) { 974d299106eSSergio Gonzalez Monroy pkt = cops[j]->sym->m_src; 975d299106eSSergio Gonzalez Monroy rte_prefetch0(pkt); 976d299106eSSergio Gonzalez Monroy 977d299106eSSergio Gonzalez Monroy priv = get_priv(pkt); 978d299106eSSergio Gonzalez Monroy sa = priv->sa; 979d299106eSSergio Gonzalez Monroy 98050705e8eSThomas Monjalon RTE_ASSERT(sa != NULL); 981d299106eSSergio Gonzalez Monroy 9824a67af84SMarcin Smoczynski if (ipsec_get_action_type(sa) == 9834a67af84SMarcin Smoczynski RTE_SECURITY_ACTION_TYPE_NONE) { 984c64278c0SSergio Gonzalez Monroy ret = xform_func(pkt, sa, cops[j]); 985ec17993aSAkhil Goyal if (unlikely(ret)) { 9861329602bSAnoob Joseph free_pkts(&pkt, 1); 987ec17993aSAkhil Goyal continue; 988ec17993aSAkhil Goyal } 9894a67af84SMarcin Smoczynski } else if (ipsec_get_action_type(sa) == 99074ac7558SMichael Shamis RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) { 99174ac7558SMichael Shamis if (cops[j]->status) { 9921329602bSAnoob Joseph free_pkts(&pkt, 1); 99374ac7558SMichael Shamis continue; 99474ac7558SMichael Shamis } 995ec17993aSAkhil Goyal } 996d299106eSSergio Gonzalez Monroy pkts[nb_pkts++] = pkt; 997d299106eSSergio Gonzalez Monroy } 998d299106eSSergio Gonzalez Monroy } 999d299106eSSergio Gonzalez Monroy 1000d299106eSSergio Gonzalez Monroy /* return packets */ 1001d299106eSSergio Gonzalez Monroy return nb_pkts; 1002d299106eSSergio Gonzalez Monroy } 1003d299106eSSergio Gonzalez Monroy 1004d299106eSSergio Gonzalez Monroy uint16_t 1005d299106eSSergio Gonzalez Monroy ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 1006d299106eSSergio Gonzalez Monroy uint16_t nb_pkts, uint16_t len) 1007d299106eSSergio Gonzalez Monroy { 1008ba66534fSMarcin Smoczynski void *sas[nb_pkts]; 1009d299106eSSergio Gonzalez Monroy 1010d299106eSSergio Gonzalez Monroy inbound_sa_lookup(ctx->sa_ctx, pkts, sas, nb_pkts); 1011d299106eSSergio Gonzalez Monroy 1012c64278c0SSergio Gonzalez Monroy ipsec_enqueue(esp_inbound, ctx, pkts, sas, nb_pkts); 1013c64278c0SSergio Gonzalez Monroy 1014d87152e7SKonstantin Ananyev return ipsec_inline_dequeue(esp_inbound_post, ctx, pkts, len); 1015d87152e7SKonstantin Ananyev } 1016d87152e7SKonstantin Ananyev 1017d87152e7SKonstantin Ananyev uint16_t 1018d87152e7SKonstantin Ananyev ipsec_inbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 1019d87152e7SKonstantin Ananyev uint16_t len) 1020d87152e7SKonstantin Ananyev { 1021c64278c0SSergio Gonzalez Monroy return ipsec_dequeue(esp_inbound_post, ctx, pkts, len); 1022d299106eSSergio Gonzalez Monroy } 1023d299106eSSergio Gonzalez Monroy 1024d299106eSSergio Gonzalez Monroy uint16_t 1025d299106eSSergio Gonzalez Monroy ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 1026d299106eSSergio Gonzalez Monroy uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len) 1027d299106eSSergio Gonzalez Monroy { 1028ba66534fSMarcin Smoczynski void *sas[nb_pkts]; 1029d299106eSSergio Gonzalez Monroy 1030d299106eSSergio Gonzalez Monroy outbound_sa_lookup(ctx->sa_ctx, sa_idx, sas, nb_pkts); 1031d299106eSSergio Gonzalez Monroy 1032c64278c0SSergio Gonzalez Monroy ipsec_enqueue(esp_outbound, ctx, pkts, sas, nb_pkts); 1033c64278c0SSergio Gonzalez Monroy 1034d87152e7SKonstantin Ananyev return ipsec_inline_dequeue(esp_outbound_post, ctx, pkts, len); 1035d87152e7SKonstantin Ananyev } 1036d87152e7SKonstantin Ananyev 1037d87152e7SKonstantin Ananyev uint16_t 1038d87152e7SKonstantin Ananyev ipsec_outbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 1039d87152e7SKonstantin Ananyev uint16_t len) 1040d87152e7SKonstantin Ananyev { 1041c64278c0SSergio Gonzalez Monroy return ipsec_dequeue(esp_outbound_post, ctx, pkts, len); 1042d299106eSSergio Gonzalez Monroy } 1043