X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl2fwd-crypto%2Fmain.c;h=8d4a10aef3ddcc3ca890cfc2a740f200c0a01743;hb=459369fc956d18e53a7cd13b1180d1a07bb420e5;hp=776595d4271d8a2359c4e1f97ba08c64c5008a58;hpb=12a4aaf1df41669caf25151d2495cc48341e3e9a;p=dpdk.git diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 776595d427..8d4a10aef3 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2015-2017 Intel Corporation. All rights reserved. + * Copyright(c) 2015-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -88,6 +88,8 @@ enum cdev_type { #define MAX_KEY_SIZE 128 #define MAX_PKT_BURST 32 #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ +#define MAX_SESSIONS 32 +#define SESSION_POOL_CACHE_SIZE 0 #define MAXIMUM_IV_LENGTH 16 #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ @@ -130,7 +132,8 @@ enum l2fwd_crypto_xform_chain { L2FWD_CRYPTO_CIPHER_HASH, L2FWD_CRYPTO_HASH_CIPHER, L2FWD_CRYPTO_CIPHER_ONLY, - L2FWD_CRYPTO_HASH_ONLY + L2FWD_CRYPTO_HASH_ONLY, + L2FWD_CRYPTO_AEAD }; struct l2fwd_key { @@ -172,6 +175,14 @@ struct l2fwd_crypto_options { unsigned int auth_iv_param; int auth_iv_random_size; + struct rte_crypto_sym_xform aead_xform; + unsigned int aead_key_param; + int aead_key_random_size; + + struct l2fwd_iv aead_iv; + unsigned int aead_iv_param; + int aead_iv_random_size; + struct l2fwd_key aad; unsigned aad_param; int aad_random_size; @@ -194,15 +205,18 @@ struct l2fwd_crypto_params { struct l2fwd_iv cipher_iv; struct l2fwd_iv auth_iv; + struct l2fwd_iv aead_iv; struct l2fwd_key aad; struct rte_cryptodev_sym_session *session; uint8_t do_cipher; uint8_t do_hash; + uint8_t do_aead; uint8_t hash_verify; enum rte_crypto_cipher_algorithm cipher_algo; enum rte_crypto_auth_algorithm auth_algo; + enum rte_crypto_aead_algorithm aead_algo; }; /** lcore configuration */ @@ -237,6 +251,7 @@ static const struct rte_eth_conf port_conf = { struct rte_mempool *l2fwd_pktmbuf_pool; struct rte_mempool *l2fwd_crypto_op_pool; +struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 }; /* Per-port statistics struct */ struct l2fwd_port_statistics { @@ -481,7 +496,6 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, rte_pktmbuf_pkt_len(m) - cparams->digest_length); - op->sym->auth.digest.length = cparams->digest_length; /* For wireless algorithms, offset/length must be in bits */ if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 || @@ -493,14 +507,6 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->auth.data.offset = ipdata_offset; op->sym->auth.data.length = data_len; } - - if (cparams->aad.length) { - op->sym->auth.aad.data = cparams->aad.data; - op->sym->auth.aad.phys_addr = cparams->aad.phys_addr; - } else { - op->sym->auth.aad.data = NULL; - op->sym->auth.aad.phys_addr = 0; - } } if (cparams->do_cipher) { @@ -522,6 +528,33 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, } } + if (cparams->do_aead) { + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, + IV_OFFSET); + /* Copy IV at the end of the crypto operation */ + rte_memcpy(iv_ptr, cparams->aead_iv.data, cparams->aead_iv.length); + + op->sym->aead.data.offset = ipdata_offset; + op->sym->aead.data.length = data_len; + + if (!cparams->hash_verify) { + /* Append space for digest to end of packet */ + op->sym->aead.digest.data = (uint8_t *)rte_pktmbuf_append(m, + cparams->digest_length); + } else { + op->sym->aead.digest.data = rte_pktmbuf_mtod(m, + uint8_t *) + ipdata_offset + data_len; + } + + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, + rte_pktmbuf_pkt_len(m) - cparams->digest_length); + + if (cparams->aad.length) { + op->sym->aead.aad.data = cparams->aad.data; + op->sym->aead.aad.phys_addr = cparams->aad.phys_addr; + } + } + op->sym->m_src = m; return l2fwd_crypto_enqueue(op, cparams); @@ -613,12 +646,16 @@ generate_random_key(uint8_t *key, unsigned length) } static struct rte_cryptodev_sym_session * -initialize_crypto_session(struct l2fwd_crypto_options *options, - uint8_t cdev_id) +initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id) { struct rte_crypto_sym_xform *first_xform; + struct rte_cryptodev_sym_session *session; + uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); + struct rte_mempool *sess_mp = session_pool_socket[socket_id]; - if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { + if (options->xform_chain == L2FWD_CRYPTO_AEAD) { + first_xform = &options->aead_xform; + } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { first_xform = &options->cipher_xform; first_xform->next = &options->auth_xform; } else if (options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER) { @@ -630,8 +667,16 @@ initialize_crypto_session(struct l2fwd_crypto_options *options, first_xform = &options->auth_xform; } - /* Setup Cipher Parameters */ - return rte_cryptodev_sym_session_create(cdev_id, first_xform); + session = rte_cryptodev_sym_session_create(sess_mp); + + if (session == NULL) + return NULL; + + if (rte_cryptodev_sym_session_init(cdev_id, session, + first_xform, sess_mp) < 0) + return NULL; + + return session; } static void @@ -652,6 +697,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) US_PER_S * BURST_TX_DRAIN_US; struct l2fwd_crypto_params *cparams; struct l2fwd_crypto_params port_cparams[qconf->nb_crypto_devs]; + struct rte_cryptodev_sym_session *session; if (qconf->nb_rx_ports == 0) { RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); @@ -670,8 +716,12 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) for (i = 0; i < qconf->nb_crypto_devs; i++) { port_cparams[i].do_cipher = 0; port_cparams[i].do_hash = 0; + port_cparams[i].do_aead = 0; switch (options->xform_chain) { + case L2FWD_CRYPTO_AEAD: + port_cparams[i].do_aead = 1; + break; case L2FWD_CRYPTO_CIPHER_HASH: case L2FWD_CRYPTO_HASH_CIPHER: port_cparams[i].do_cipher = 1; @@ -696,6 +746,14 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) if (!options->auth_iv_param) generate_random_key(port_cparams[i].auth_iv.data, port_cparams[i].auth_iv.length); + if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) + port_cparams[i].hash_verify = 1; + else + port_cparams[i].hash_verify = 0; + + port_cparams[i].auth_algo = options->auth_xform.auth.algo; + port_cparams[i].digest_length = + options->auth_xform.auth.digest_length; /* Set IV parameters */ if (options->auth_iv.length) { options->auth_xform.auth.iv.offset = @@ -703,11 +761,21 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) options->auth_xform.auth.iv.length = options->auth_iv.length; } + } + + if (port_cparams[i].do_aead) { + port_cparams[i].aead_iv.data = options->aead_iv.data; + port_cparams[i].aead_iv.length = options->aead_iv.length; + if (!options->aead_iv_param) + generate_random_key(port_cparams[i].aead_iv.data, + port_cparams[i].aead_iv.length); + port_cparams[i].aead_algo = options->aead_xform.aead.algo; port_cparams[i].digest_length = - options->auth_xform.auth.digest_length; - if (options->auth_xform.auth.add_auth_data_length) { + options->aead_xform.aead.digest_length; + if (options->aead_xform.aead.aad_length) { port_cparams[i].aad.data = options->aad.data; port_cparams[i].aad.phys_addr = options->aad.phys_addr; + port_cparams[i].aad.length = options->aad.length; if (!options->aad_param) generate_random_key(port_cparams[i].aad.data, port_cparams[i].aad.length); @@ -715,12 +783,14 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) } else port_cparams[i].aad.length = 0; - if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) + if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) port_cparams[i].hash_verify = 1; else port_cparams[i].hash_verify = 0; - port_cparams[i].auth_algo = options->auth_xform.auth.algo; + /* Set IV parameters */ + options->aead_xform.aead.iv.offset = IV_OFFSET; + options->aead_xform.aead.iv.length = options->aead_iv.length; } if (port_cparams[i].do_cipher) { @@ -737,11 +807,13 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) options->cipher_iv.length; } - port_cparams[i].session = initialize_crypto_session(options, + session = initialize_crypto_session(options, port_cparams[i].dev_id); + if (session == NULL) + rte_exit(EXIT_FAILURE, "Failed to initialize crypto session\n"); + + port_cparams[i].session = session; - if (port_cparams[i].session == NULL) - return; RTE_LOG(INFO, L2FWD, " -- lcoreid=%u cryptoid=%u\n", lcore_id, port_cparams[i].dev_id); } @@ -882,7 +954,7 @@ l2fwd_crypto_usage(const char *prgname) " --cdev_type HW / SW / ANY\n" " --chain HASH_CIPHER / CIPHER_HASH / CIPHER_ONLY /" - " HASH_ONLY\n" + " HASH_ONLY / AEAD\n" " --cipher_algo ALGO\n" " --cipher_op ENCRYPT / DECRYPT\n" @@ -897,8 +969,16 @@ l2fwd_crypto_usage(const char *prgname) " --auth_key_random_size SIZE: size of auth key when generated randomly\n" " --auth_iv IV (bytes separated with \":\")\n" " --auth_iv_random_size SIZE: size of auth IV when generated randomly\n" + + " --aead_algo ALGO\n" + " --aead_op ENCRYPT / DECRYPT\n" + " --aead_key KEY (bytes separated with \":\")\n" + " --aead_key_random_size SIZE: size of AEAD key when generated randomly\n" + " --aead_iv IV (bytes separated with \":\")\n" + " --aead_iv_random_size SIZE: size of AEAD IV when generated randomly\n" " --aad AAD (bytes separated with \":\")\n" " --aad_random_size SIZE: size of AAD when generated randomly\n" + " --digest_size SIZE: size of digest to be generated/verified\n" " --sessionless\n" @@ -940,6 +1020,9 @@ parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) } else if (strcmp("HASH_ONLY", optarg) == 0) { options->xform_chain = L2FWD_CRYPTO_HASH_ONLY; return 0; + } else if (strcmp("AEAD", optarg) == 0) { + options->xform_chain = L2FWD_CRYPTO_AEAD; + return 0; } return -1; @@ -1046,6 +1129,32 @@ parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg) return -1; } +static int +parse_aead_algo(enum rte_crypto_aead_algorithm *algo, char *optarg) +{ + if (rte_cryptodev_get_aead_algo_enum(algo, optarg) < 0) { + RTE_LOG(ERR, USER1, "AEAD algorithm specified " + "not supported!\n"); + return -1; + } + + return 0; +} + +static int +parse_aead_op(enum rte_crypto_aead_operation *op, char *optarg) +{ + if (strcmp("ENCRYPT", optarg) == 0) { + *op = RTE_CRYPTO_AEAD_OP_ENCRYPT; + return 0; + } else if (strcmp("DECRYPT", optarg) == 0) { + *op = RTE_CRYPTO_AEAD_OP_DECRYPT; + return 0; + } + + printf("AEAD operation specified not supported!\n"); + return -1; +} static int parse_cryptodev_mask(struct l2fwd_crypto_options *options, const char *q_arg) @@ -1144,7 +1253,6 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, return parse_size(&options->akey_random_size, optarg); } - else if (strcmp(lgopts[option_index].name, "auth_iv") == 0) { options->auth_iv_param = 1; options->auth_iv.length = @@ -1158,6 +1266,43 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, else if (strcmp(lgopts[option_index].name, "auth_iv_random_size") == 0) return parse_size(&options->auth_iv_random_size, optarg); + /* AEAD options */ + else if (strcmp(lgopts[option_index].name, "aead_algo") == 0) { + return parse_aead_algo(&options->aead_xform.aead.algo, + optarg); + } + + else if (strcmp(lgopts[option_index].name, "aead_op") == 0) + return parse_aead_op(&options->aead_xform.aead.op, + optarg); + + else if (strcmp(lgopts[option_index].name, "aead_key") == 0) { + options->aead_key_param = 1; + options->aead_xform.aead.key.length = + parse_key(options->aead_xform.aead.key.data, optarg); + if (options->aead_xform.aead.key.length > 0) + return 0; + else + return -1; + } + + else if (strcmp(lgopts[option_index].name, "aead_key_random_size") == 0) + return parse_size(&options->aead_key_random_size, optarg); + + + else if (strcmp(lgopts[option_index].name, "aead_iv") == 0) { + options->aead_iv_param = 1; + options->aead_iv.length = + parse_key(options->aead_iv.data, optarg); + if (options->aead_iv.length > 0) + return 0; + else + return -1; + } + + else if (strcmp(lgopts[option_index].name, "aead_iv_random_size") == 0) + return parse_size(&options->aead_iv_random_size, optarg); + else if (strcmp(lgopts[option_index].name, "aad") == 0) { options->aad_param = 1; options->aad.length = @@ -1292,13 +1437,28 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) options->auth_iv_param = 0; options->auth_iv_random_size = -1; options->auth_iv.length = 0; + + options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* AEAD Data */ + options->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; + options->aead_xform.next = NULL; + options->aead_key_param = 0; + options->aead_key_random_size = -1; + options->aead_xform.aead.key.length = 0; + options->aead_iv_param = 0; + options->aead_iv_random_size = -1; + options->aead_iv.length = 0; + + options->auth_xform.aead.algo = RTE_CRYPTO_AEAD_AES_GCM; + options->auth_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT; + options->aad_param = 0; options->aad_random_size = -1; options->aad.length = 0; - options->digest_size = -1; - options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + options->digest_size = -1; options->type = CDEV_TYPE_ANY; options->cryptodev_mask = UINT64_MAX; @@ -1326,6 +1486,18 @@ display_auth_info(struct l2fwd_crypto_options *options) options->auth_xform.auth.key.data, options->auth_xform.auth.key.length); rte_hexdump(stdout, "IV:", options->auth_iv.data, options->auth_iv.length); +} + +static void +display_aead_info(struct l2fwd_crypto_options *options) +{ + printf("\n---- AEAD information ---\n"); + printf("Algorithm: %s\n", + rte_crypto_aead_algorithm_strings[options->aead_xform.aead.algo]); + rte_hexdump(stdout, "AEAD key:", + options->aead_xform.aead.key.data, + options->aead_xform.aead.key.length); + rte_hexdump(stdout, "IV:", options->aead_iv.data, options->aead_iv.length); rte_hexdump(stdout, "AAD:", options->aad.data, options->aad.length); } @@ -1334,6 +1506,7 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) { char string_cipher_op[MAX_STR_LEN]; char string_auth_op[MAX_STR_LEN]; + char string_aead_op[MAX_STR_LEN]; if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) strcpy(string_cipher_op, "Encrypt"); @@ -1345,6 +1518,12 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) else strcpy(string_auth_op, "Auth verify"); + if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) + strcpy(string_aead_op, "Authenticated encryption"); + else + strcpy(string_aead_op, "Authenticated decryption"); + + printf("Options:-\nn"); printf("portmask: %x\n", options->portmask); printf("ports per lcore: %u\n", options->nb_ports_per_lcore); @@ -1374,6 +1553,10 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) printf("\nCrypto chain: "); switch (options->xform_chain) { + case L2FWD_CRYPTO_AEAD: + printf("Input --> %s --> Output\n", string_aead_op); + display_aead_info(options); + break; case L2FWD_CRYPTO_CIPHER_HASH: printf("Input --> %s --> %s --> Output\n", string_cipher_op, string_auth_op); @@ -1425,8 +1608,16 @@ l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options, { "auth_iv", required_argument, 0, 0 }, { "auth_iv_random_size", required_argument, 0, 0 }, + { "aead_algo", required_argument, 0, 0 }, + { "aead_op", required_argument, 0, 0 }, + { "aead_key", required_argument, 0, 0 }, + { "aead_key_random_size", required_argument, 0, 0 }, + { "aead_iv", required_argument, 0, 0 }, + { "aead_iv_random_size", required_argument, 0, 0 }, + { "aad", required_argument, 0, 0 }, { "aad_random_size", required_argument, 0, 0 }, + { "digest_size", required_argument, 0, 0 }, { "sessionless", no_argument, 0, 0 }, @@ -1557,7 +1748,8 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) /* Check if device has to be HW/SW or any */ static int -check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_info) +check_type(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info) { if (options->type == CDEV_TYPE_HW && (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) @@ -1571,6 +1763,108 @@ check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_ return -1; } +static const struct rte_cryptodev_capabilities * +check_device_support_cipher_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_cipher_algorithm cap_cipher_algo; + enum rte_crypto_cipher_algorithm opt_cipher_algo = + options->cipher_xform.cipher.algo; + + while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { + cap_cipher_algo = cap->sym.cipher.algo; + if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (cap_cipher_algo == opt_cipher_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_cipher_algorithm_strings[opt_cipher_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + +static const struct rte_cryptodev_capabilities * +check_device_support_auth_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_auth_algorithm cap_auth_algo; + enum rte_crypto_auth_algorithm opt_auth_algo = + options->auth_xform.auth.algo; + + while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { + cap_auth_algo = cap->sym.auth.algo; + if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (cap_auth_algo == opt_auth_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_auth_algorithm_strings[opt_auth_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + +static const struct rte_cryptodev_capabilities * +check_device_support_aead_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_aead_algorithm cap_aead_algo; + enum rte_crypto_aead_algorithm opt_aead_algo = + options->aead_xform.aead.algo; + + while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { + cap_aead_algo = cap->sym.aead.algo; + if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (cap_aead_algo == opt_aead_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_aead_algorithm_strings[opt_aead_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + /* Check if the device is enabled by cryptodev_mask */ static int check_cryptodev_mask(struct l2fwd_crypto_options *options, @@ -1648,12 +1942,9 @@ static int initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, uint8_t *enabled_cdevs) { - unsigned i, cdev_id, cdev_count, enabled_cdev_count = 0; + unsigned int cdev_id, cdev_count, enabled_cdev_count = 0; const struct rte_cryptodev_capabilities *cap; - enum rte_crypto_auth_algorithm cap_auth_algo; - enum rte_crypto_auth_algorithm opt_auth_algo; - enum rte_crypto_cipher_algorithm cap_cipher_algo; - enum rte_crypto_cipher_algorithm opt_cipher_algo; + unsigned int sess_sz, max_sess_sz = 0; int retval; cdev_count = rte_cryptodev_count(); @@ -1662,18 +1953,21 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, return -1; } + for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) { + sess_sz = rte_cryptodev_get_private_session_size(cdev_id); + if (sess_sz > max_sess_sz) + max_sess_sz = sess_sz; + } + for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports; cdev_id++) { struct rte_cryptodev_qp_conf qp_conf; struct rte_cryptodev_info dev_info; + uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); struct rte_cryptodev_config conf = { .nb_queue_pairs = 1, - .socket_id = SOCKET_ID_ANY, - .session_mp = { - .nb_objs = 2048, - .cache_size = 64 - } + .socket_id = socket_id, }; if (check_cryptodev_mask(options, (uint8_t)cdev_id)) @@ -1681,34 +1975,150 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, rte_cryptodev_info_get(cdev_id, &dev_info); + if (session_pool_socket[socket_id] == NULL) { + char mp_name[RTE_MEMPOOL_NAMESIZE]; + struct rte_mempool *sess_mp; + + snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, + "sess_mp_%u", socket_id); + + /* + * Create enough objects for session headers and + * device private data + */ + sess_mp = rte_mempool_create(mp_name, + MAX_SESSIONS * 2, + max_sess_sz, + SESSION_POOL_CACHE_SIZE, + 0, NULL, NULL, NULL, + NULL, socket_id, + 0); + + if (sess_mp == NULL) { + printf("Cannot create session pool on socket %d\n", + socket_id); + return -ENOMEM; + } + + printf("Allocated session pool on socket %d\n", socket_id); + session_pool_socket[socket_id] = sess_mp; + } + + /* Set AEAD parameters */ + if (options->xform_chain == L2FWD_CRYPTO_AEAD) { + /* Check if device supports AEAD algo */ + cap = check_device_support_aead_algo(options, &dev_info, + cdev_id); + if (cap == NULL) + continue; + + options->block_size = cap->sym.aead.block_size; + + check_iv_param(&cap->sym.aead.iv_size, + options->aead_iv_param, + options->aead_iv_random_size, + &options->aead_iv.length); + + /* + * Check if length of provided AEAD key is supported + * by the algorithm chosen. + */ + if (options->aead_key_param) { + if (check_supported_size( + options->aead_xform.aead.key.length, + cap->sym.aead.key_size.min, + cap->sym.aead.key_size.max, + cap->sym.aead.key_size.increment) + != 0) { + printf("Unsupported aead key length\n"); + return -1; + } + /* + * Check if length of the aead key to be randomly generated + * is supported by the algorithm chosen. + */ + } else if (options->aead_key_random_size != -1) { + if (check_supported_size(options->aead_key_random_size, + cap->sym.aead.key_size.min, + cap->sym.aead.key_size.max, + cap->sym.aead.key_size.increment) + != 0) { + printf("Unsupported aead key length\n"); + return -1; + } + options->aead_xform.aead.key.length = + options->aead_key_random_size; + /* No size provided, use minimum size. */ + } else + options->aead_xform.aead.key.length = + cap->sym.aead.key_size.min; + + if (!options->aead_key_param) + generate_random_key( + options->aead_xform.aead.key.data, + options->aead_xform.aead.key.length); + + /* + * Check if length of provided AAD is supported + * by the algorithm chosen. + */ + if (options->aad_param) { + if (check_supported_size(options->aad.length, + cap->sym.aead.aad_size.min, + cap->sym.aead.aad_size.max, + cap->sym.aead.aad_size.increment) + != 0) { + printf("Unsupported AAD length\n"); + return -1; + } + /* + * Check if length of AAD to be randomly generated + * is supported by the algorithm chosen. + */ + } else if (options->aad_random_size != -1) { + if (check_supported_size(options->aad_random_size, + cap->sym.aead.aad_size.min, + cap->sym.aead.aad_size.max, + cap->sym.aead.aad_size.increment) + != 0) { + printf("Unsupported AAD length\n"); + return -1; + } + options->aad.length = options->aad_random_size; + /* No size provided, use minimum size. */ + } else + options->aad.length = cap->sym.auth.aad_size.min; + + options->aead_xform.aead.aad_length = + options->aad.length; + + /* Check if digest size is supported by the algorithm. */ + if (options->digest_size != -1) { + if (check_supported_size(options->digest_size, + cap->sym.aead.digest_size.min, + cap->sym.aead.digest_size.max, + cap->sym.aead.digest_size.increment) + != 0) { + printf("Unsupported digest length\n"); + return -1; + } + options->aead_xform.aead.digest_length = + options->digest_size; + /* No size provided, use minimum size. */ + } else + options->aead_xform.aead.digest_length = + cap->sym.aead.digest_size.min; + } + /* Set cipher parameters */ if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { /* Check if device supports cipher algo */ - i = 0; - opt_cipher_algo = options->cipher_xform.cipher.algo; - cap = &dev_info.capabilities[i]; - while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { - cap_cipher_algo = cap->sym.cipher.algo; - if (cap->sym.xform_type == - RTE_CRYPTO_SYM_XFORM_CIPHER) { - if (cap_cipher_algo == opt_cipher_algo) { - if (check_type(options, &dev_info) == 0) - break; - } - } - cap = &dev_info.capabilities[++i]; - } - - if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { - printf("Algorithm %s not supported by cryptodev %u" - " or device not of preferred type (%s)\n", - rte_crypto_cipher_algorithm_strings[opt_cipher_algo], - cdev_id, - options->string_type); + cap = check_device_support_cipher_algo(options, &dev_info, + cdev_id); + if (cap == NULL) continue; - } options->block_size = cap->sym.cipher.block_size; @@ -1763,66 +2173,15 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { /* Check if device supports auth algo */ - i = 0; - opt_auth_algo = options->auth_xform.auth.algo; - cap = &dev_info.capabilities[i]; - while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { - cap_auth_algo = cap->sym.auth.algo; - if ((cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) && - (cap_auth_algo == opt_auth_algo) && - (check_type(options, &dev_info) == 0)) { - break; - } - cap = &dev_info.capabilities[++i]; - } - - if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { - printf("Algorithm %s not supported by cryptodev %u" - " or device not of preferred type (%s)\n", - rte_crypto_auth_algorithm_strings[opt_auth_algo], - cdev_id, - options->string_type); + cap = check_device_support_auth_algo(options, &dev_info, + cdev_id); + if (cap == NULL) continue; - } check_iv_param(&cap->sym.auth.iv_size, options->auth_iv_param, options->auth_iv_random_size, &options->auth_iv.length); - /* - * Check if length of provided AAD is supported - * by the algorithm chosen. - */ - if (options->aad_param) { - if (check_supported_size(options->aad.length, - cap->sym.auth.aad_size.min, - cap->sym.auth.aad_size.max, - cap->sym.auth.aad_size.increment) - != 0) { - printf("Unsupported AAD length\n"); - return -1; - } - /* - * Check if length of AAD to be randomly generated - * is supported by the algorithm chosen. - */ - } else if (options->aad_random_size != -1) { - if (check_supported_size(options->aad_random_size, - cap->sym.auth.aad_size.min, - cap->sym.auth.aad_size.max, - cap->sym.auth.aad_size.increment) - != 0) { - printf("Unsupported AAD length\n"); - return -1; - } - options->aad.length = options->aad_random_size; - /* No size provided, use minimum size. */ - } else - options->aad.length = cap->sym.auth.aad_size.min; - - options->auth_xform.auth.add_auth_data_length = - options->aad.length; - /* * Check if length of provided auth key is supported * by the algorithm chosen. @@ -1889,7 +2248,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, qp_conf.nb_descriptors = 2048; retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, - SOCKET_ID_ANY); + socket_id, session_pool_socket[socket_id]); if (retval < 0) { printf("Failed to setup queue pair %u on cryptodev %u", 0, cdev_id); @@ -1945,6 +2304,14 @@ initialize_ports(struct l2fwd_crypto_options *options) return -1; } + retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, + &nb_txd); + if (retval < 0) { + printf("Cannot adjust number of descriptors: err=%d, port=%u\n", + retval, (unsigned) portid); + return -1; + } + /* init one RX queue */ fflush(stdout); retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, @@ -2024,12 +2391,16 @@ reserve_key_memory(struct l2fwd_crypto_options *options) if (options->cipher_xform.cipher.key.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key"); - options->auth_xform.auth.key.data = rte_malloc("auth key", MAX_KEY_SIZE, 0); if (options->auth_xform.auth.key.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key"); + options->aead_xform.aead.key.data = rte_malloc("aead key", + MAX_KEY_SIZE, 0); + if (options->aead_xform.aead.key.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD key"); + options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0); if (options->cipher_iv.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher IV"); @@ -2038,6 +2409,10 @@ reserve_key_memory(struct l2fwd_crypto_options *options) if (options->auth_iv.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth IV"); + options->aead_iv.data = rte_malloc("aead_iv", MAX_KEY_SIZE, 0); + if (options->aead_iv.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv"); + options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); if (options->aad.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD");