X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl2fwd-crypto%2Fmain.c;h=43fef59e5295f8e9b4a2ff963797f9513aa50102;hb=a67323e49c47380604c0dece509ffd9b7e58cfc3;hp=c561270b3845d1df06ee1ecb7745ac9284bec0e1;hpb=a061e50a0d979e414f239c32cad1fc4de065e9b8;p=dpdk.git diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index c561270b38..43fef59e52 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include @@ -70,7 +72,7 @@ #include #include #include -#include +#include enum cdev_type { CDEV_TYPE_ANY, @@ -133,6 +135,9 @@ struct l2fwd_key { phys_addr_t phys_addr; }; +char supported_auth_algo[RTE_CRYPTO_AUTH_LIST_END][MAX_STR_LEN]; +char supported_cipher_algo[RTE_CRYPTO_CIPHER_LIST_END][MAX_STR_LEN]; + /** l2fwd crypto application command line options */ struct l2fwd_crypto_options { unsigned portmask; @@ -164,8 +169,6 @@ struct l2fwd_crypto_options { int digest_size; uint16_t block_size; - char string_auth_algo[MAX_STR_LEN]; - char string_cipher_algo[MAX_STR_LEN]; char string_type[MAX_STR_LEN]; }; @@ -241,7 +244,7 @@ struct l2fwd_crypto_statistics { } __rte_cache_aligned; struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; -struct l2fwd_crypto_statistics crypto_statistics[RTE_MAX_ETHPORTS]; +struct l2fwd_crypto_statistics crypto_statistics[RTE_CRYPTO_MAX_DEVS]; /* A tsc-based timer responsible for triggering statistics printout */ #define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ @@ -328,6 +331,48 @@ print_stats(void) printf("\n====================================================\n"); } +static void +fill_supported_algorithm_tables(void) +{ + unsigned i; + + for (i = 0; i < RTE_CRYPTO_AUTH_LIST_END; i++) + strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); + + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], + "AES_XCBC_MAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_ZUC_EIA3], "ZUC_EIA3"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); + + for (i = 0; i < RTE_CRYPTO_CIPHER_LIST_END; i++) + strcpy(supported_cipher_algo[i], "NOT_SUPPORTED"); + + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_AES_CBC], "AES_CBC"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_AES_CTR], "AES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_AES_GCM], "AES_GCM"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_NULL], "NULL"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_ZUC_EEA3], "ZUC_EEA3"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); +} static int @@ -406,6 +451,10 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, /* Zero pad data to be crypto'd so it is block aligned */ data_len = rte_pktmbuf_data_len(m) - ipdata_offset; + + if (cparams->do_hash && cparams->hash_verify) + data_len -= cparams->digest_length; + pad_len = data_len % cparams->block_size ? cparams->block_size - (data_len % cparams->block_size) : 0; @@ -427,16 +476,18 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, cparams->digest_length); } else { - op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, - cparams->digest_length); + op->sym->auth.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); op->sym->auth.digest.length = cparams->digest_length; - /* For SNOW3G algorithms, offset/length must be in bits */ - if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) { + /* For wireless algorithms, offset/length must be in bits */ + if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 || + cparams->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 || + cparams->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3) { op->sym->auth.data.offset = ipdata_offset << 3; op->sym->auth.data.length = data_len << 3; } else { @@ -456,24 +507,15 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->cipher.iv.phys_addr = cparams->iv.phys_addr; op->sym->cipher.iv.length = cparams->iv.length; - /* For SNOW3G algorithms, offset/length must be in bits */ - if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2) { + /* For wireless algorithms, offset/length must be in bits */ + if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 || + cparams->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 || + cparams->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3) { op->sym->cipher.data.offset = ipdata_offset << 3; - if (cparams->do_hash && cparams->hash_verify) - /* Do not cipher the hash tag */ - op->sym->cipher.data.length = (data_len - - cparams->digest_length) << 3; - else - op->sym->cipher.data.length = data_len << 3; - + op->sym->cipher.data.length = data_len << 3; } else { op->sym->cipher.data.offset = ipdata_offset; - if (cparams->do_hash && cparams->hash_verify) - /* Do not cipher the hash tag */ - op->sym->cipher.data.length = data_len - - cparams->digest_length; - else - op->sym->cipher.data.length = data_len; + op->sym->cipher.data.length = data_len; } } @@ -553,10 +595,18 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid) static void generate_random_key(uint8_t *key, unsigned length) { - unsigned i; + int fd; + int ret; - for (i = 0; i < length; i++) - key[i] = rand() % 0xff; + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) + rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); + + ret = read(fd, key, length); + close(fd); + + if (ret != (signed)length) + rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); } static struct rte_cryptodev_sym_session * @@ -593,7 +643,7 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) unsigned lcore_id = rte_lcore_id(); uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; - unsigned i, j, portid, nb_rx; + unsigned i, j, portid, nb_rx, len; struct lcore_queue_conf *qconf = &lcore_queue_conf[lcore_id]; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; @@ -607,8 +657,6 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); - l2fwd_crypto_options_print(options); - for (i = 0; i < qconf->nb_rx_ports; i++) { portid = qconf->rx_port_list[i]; @@ -681,15 +729,31 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) port_cparams[i].dev_id); } + l2fwd_crypto_options_print(options); + + /* + * Initialize previous tsc timestamp before the loop, + * to avoid showing the port statistics immediately, + * so user can see the crypto information. + */ + prev_tsc = rte_rdtsc(); while (1) { cur_tsc = rte_rdtsc(); /* - * TX burst queue drain + * Crypto device/TX burst queue drain */ diff_tsc = cur_tsc - prev_tsc; if (unlikely(diff_tsc > drain_tsc)) { + /* Enqueue all crypto ops remaining in buffers */ + for (i = 0; i < qconf->nb_crypto_devs; i++) { + cparams = &port_cparams[i]; + len = qconf->op_buf[cparams->dev_id].len; + l2fwd_crypto_send_burst(qconf, len, cparams); + qconf->op_buf[cparams->dev_id].len = 0; + } + /* Transmit all packets remaining in buffers */ for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { if (qconf->pkt_buf[portid].len == 0) continue; @@ -804,16 +868,16 @@ l2fwd_crypto_usage(const char *prgname) " --cipher_algo ALGO\n" " --cipher_op ENCRYPT / DECRYPT\n" - " --cipher_key KEY\n" + " --cipher_key KEY (bytes separated with \":\")\n" " --cipher_key_random_size SIZE: size of cipher key when generated randomly\n" - " --iv IV\n" + " --iv IV (bytes separated with \":\")\n" " --iv_random_size SIZE: size of IV when generated randomly\n" " --auth_algo ALGO\n" " --auth_op GENERATE / VERIFY\n" - " --auth_key KEY\n" + " --auth_key KEY (bytes separated with \":\")\n" " --auth_key_random_size SIZE: size of auth key when generated randomly\n" - " --aad AAD\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" @@ -864,18 +928,13 @@ parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) static int parse_cipher_algo(enum rte_crypto_cipher_algorithm *algo, char *optarg) { - if (strcmp("AES_CBC", optarg) == 0) { - *algo = RTE_CRYPTO_CIPHER_AES_CBC; - return 0; - } else if (strcmp("AES_GCM", optarg) == 0) { - *algo = RTE_CRYPTO_CIPHER_AES_GCM; - return 0; - } else if (strcmp("NULL", optarg) == 0) { - *algo = RTE_CRYPTO_CIPHER_NULL; - return 0; - } else if (strcmp("SNOW3G_UEA2", optarg) == 0) { - *algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2; - return 0; + unsigned i; + + for (i = 0; i < RTE_CRYPTO_CIPHER_LIST_END; i++) { + if (!strcmp(supported_cipher_algo[i], optarg)) { + *algo = (enum rte_crypto_cipher_algorithm)i; + return 0; + } } printf("Cipher algorithm not supported!\n"); @@ -945,33 +1004,13 @@ parse_size(int *size, const char *q_arg) static int parse_auth_algo(enum rte_crypto_auth_algorithm *algo, char *optarg) { - if (strcmp("AES_GCM", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_AES_GCM; - return 0; - } else if (strcmp("MD5_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_MD5_HMAC; - return 0; - } else if (strcmp("NULL", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_NULL; - return 0; - } else if (strcmp("SHA1_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - return 0; - } else if (strcmp("SHA224_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SHA224_HMAC; - return 0; - } else if (strcmp("SHA256_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SHA256_HMAC; - return 0; - } else if (strcmp("SHA384_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SHA384_HMAC; - return 0; - } else if (strcmp("SHA512_HMAC", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - return 0; - } else if (strcmp("SNOW3G_UIA2", optarg) == 0) { - *algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2; - return 0; + unsigned i; + + for (i = 0; i < RTE_CRYPTO_AUTH_LIST_END; i++) { + if (!strcmp(supported_auth_algo[i], optarg)) { + *algo = (enum rte_crypto_auth_algorithm)i; + return 0; + } } printf("Authentication algorithm specified not supported!\n"); @@ -1003,7 +1042,8 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, if (strcmp(lgopts[option_index].name, "cdev_type") == 0) { retval = parse_cryptodev_type(&options->type, optarg); if (retval == 0) - strcpy(options->string_type, optarg); + snprintf(options->string_type, MAX_STR_LEN, + "%s", optarg); return retval; } @@ -1011,13 +1051,9 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, return parse_crypto_opt_chain(options, optarg); /* Cipher options */ - else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0) { - retval = parse_cipher_algo(&options->cipher_xform.cipher.algo, + else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0) + return parse_cipher_algo(&options->cipher_xform.cipher.algo, optarg); - if (retval == 0) - strcpy(options->string_cipher_algo, optarg); - return retval; - } else if (strcmp(lgopts[option_index].name, "cipher_op") == 0) return parse_cipher_op(&options->cipher_xform.cipher.op, @@ -1051,11 +1087,8 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, /* Authentication options */ else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) { - retval = parse_auth_algo(&options->auth_xform.auth.algo, + return parse_auth_algo(&options->auth_xform.auth.algo, optarg); - if (retval == 0) - strcpy(options->string_auth_algo, optarg); - return retval; } else if (strcmp(lgopts[option_index].name, "auth_op") == 0) @@ -1177,8 +1210,6 @@ l2fwd_crypto_parse_timer_period(struct l2fwd_crypto_options *options, static void l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) { - srand(time(NULL)); - options->portmask = 0xffffffff; options->nb_ports_per_lcore = 1; options->refresh_period = 10000; @@ -1217,9 +1248,46 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) options->type = CDEV_TYPE_ANY; } +static void +display_cipher_info(struct l2fwd_crypto_options *options) +{ + printf("\n---- Cipher information ---\n"); + printf("Algorithm: %s\n", + supported_cipher_algo[options->cipher_xform.cipher.algo]); + rte_hexdump(stdout, "Cipher key:", + options->cipher_xform.cipher.key.data, + options->cipher_xform.cipher.key.length); + rte_hexdump(stdout, "IV:", options->iv.data, options->iv.length); +} + +static void +display_auth_info(struct l2fwd_crypto_options *options) +{ + printf("\n---- Authentication information ---\n"); + printf("Algorithm: %s\n", + supported_auth_algo[options->auth_xform.auth.algo]); + rte_hexdump(stdout, "Auth key:", + options->auth_xform.auth.key.data, + options->auth_xform.auth.key.length); + rte_hexdump(stdout, "AAD:", options->aad.data, options->aad.length); +} + static void l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) { + char string_cipher_op[MAX_STR_LEN]; + char string_auth_op[MAX_STR_LEN]; + + if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + strcpy(string_cipher_op, "Encrypt"); + else + strcpy(string_cipher_op, "Decrypt"); + + if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) + strcpy(string_auth_op, "Auth generate"); + else + strcpy(string_auth_op, "Auth verify"); + printf("Options:-\nn"); printf("portmask: %x\n", options->portmask); printf("ports per lcore: %u\n", options->nb_ports_per_lcore); @@ -1231,6 +1299,42 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) printf("sessionless crypto: %s\n", options->sessionless ? "enabled" : "disabled"); + + if (options->ckey_param && (options->ckey_random_size != -1)) + printf("Cipher key already parsed, ignoring size of random key\n"); + + if (options->akey_param && (options->akey_random_size != -1)) + printf("Auth key already parsed, ignoring size of random key\n"); + + if (options->iv_param && (options->iv_random_size != -1)) + printf("IV already parsed, ignoring size of random IV\n"); + + if (options->aad_param && (options->aad_random_size != -1)) + printf("AAD already parsed, ignoring size of random AAD\n"); + + printf("\nCrypto chain: "); + switch (options->xform_chain) { + case L2FWD_CRYPTO_CIPHER_HASH: + printf("Input --> %s --> %s --> Output\n", + string_cipher_op, string_auth_op); + display_cipher_info(options); + display_auth_info(options); + break; + case L2FWD_CRYPTO_HASH_CIPHER: + printf("Input --> %s --> %s --> Output\n", + string_auth_op, string_cipher_op); + display_cipher_info(options); + display_auth_info(options); + break; + case L2FWD_CRYPTO_HASH_ONLY: + printf("Input --> %s --> Output\n", string_auth_op); + display_auth_info(options); + break; + case L2FWD_CRYPTO_CIPHER_ONLY: + printf("Input --> %s --> Output\n", string_cipher_op); + display_cipher_info(options); + break; + } } /* Parse the argument given in the command line of the application */ @@ -1365,7 +1469,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) continue; } /* clear all_ports_up flag if any link down */ - if (link.link_status == 0) { + if (link.link_status == ETH_LINK_DOWN) { all_ports_up = 0; break; } @@ -1410,6 +1514,15 @@ check_supported_size(uint16_t length, uint16_t min, uint16_t max, { uint16_t supp_size; + /* Single value */ + if (increment == 0) { + if (length == min) + return 0; + else + return -1; + } + + /* Range of values */ for (supp_size = min; supp_size <= max; supp_size += increment) { if (length == supp_size) return 0; @@ -1474,7 +1587,8 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { printf("Algorithm %s not supported by cryptodev %u" " or device not of preferred type (%s)\n", - options->string_cipher_algo, cdev_id, + supported_cipher_algo[opt_cipher_algo], + cdev_id, options->string_type); continue; } @@ -1573,7 +1687,8 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { printf("Algorithm %s not supported by cryptodev %u" " or device not of preferred type (%s)\n", - options->string_auth_algo, cdev_id, + supported_auth_algo[opt_auth_algo], + cdev_id, options->string_type); continue; } @@ -1686,6 +1801,13 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, return -1; } + retval = rte_cryptodev_start(cdev_id); + if (retval < 0) { + printf("Failed to start device %u: error %d\n", + cdev_id, retval); + return -1; + } + l2fwd_enabled_crypto_mask |= (1 << cdev_id); enabled_cdevs[cdev_id] = 1; @@ -1707,9 +1829,6 @@ initialize_ports(struct l2fwd_crypto_options *options) return -1; } - if (nb_ports > RTE_MAX_ETHPORTS) - nb_ports = RTE_MAX_ETHPORTS; - /* Reset l2fwd_dst_ports */ for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) l2fwd_dst_ports[portid] = 0; @@ -1848,6 +1967,9 @@ main(int argc, char **argv) /* reserve memory for Cipher/Auth key and IV */ reserve_key_memory(&options); + /* fill out the supported algorithm tables */ + fill_supported_algorithm_tables(); + /* parse application arguments (after the EAL ones) */ ret = l2fwd_crypto_parse_args(&options, argc, argv); if (ret < 0)