1387259bdSDeclan Doherty /*- 2387259bdSDeclan Doherty * BSD LICENSE 3387259bdSDeclan Doherty * 42c59bd32SSlawomir Mrozowicz * Copyright(c) 2015-2016 Intel Corporation. All rights reserved. 5387259bdSDeclan Doherty * All rights reserved. 6387259bdSDeclan Doherty * 7387259bdSDeclan Doherty * Redistribution and use in source and binary forms, with or without 8387259bdSDeclan Doherty * modification, are permitted provided that the following conditions 9387259bdSDeclan Doherty * are met: 10387259bdSDeclan Doherty * 11387259bdSDeclan Doherty * * Redistributions of source code must retain the above copyright 12387259bdSDeclan Doherty * notice, this list of conditions and the following disclaimer. 13387259bdSDeclan Doherty * * Redistributions in binary form must reproduce the above copyright 14387259bdSDeclan Doherty * notice, this list of conditions and the following disclaimer in 15387259bdSDeclan Doherty * the documentation and/or other materials provided with the 16387259bdSDeclan Doherty * distribution. 17387259bdSDeclan Doherty * * Neither the name of Intel Corporation nor the names of its 18387259bdSDeclan Doherty * contributors may be used to endorse or promote products derived 19387259bdSDeclan Doherty * from this software without specific prior written permission. 20387259bdSDeclan Doherty * 21387259bdSDeclan Doherty * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22387259bdSDeclan Doherty * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23387259bdSDeclan Doherty * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24387259bdSDeclan Doherty * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25387259bdSDeclan Doherty * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26387259bdSDeclan Doherty * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27387259bdSDeclan Doherty * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28387259bdSDeclan Doherty * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29387259bdSDeclan Doherty * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30387259bdSDeclan Doherty * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31387259bdSDeclan Doherty * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32387259bdSDeclan Doherty */ 33387259bdSDeclan Doherty 34387259bdSDeclan Doherty #include <time.h> 35387259bdSDeclan Doherty #include <stdio.h> 36387259bdSDeclan Doherty #include <stdlib.h> 37387259bdSDeclan Doherty #include <string.h> 38387259bdSDeclan Doherty #include <stdint.h> 39387259bdSDeclan Doherty #include <inttypes.h> 40387259bdSDeclan Doherty #include <sys/types.h> 41387259bdSDeclan Doherty #include <sys/queue.h> 42387259bdSDeclan Doherty #include <netinet/in.h> 43387259bdSDeclan Doherty #include <setjmp.h> 44387259bdSDeclan Doherty #include <stdarg.h> 45387259bdSDeclan Doherty #include <ctype.h> 46387259bdSDeclan Doherty #include <errno.h> 47387259bdSDeclan Doherty #include <getopt.h> 486dad6e69SPiotr Azarewicz #include <fcntl.h> 496dad6e69SPiotr Azarewicz #include <unistd.h> 50387259bdSDeclan Doherty 51387259bdSDeclan Doherty #include <rte_atomic.h> 52387259bdSDeclan Doherty #include <rte_branch_prediction.h> 53387259bdSDeclan Doherty #include <rte_common.h> 54387259bdSDeclan Doherty #include <rte_cryptodev.h> 55387259bdSDeclan Doherty #include <rte_cycles.h> 56387259bdSDeclan Doherty #include <rte_debug.h> 57387259bdSDeclan Doherty #include <rte_eal.h> 58387259bdSDeclan Doherty #include <rte_ether.h> 59387259bdSDeclan Doherty #include <rte_ethdev.h> 60387259bdSDeclan Doherty #include <rte_interrupts.h> 61387259bdSDeclan Doherty #include <rte_ip.h> 62387259bdSDeclan Doherty #include <rte_launch.h> 63387259bdSDeclan Doherty #include <rte_lcore.h> 64387259bdSDeclan Doherty #include <rte_log.h> 65387259bdSDeclan Doherty #include <rte_malloc.h> 66387259bdSDeclan Doherty #include <rte_mbuf.h> 67387259bdSDeclan Doherty #include <rte_memcpy.h> 68387259bdSDeclan Doherty #include <rte_memory.h> 69387259bdSDeclan Doherty #include <rte_mempool.h> 70387259bdSDeclan Doherty #include <rte_memzone.h> 71387259bdSDeclan Doherty #include <rte_pci.h> 72387259bdSDeclan Doherty #include <rte_per_lcore.h> 73387259bdSDeclan Doherty #include <rte_prefetch.h> 74387259bdSDeclan Doherty #include <rte_random.h> 7541e97c2eSPablo de Lara #include <rte_hexdump.h> 76387259bdSDeclan Doherty 7727cf2d1bSPablo de Lara enum cdev_type { 7827cf2d1bSPablo de Lara CDEV_TYPE_ANY, 7927cf2d1bSPablo de Lara CDEV_TYPE_HW, 8027cf2d1bSPablo de Lara CDEV_TYPE_SW 8127cf2d1bSPablo de Lara }; 8227cf2d1bSPablo de Lara 83387259bdSDeclan Doherty #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 84387259bdSDeclan Doherty 85387259bdSDeclan Doherty #define NB_MBUF 8192 86387259bdSDeclan Doherty 8727cf2d1bSPablo de Lara #define MAX_STR_LEN 32 881df9c010SPablo de Lara #define MAX_KEY_SIZE 128 89387259bdSDeclan Doherty #define MAX_PKT_BURST 32 90387259bdSDeclan Doherty #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ 912c59bd32SSlawomir Mrozowicz #define MAX_SESSIONS 32 922c59bd32SSlawomir Mrozowicz #define SESSION_POOL_CACHE_SIZE 0 93387259bdSDeclan Doherty 94e636243eSPablo de Lara #define MAXIMUM_IV_LENGTH 16 95e636243eSPablo de Lara #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ 96e636243eSPablo de Lara sizeof(struct rte_crypto_sym_op)) 97e636243eSPablo de Lara 98387259bdSDeclan Doherty /* 99387259bdSDeclan Doherty * Configurable number of RX/TX ring descriptors 100387259bdSDeclan Doherty */ 101387259bdSDeclan Doherty #define RTE_TEST_RX_DESC_DEFAULT 128 102387259bdSDeclan Doherty #define RTE_TEST_TX_DESC_DEFAULT 512 1033c96262cSPablo de Lara 104387259bdSDeclan Doherty static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 105387259bdSDeclan Doherty static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; 106387259bdSDeclan Doherty 107387259bdSDeclan Doherty /* ethernet addresses of ports */ 108387259bdSDeclan Doherty static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; 109387259bdSDeclan Doherty 110387259bdSDeclan Doherty /* mask of enabled ports */ 111387259bdSDeclan Doherty static uint64_t l2fwd_enabled_port_mask; 112387259bdSDeclan Doherty static uint64_t l2fwd_enabled_crypto_mask; 113387259bdSDeclan Doherty 114387259bdSDeclan Doherty /* list of enabled ports */ 115387259bdSDeclan Doherty static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; 116387259bdSDeclan Doherty 117387259bdSDeclan Doherty 118387259bdSDeclan Doherty struct pkt_buffer { 119387259bdSDeclan Doherty unsigned len; 120387259bdSDeclan Doherty struct rte_mbuf *buffer[MAX_PKT_BURST]; 121387259bdSDeclan Doherty }; 122387259bdSDeclan Doherty 123c0f87eb5SDeclan Doherty struct op_buffer { 124c0f87eb5SDeclan Doherty unsigned len; 125c0f87eb5SDeclan Doherty struct rte_crypto_op *buffer[MAX_PKT_BURST]; 126c0f87eb5SDeclan Doherty }; 127c0f87eb5SDeclan Doherty 128387259bdSDeclan Doherty #define MAX_RX_QUEUE_PER_LCORE 16 129387259bdSDeclan Doherty #define MAX_TX_QUEUE_PER_PORT 16 130387259bdSDeclan Doherty 131387259bdSDeclan Doherty enum l2fwd_crypto_xform_chain { 132387259bdSDeclan Doherty L2FWD_CRYPTO_CIPHER_HASH, 1331a75e9f3SPablo de Lara L2FWD_CRYPTO_HASH_CIPHER, 1341a75e9f3SPablo de Lara L2FWD_CRYPTO_CIPHER_ONLY, 1352661f4fbSPablo de Lara L2FWD_CRYPTO_HASH_ONLY, 1362661f4fbSPablo de Lara L2FWD_CRYPTO_AEAD 137387259bdSDeclan Doherty }; 138387259bdSDeclan Doherty 139a7f4562bSFiona Trahe struct l2fwd_key { 140a7f4562bSFiona Trahe uint8_t *data; 141a7f4562bSFiona Trahe uint32_t length; 142a7f4562bSFiona Trahe phys_addr_t phys_addr; 143a7f4562bSFiona Trahe }; 144a7f4562bSFiona Trahe 1450fbd75a9SPablo de Lara struct l2fwd_iv { 1460fbd75a9SPablo de Lara uint8_t *data; 1470fbd75a9SPablo de Lara uint16_t length; 1480fbd75a9SPablo de Lara }; 1490fbd75a9SPablo de Lara 150387259bdSDeclan Doherty /** l2fwd crypto application command line options */ 151387259bdSDeclan Doherty struct l2fwd_crypto_options { 152387259bdSDeclan Doherty unsigned portmask; 153387259bdSDeclan Doherty unsigned nb_ports_per_lcore; 154387259bdSDeclan Doherty unsigned refresh_period; 155387259bdSDeclan Doherty unsigned single_lcore:1; 156387259bdSDeclan Doherty 15727cf2d1bSPablo de Lara enum cdev_type type; 158387259bdSDeclan Doherty unsigned sessionless:1; 159387259bdSDeclan Doherty 160387259bdSDeclan Doherty enum l2fwd_crypto_xform_chain xform_chain; 161387259bdSDeclan Doherty 1621bd407faSFiona Trahe struct rte_crypto_sym_xform cipher_xform; 1631df9c010SPablo de Lara unsigned ckey_param; 164a061e50aSPablo de Lara int ckey_random_size; 165387259bdSDeclan Doherty 166acf86169SPablo de Lara struct l2fwd_iv cipher_iv; 167acf86169SPablo de Lara unsigned int cipher_iv_param; 168acf86169SPablo de Lara int cipher_iv_random_size; 169387259bdSDeclan Doherty 1701bd407faSFiona Trahe struct rte_crypto_sym_xform auth_xform; 1711df9c010SPablo de Lara uint8_t akey_param; 172a061e50aSPablo de Lara int akey_random_size; 173617a7949SPablo de Lara 174acf86169SPablo de Lara struct l2fwd_iv auth_iv; 175acf86169SPablo de Lara unsigned int auth_iv_param; 176acf86169SPablo de Lara int auth_iv_random_size; 177acf86169SPablo de Lara 1782661f4fbSPablo de Lara struct rte_crypto_sym_xform aead_xform; 1792661f4fbSPablo de Lara unsigned int aead_key_param; 1802661f4fbSPablo de Lara int aead_key_random_size; 1812661f4fbSPablo de Lara 1822661f4fbSPablo de Lara struct l2fwd_iv aead_iv; 1832661f4fbSPablo de Lara unsigned int aead_iv_param; 1842661f4fbSPablo de Lara int aead_iv_random_size; 1852661f4fbSPablo de Lara 186617a7949SPablo de Lara struct l2fwd_key aad; 187617a7949SPablo de Lara unsigned aad_param; 188a061e50aSPablo de Lara int aad_random_size; 189a061e50aSPablo de Lara 190a061e50aSPablo de Lara int digest_size; 19127cf2d1bSPablo de Lara 19227cf2d1bSPablo de Lara uint16_t block_size; 19327cf2d1bSPablo de Lara char string_type[MAX_STR_LEN]; 194d2797f51SFan Zhang 195d2797f51SFan Zhang uint64_t cryptodev_mask; 196387259bdSDeclan Doherty }; 197387259bdSDeclan Doherty 198387259bdSDeclan Doherty /** l2fwd crypto lcore params */ 199387259bdSDeclan Doherty struct l2fwd_crypto_params { 200387259bdSDeclan Doherty uint8_t dev_id; 201387259bdSDeclan Doherty uint8_t qp_id; 202387259bdSDeclan Doherty 203387259bdSDeclan Doherty unsigned digest_length; 204387259bdSDeclan Doherty unsigned block_size; 20527cf2d1bSPablo de Lara 206acf86169SPablo de Lara struct l2fwd_iv cipher_iv; 207acf86169SPablo de Lara struct l2fwd_iv auth_iv; 2082661f4fbSPablo de Lara struct l2fwd_iv aead_iv; 209617a7949SPablo de Lara struct l2fwd_key aad; 2101bd407faSFiona Trahe struct rte_cryptodev_sym_session *session; 2111a75e9f3SPablo de Lara 2121a75e9f3SPablo de Lara uint8_t do_cipher; 2131a75e9f3SPablo de Lara uint8_t do_hash; 2142661f4fbSPablo de Lara uint8_t do_aead; 21527cf2d1bSPablo de Lara uint8_t hash_verify; 216d29ea843SPablo de Lara 217d29ea843SPablo de Lara enum rte_crypto_cipher_algorithm cipher_algo; 218d29ea843SPablo de Lara enum rte_crypto_auth_algorithm auth_algo; 2192661f4fbSPablo de Lara enum rte_crypto_aead_algorithm aead_algo; 220387259bdSDeclan Doherty }; 221387259bdSDeclan Doherty 222387259bdSDeclan Doherty /** lcore configuration */ 223387259bdSDeclan Doherty struct lcore_queue_conf { 224387259bdSDeclan Doherty unsigned nb_rx_ports; 225387259bdSDeclan Doherty unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; 226387259bdSDeclan Doherty 227387259bdSDeclan Doherty unsigned nb_crypto_devs; 228387259bdSDeclan Doherty unsigned cryptodev_list[MAX_RX_QUEUE_PER_LCORE]; 229387259bdSDeclan Doherty 230ad476dd3SPablo de Lara struct op_buffer op_buf[RTE_CRYPTO_MAX_DEVS]; 231c0f87eb5SDeclan Doherty struct pkt_buffer pkt_buf[RTE_MAX_ETHPORTS]; 232387259bdSDeclan Doherty } __rte_cache_aligned; 233387259bdSDeclan Doherty 234387259bdSDeclan Doherty struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; 235387259bdSDeclan Doherty 236387259bdSDeclan Doherty static const struct rte_eth_conf port_conf = { 237387259bdSDeclan Doherty .rxmode = { 2381df9c010SPablo de Lara .mq_mode = ETH_MQ_RX_NONE, 2391df9c010SPablo de Lara .max_rx_pkt_len = ETHER_MAX_LEN, 240387259bdSDeclan Doherty .split_hdr_size = 0, 241387259bdSDeclan Doherty .header_split = 0, /**< Header Split disabled */ 242387259bdSDeclan Doherty .hw_ip_checksum = 0, /**< IP checksum offload disabled */ 243387259bdSDeclan Doherty .hw_vlan_filter = 0, /**< VLAN filtering disabled */ 244387259bdSDeclan Doherty .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ 24560da774eSJeff Guo .hw_strip_crc = 1, /**< CRC stripped by hardware */ 246387259bdSDeclan Doherty }, 247387259bdSDeclan Doherty .txmode = { 248387259bdSDeclan Doherty .mq_mode = ETH_MQ_TX_NONE, 249387259bdSDeclan Doherty }, 250387259bdSDeclan Doherty }; 251387259bdSDeclan Doherty 252387259bdSDeclan Doherty struct rte_mempool *l2fwd_pktmbuf_pool; 253c0f87eb5SDeclan Doherty struct rte_mempool *l2fwd_crypto_op_pool; 2542c59bd32SSlawomir Mrozowicz struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 }; 255387259bdSDeclan Doherty 256387259bdSDeclan Doherty /* Per-port statistics struct */ 257387259bdSDeclan Doherty struct l2fwd_port_statistics { 258387259bdSDeclan Doherty uint64_t tx; 259387259bdSDeclan Doherty uint64_t rx; 260387259bdSDeclan Doherty 261387259bdSDeclan Doherty uint64_t crypto_enqueued; 262387259bdSDeclan Doherty uint64_t crypto_dequeued; 263387259bdSDeclan Doherty 264387259bdSDeclan Doherty uint64_t dropped; 265387259bdSDeclan Doherty } __rte_cache_aligned; 266387259bdSDeclan Doherty 267387259bdSDeclan Doherty struct l2fwd_crypto_statistics { 268387259bdSDeclan Doherty uint64_t enqueued; 269387259bdSDeclan Doherty uint64_t dequeued; 270387259bdSDeclan Doherty 271387259bdSDeclan Doherty uint64_t errors; 272387259bdSDeclan Doherty } __rte_cache_aligned; 273387259bdSDeclan Doherty 274387259bdSDeclan Doherty struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; 275572f0779SSlawomir Mrozowicz struct l2fwd_crypto_statistics crypto_statistics[RTE_CRYPTO_MAX_DEVS]; 276387259bdSDeclan Doherty 277387259bdSDeclan Doherty /* A tsc-based timer responsible for triggering statistics printout */ 278387259bdSDeclan Doherty #define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ 2793c96262cSPablo de Lara #define MAX_TIMER_PERIOD 86400UL /* 1 day max */ 280387259bdSDeclan Doherty 281387259bdSDeclan Doherty /* default period is 10 seconds */ 282387259bdSDeclan Doherty static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; 283387259bdSDeclan Doherty 284387259bdSDeclan Doherty /* Print out statistics on packets dropped */ 285387259bdSDeclan Doherty static void 286387259bdSDeclan Doherty print_stats(void) 287387259bdSDeclan Doherty { 28828523d9aSPablo de Lara uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; 28928523d9aSPablo de Lara uint64_t total_packets_enqueued, total_packets_dequeued, 29028523d9aSPablo de Lara total_packets_errors; 291387259bdSDeclan Doherty unsigned portid; 292387259bdSDeclan Doherty uint64_t cdevid; 293387259bdSDeclan Doherty 29428523d9aSPablo de Lara total_packets_dropped = 0; 29528523d9aSPablo de Lara total_packets_tx = 0; 29628523d9aSPablo de Lara total_packets_rx = 0; 29728523d9aSPablo de Lara total_packets_enqueued = 0; 29828523d9aSPablo de Lara total_packets_dequeued = 0; 29928523d9aSPablo de Lara total_packets_errors = 0; 300387259bdSDeclan Doherty 301387259bdSDeclan Doherty const char clr[] = { 27, '[', '2', 'J', '\0' }; 302387259bdSDeclan Doherty const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 303387259bdSDeclan Doherty 304387259bdSDeclan Doherty /* Clear screen and move to top left */ 305387259bdSDeclan Doherty printf("%s%s", clr, topLeft); 306387259bdSDeclan Doherty 307387259bdSDeclan Doherty printf("\nPort statistics ===================================="); 308387259bdSDeclan Doherty 309387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 310387259bdSDeclan Doherty /* skip disabled ports */ 311387259bdSDeclan Doherty if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) 312387259bdSDeclan Doherty continue; 313387259bdSDeclan Doherty printf("\nStatistics for port %u ------------------------------" 314387259bdSDeclan Doherty "\nPackets sent: %32"PRIu64 315387259bdSDeclan Doherty "\nPackets received: %28"PRIu64 316387259bdSDeclan Doherty "\nPackets dropped: %29"PRIu64, 317387259bdSDeclan Doherty portid, 318387259bdSDeclan Doherty port_statistics[portid].tx, 319387259bdSDeclan Doherty port_statistics[portid].rx, 320387259bdSDeclan Doherty port_statistics[portid].dropped); 321387259bdSDeclan Doherty 322387259bdSDeclan Doherty total_packets_dropped += port_statistics[portid].dropped; 323387259bdSDeclan Doherty total_packets_tx += port_statistics[portid].tx; 324387259bdSDeclan Doherty total_packets_rx += port_statistics[portid].rx; 325387259bdSDeclan Doherty } 326387259bdSDeclan Doherty printf("\nCrypto statistics =================================="); 327387259bdSDeclan Doherty 328387259bdSDeclan Doherty for (cdevid = 0; cdevid < RTE_CRYPTO_MAX_DEVS; cdevid++) { 329387259bdSDeclan Doherty /* skip disabled ports */ 330ad476dd3SPablo de Lara if ((l2fwd_enabled_crypto_mask & (((uint64_t)1) << cdevid)) == 0) 331387259bdSDeclan Doherty continue; 332387259bdSDeclan Doherty printf("\nStatistics for cryptodev %"PRIu64 333387259bdSDeclan Doherty " -------------------------" 334387259bdSDeclan Doherty "\nPackets enqueued: %28"PRIu64 335387259bdSDeclan Doherty "\nPackets dequeued: %28"PRIu64 336387259bdSDeclan Doherty "\nPackets errors: %30"PRIu64, 337387259bdSDeclan Doherty cdevid, 338387259bdSDeclan Doherty crypto_statistics[cdevid].enqueued, 339387259bdSDeclan Doherty crypto_statistics[cdevid].dequeued, 340387259bdSDeclan Doherty crypto_statistics[cdevid].errors); 341387259bdSDeclan Doherty 342387259bdSDeclan Doherty total_packets_enqueued += crypto_statistics[cdevid].enqueued; 343387259bdSDeclan Doherty total_packets_dequeued += crypto_statistics[cdevid].dequeued; 344387259bdSDeclan Doherty total_packets_errors += crypto_statistics[cdevid].errors; 345387259bdSDeclan Doherty } 346387259bdSDeclan Doherty printf("\nAggregate statistics ===============================" 347387259bdSDeclan Doherty "\nTotal packets received: %22"PRIu64 348387259bdSDeclan Doherty "\nTotal packets enqueued: %22"PRIu64 349387259bdSDeclan Doherty "\nTotal packets dequeued: %22"PRIu64 350387259bdSDeclan Doherty "\nTotal packets sent: %26"PRIu64 351387259bdSDeclan Doherty "\nTotal packets dropped: %23"PRIu64 352387259bdSDeclan Doherty "\nTotal packets crypto errors: %17"PRIu64, 353387259bdSDeclan Doherty total_packets_rx, 354387259bdSDeclan Doherty total_packets_enqueued, 355387259bdSDeclan Doherty total_packets_dequeued, 356387259bdSDeclan Doherty total_packets_tx, 357387259bdSDeclan Doherty total_packets_dropped, 358387259bdSDeclan Doherty total_packets_errors); 359387259bdSDeclan Doherty printf("\n====================================================\n"); 360387259bdSDeclan Doherty } 361387259bdSDeclan Doherty 362387259bdSDeclan Doherty static int 363387259bdSDeclan Doherty l2fwd_crypto_send_burst(struct lcore_queue_conf *qconf, unsigned n, 364387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams) 365387259bdSDeclan Doherty { 366c0f87eb5SDeclan Doherty struct rte_crypto_op **op_buffer; 367387259bdSDeclan Doherty unsigned ret; 368387259bdSDeclan Doherty 369c0f87eb5SDeclan Doherty op_buffer = (struct rte_crypto_op **) 370c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].buffer; 371387259bdSDeclan Doherty 372c0f87eb5SDeclan Doherty ret = rte_cryptodev_enqueue_burst(cparams->dev_id, 373c0f87eb5SDeclan Doherty cparams->qp_id, op_buffer, (uint16_t) n); 374c0f87eb5SDeclan Doherty 375387259bdSDeclan Doherty crypto_statistics[cparams->dev_id].enqueued += ret; 376387259bdSDeclan Doherty if (unlikely(ret < n)) { 377387259bdSDeclan Doherty crypto_statistics[cparams->dev_id].errors += (n - ret); 378387259bdSDeclan Doherty do { 379c0f87eb5SDeclan Doherty rte_pktmbuf_free(op_buffer[ret]->sym->m_src); 380c0f87eb5SDeclan Doherty rte_crypto_op_free(op_buffer[ret]); 381387259bdSDeclan Doherty } while (++ret < n); 382387259bdSDeclan Doherty } 383387259bdSDeclan Doherty 384387259bdSDeclan Doherty return 0; 385387259bdSDeclan Doherty } 386387259bdSDeclan Doherty 387387259bdSDeclan Doherty static int 388c0f87eb5SDeclan Doherty l2fwd_crypto_enqueue(struct rte_crypto_op *op, 389c0f87eb5SDeclan Doherty struct l2fwd_crypto_params *cparams) 390387259bdSDeclan Doherty { 391387259bdSDeclan Doherty unsigned lcore_id, len; 392387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 393387259bdSDeclan Doherty 394387259bdSDeclan Doherty lcore_id = rte_lcore_id(); 395387259bdSDeclan Doherty 396387259bdSDeclan Doherty qconf = &lcore_queue_conf[lcore_id]; 397c0f87eb5SDeclan Doherty len = qconf->op_buf[cparams->dev_id].len; 398c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].buffer[len] = op; 399387259bdSDeclan Doherty len++; 400387259bdSDeclan Doherty 401c0f87eb5SDeclan Doherty /* enough ops to be sent */ 402387259bdSDeclan Doherty if (len == MAX_PKT_BURST) { 403387259bdSDeclan Doherty l2fwd_crypto_send_burst(qconf, MAX_PKT_BURST, cparams); 404387259bdSDeclan Doherty len = 0; 405387259bdSDeclan Doherty } 406387259bdSDeclan Doherty 407c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].len = len; 408387259bdSDeclan Doherty return 0; 409387259bdSDeclan Doherty } 410387259bdSDeclan Doherty 411387259bdSDeclan Doherty static int 412387259bdSDeclan Doherty l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, 413c0f87eb5SDeclan Doherty struct rte_crypto_op *op, 414387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams) 415387259bdSDeclan Doherty { 416387259bdSDeclan Doherty struct ether_hdr *eth_hdr; 417387259bdSDeclan Doherty struct ipv4_hdr *ip_hdr; 418387259bdSDeclan Doherty 4195839fd20SPablo de Lara uint32_t ipdata_offset, data_len; 4205839fd20SPablo de Lara uint32_t pad_len = 0; 421387259bdSDeclan Doherty char *padding; 422387259bdSDeclan Doherty 423387259bdSDeclan Doherty eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); 424387259bdSDeclan Doherty 425387259bdSDeclan Doherty if (eth_hdr->ether_type != rte_cpu_to_be_16(ETHER_TYPE_IPv4)) 426387259bdSDeclan Doherty return -1; 427387259bdSDeclan Doherty 428387259bdSDeclan Doherty ipdata_offset = sizeof(struct ether_hdr); 429387259bdSDeclan Doherty 430387259bdSDeclan Doherty ip_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, char *) + 431387259bdSDeclan Doherty ipdata_offset); 432387259bdSDeclan Doherty 433387259bdSDeclan Doherty ipdata_offset += (ip_hdr->version_ihl & IPV4_HDR_IHL_MASK) 434387259bdSDeclan Doherty * IPV4_IHL_MULTIPLIER; 435387259bdSDeclan Doherty 436387259bdSDeclan Doherty 437387259bdSDeclan Doherty /* Zero pad data to be crypto'd so it is block aligned */ 438387259bdSDeclan Doherty data_len = rte_pktmbuf_data_len(m) - ipdata_offset; 439893fbab0SPiotr Azarewicz 440893fbab0SPiotr Azarewicz if (cparams->do_hash && cparams->hash_verify) 441893fbab0SPiotr Azarewicz data_len -= cparams->digest_length; 442893fbab0SPiotr Azarewicz 4435839fd20SPablo de Lara if (cparams->do_cipher) { 4445839fd20SPablo de Lara /* 4455839fd20SPablo de Lara * Following algorithms are block cipher algorithms, 4465839fd20SPablo de Lara * and might need padding 4475839fd20SPablo de Lara */ 4485839fd20SPablo de Lara switch (cparams->cipher_algo) { 4495839fd20SPablo de Lara case RTE_CRYPTO_CIPHER_AES_CBC: 4505839fd20SPablo de Lara case RTE_CRYPTO_CIPHER_AES_ECB: 4515839fd20SPablo de Lara case RTE_CRYPTO_CIPHER_DES_CBC: 4525839fd20SPablo de Lara case RTE_CRYPTO_CIPHER_3DES_CBC: 4535839fd20SPablo de Lara case RTE_CRYPTO_CIPHER_3DES_ECB: 4545839fd20SPablo de Lara if (data_len % cparams->block_size) 4555839fd20SPablo de Lara pad_len = cparams->block_size - 4565839fd20SPablo de Lara (data_len % cparams->block_size); 4575839fd20SPablo de Lara break; 4585839fd20SPablo de Lara default: 4595839fd20SPablo de Lara pad_len = 0; 4605839fd20SPablo de Lara } 461387259bdSDeclan Doherty 462387259bdSDeclan Doherty if (pad_len) { 463387259bdSDeclan Doherty padding = rte_pktmbuf_append(m, pad_len); 464387259bdSDeclan Doherty if (unlikely(!padding)) 465387259bdSDeclan Doherty return -1; 466387259bdSDeclan Doherty 467387259bdSDeclan Doherty data_len += pad_len; 468387259bdSDeclan Doherty memset(padding, 0, pad_len); 469387259bdSDeclan Doherty } 4705839fd20SPablo de Lara } 471387259bdSDeclan Doherty 472387259bdSDeclan Doherty /* Set crypto operation data parameters */ 473c0f87eb5SDeclan Doherty rte_crypto_op_attach_sym_session(op, cparams->session); 474387259bdSDeclan Doherty 4751a75e9f3SPablo de Lara if (cparams->do_hash) { 476acf86169SPablo de Lara if (cparams->auth_iv.length) { 477acf86169SPablo de Lara uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, 478acf86169SPablo de Lara uint8_t *, 479acf86169SPablo de Lara IV_OFFSET + 480acf86169SPablo de Lara cparams->cipher_iv.length); 481acf86169SPablo de Lara /* 482acf86169SPablo de Lara * Copy IV at the end of the crypto operation, 483acf86169SPablo de Lara * after the cipher IV, if added 484acf86169SPablo de Lara */ 485acf86169SPablo de Lara rte_memcpy(iv_ptr, cparams->auth_iv.data, 486acf86169SPablo de Lara cparams->auth_iv.length); 487acf86169SPablo de Lara } 48827cf2d1bSPablo de Lara if (!cparams->hash_verify) { 489387259bdSDeclan Doherty /* Append space for digest to end of packet */ 490c0f87eb5SDeclan Doherty op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, 491387259bdSDeclan Doherty cparams->digest_length); 49227cf2d1bSPablo de Lara } else { 493893fbab0SPiotr Azarewicz op->sym->auth.digest.data = rte_pktmbuf_mtod(m, 494893fbab0SPiotr Azarewicz uint8_t *) + ipdata_offset + data_len; 49527cf2d1bSPablo de Lara } 49627cf2d1bSPablo de Lara 497c0f87eb5SDeclan Doherty op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, 498387259bdSDeclan Doherty rte_pktmbuf_pkt_len(m) - cparams->digest_length); 499387259bdSDeclan Doherty 5001f393d82SPablo de Lara /* For wireless algorithms, offset/length must be in bits */ 5012773c86dSPablo de Lara if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 || 5021f393d82SPablo de Lara cparams->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 || 5031f393d82SPablo de Lara cparams->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3) { 504d29ea843SPablo de Lara op->sym->auth.data.offset = ipdata_offset << 3; 505d29ea843SPablo de Lara op->sym->auth.data.length = data_len << 3; 506d29ea843SPablo de Lara } else { 507c0f87eb5SDeclan Doherty op->sym->auth.data.offset = ipdata_offset; 508c0f87eb5SDeclan Doherty op->sym->auth.data.length = data_len; 509d29ea843SPablo de Lara } 5101a75e9f3SPablo de Lara } 5111a75e9f3SPablo de Lara 5121a75e9f3SPablo de Lara if (cparams->do_cipher) { 513e636243eSPablo de Lara uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 514e636243eSPablo de Lara IV_OFFSET); 515e636243eSPablo de Lara /* Copy IV at the end of the crypto operation */ 516acf86169SPablo de Lara rte_memcpy(iv_ptr, cparams->cipher_iv.data, 517acf86169SPablo de Lara cparams->cipher_iv.length); 518e636243eSPablo de Lara 5191f393d82SPablo de Lara /* For wireless algorithms, offset/length must be in bits */ 5202773c86dSPablo de Lara if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 || 5211f393d82SPablo de Lara cparams->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 || 5221f393d82SPablo de Lara cparams->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3) { 523d29ea843SPablo de Lara op->sym->cipher.data.offset = ipdata_offset << 3; 524d29ea843SPablo de Lara op->sym->cipher.data.length = data_len << 3; 525d29ea843SPablo de Lara } else { 526c0f87eb5SDeclan Doherty op->sym->cipher.data.offset = ipdata_offset; 527c0f87eb5SDeclan Doherty op->sym->cipher.data.length = data_len; 5281a75e9f3SPablo de Lara } 529d29ea843SPablo de Lara } 530387259bdSDeclan Doherty 5312661f4fbSPablo de Lara if (cparams->do_aead) { 5322661f4fbSPablo de Lara uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 5332661f4fbSPablo de Lara IV_OFFSET); 5342661f4fbSPablo de Lara /* Copy IV at the end of the crypto operation */ 5352661f4fbSPablo de Lara rte_memcpy(iv_ptr, cparams->aead_iv.data, cparams->aead_iv.length); 5362661f4fbSPablo de Lara 5372661f4fbSPablo de Lara op->sym->aead.data.offset = ipdata_offset; 5382661f4fbSPablo de Lara op->sym->aead.data.length = data_len; 5392661f4fbSPablo de Lara 5402661f4fbSPablo de Lara if (!cparams->hash_verify) { 5412661f4fbSPablo de Lara /* Append space for digest to end of packet */ 5422661f4fbSPablo de Lara op->sym->aead.digest.data = (uint8_t *)rte_pktmbuf_append(m, 5432661f4fbSPablo de Lara cparams->digest_length); 5442661f4fbSPablo de Lara } else { 5452661f4fbSPablo de Lara op->sym->aead.digest.data = rte_pktmbuf_mtod(m, 5462661f4fbSPablo de Lara uint8_t *) + ipdata_offset + data_len; 5472661f4fbSPablo de Lara } 5482661f4fbSPablo de Lara 5492661f4fbSPablo de Lara op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, 5502661f4fbSPablo de Lara rte_pktmbuf_pkt_len(m) - cparams->digest_length); 5512661f4fbSPablo de Lara 5522661f4fbSPablo de Lara if (cparams->aad.length) { 5532661f4fbSPablo de Lara op->sym->aead.aad.data = cparams->aad.data; 5542661f4fbSPablo de Lara op->sym->aead.aad.phys_addr = cparams->aad.phys_addr; 5552661f4fbSPablo de Lara } 5562661f4fbSPablo de Lara } 5572661f4fbSPablo de Lara 558c0f87eb5SDeclan Doherty op->sym->m_src = m; 559c0f87eb5SDeclan Doherty 560c0f87eb5SDeclan Doherty return l2fwd_crypto_enqueue(op, cparams); 561387259bdSDeclan Doherty } 562387259bdSDeclan Doherty 563387259bdSDeclan Doherty 564387259bdSDeclan Doherty /* Send the burst of packets on an output interface */ 565387259bdSDeclan Doherty static int 566c0f87eb5SDeclan Doherty l2fwd_send_burst(struct lcore_queue_conf *qconf, unsigned n, 567c0f87eb5SDeclan Doherty uint8_t port) 568387259bdSDeclan Doherty { 569387259bdSDeclan Doherty struct rte_mbuf **pkt_buffer; 570387259bdSDeclan Doherty unsigned ret; 571387259bdSDeclan Doherty 572c0f87eb5SDeclan Doherty pkt_buffer = (struct rte_mbuf **)qconf->pkt_buf[port].buffer; 573387259bdSDeclan Doherty 574c0f87eb5SDeclan Doherty ret = rte_eth_tx_burst(port, 0, pkt_buffer, (uint16_t)n); 575387259bdSDeclan Doherty port_statistics[port].tx += ret; 576387259bdSDeclan Doherty if (unlikely(ret < n)) { 577387259bdSDeclan Doherty port_statistics[port].dropped += (n - ret); 578387259bdSDeclan Doherty do { 579387259bdSDeclan Doherty rte_pktmbuf_free(pkt_buffer[ret]); 580387259bdSDeclan Doherty } while (++ret < n); 581387259bdSDeclan Doherty } 582387259bdSDeclan Doherty 583387259bdSDeclan Doherty return 0; 584387259bdSDeclan Doherty } 585387259bdSDeclan Doherty 586387259bdSDeclan Doherty /* Enqueue packets for TX and prepare them to be sent */ 587387259bdSDeclan Doherty static int 588387259bdSDeclan Doherty l2fwd_send_packet(struct rte_mbuf *m, uint8_t port) 589387259bdSDeclan Doherty { 590387259bdSDeclan Doherty unsigned lcore_id, len; 591387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 592387259bdSDeclan Doherty 593387259bdSDeclan Doherty lcore_id = rte_lcore_id(); 594387259bdSDeclan Doherty 595387259bdSDeclan Doherty qconf = &lcore_queue_conf[lcore_id]; 596c0f87eb5SDeclan Doherty len = qconf->pkt_buf[port].len; 597c0f87eb5SDeclan Doherty qconf->pkt_buf[port].buffer[len] = m; 598387259bdSDeclan Doherty len++; 599387259bdSDeclan Doherty 600387259bdSDeclan Doherty /* enough pkts to be sent */ 601387259bdSDeclan Doherty if (unlikely(len == MAX_PKT_BURST)) { 602387259bdSDeclan Doherty l2fwd_send_burst(qconf, MAX_PKT_BURST, port); 603387259bdSDeclan Doherty len = 0; 604387259bdSDeclan Doherty } 605387259bdSDeclan Doherty 606c0f87eb5SDeclan Doherty qconf->pkt_buf[port].len = len; 607387259bdSDeclan Doherty return 0; 608387259bdSDeclan Doherty } 609387259bdSDeclan Doherty 610387259bdSDeclan Doherty static void 611387259bdSDeclan Doherty l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid) 612387259bdSDeclan Doherty { 613387259bdSDeclan Doherty struct ether_hdr *eth; 614387259bdSDeclan Doherty void *tmp; 615387259bdSDeclan Doherty unsigned dst_port; 616387259bdSDeclan Doherty 617387259bdSDeclan Doherty dst_port = l2fwd_dst_ports[portid]; 618387259bdSDeclan Doherty eth = rte_pktmbuf_mtod(m, struct ether_hdr *); 619387259bdSDeclan Doherty 620387259bdSDeclan Doherty /* 02:00:00:00:00:xx */ 621387259bdSDeclan Doherty tmp = ð->d_addr.addr_bytes[0]; 622387259bdSDeclan Doherty *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40); 623387259bdSDeclan Doherty 624387259bdSDeclan Doherty /* src addr */ 625387259bdSDeclan Doherty ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], ð->s_addr); 626387259bdSDeclan Doherty 627387259bdSDeclan Doherty l2fwd_send_packet(m, (uint8_t) dst_port); 628387259bdSDeclan Doherty } 629387259bdSDeclan Doherty 630387259bdSDeclan Doherty /** Generate random key */ 631387259bdSDeclan Doherty static void 632387259bdSDeclan Doherty generate_random_key(uint8_t *key, unsigned length) 633387259bdSDeclan Doherty { 6346dad6e69SPiotr Azarewicz int fd; 6356dad6e69SPiotr Azarewicz int ret; 636387259bdSDeclan Doherty 6376dad6e69SPiotr Azarewicz fd = open("/dev/urandom", O_RDONLY); 6386dad6e69SPiotr Azarewicz if (fd < 0) 6396dad6e69SPiotr Azarewicz rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); 6406dad6e69SPiotr Azarewicz 6416dad6e69SPiotr Azarewicz ret = read(fd, key, length); 6426dad6e69SPiotr Azarewicz close(fd); 6436dad6e69SPiotr Azarewicz 6446dad6e69SPiotr Azarewicz if (ret != (signed)length) 6456dad6e69SPiotr Azarewicz rte_exit(EXIT_FAILURE, "Failed to generate random key\n"); 646387259bdSDeclan Doherty } 647387259bdSDeclan Doherty 6481bd407faSFiona Trahe static struct rte_cryptodev_sym_session * 6492c59bd32SSlawomir Mrozowicz initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id) 650387259bdSDeclan Doherty { 6511bd407faSFiona Trahe struct rte_crypto_sym_xform *first_xform; 652*b3bbd9e5SSlawomir Mrozowicz struct rte_cryptodev_sym_session *session; 653*b3bbd9e5SSlawomir Mrozowicz uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); 654*b3bbd9e5SSlawomir Mrozowicz struct rte_mempool *sess_mp = session_pool_socket[socket_id]; 655387259bdSDeclan Doherty 6562661f4fbSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 6572661f4fbSPablo de Lara first_xform = &options->aead_xform; 6582661f4fbSPablo de Lara } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { 659387259bdSDeclan Doherty first_xform = &options->cipher_xform; 660387259bdSDeclan Doherty first_xform->next = &options->auth_xform; 6611a75e9f3SPablo de Lara } else if (options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER) { 662387259bdSDeclan Doherty first_xform = &options->auth_xform; 663387259bdSDeclan Doherty first_xform->next = &options->cipher_xform; 6641a75e9f3SPablo de Lara } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 6651a75e9f3SPablo de Lara first_xform = &options->cipher_xform; 6661a75e9f3SPablo de Lara } else { 6671a75e9f3SPablo de Lara first_xform = &options->auth_xform; 668387259bdSDeclan Doherty } 669387259bdSDeclan Doherty 670*b3bbd9e5SSlawomir Mrozowicz session = rte_cryptodev_sym_session_create(sess_mp); 671*b3bbd9e5SSlawomir Mrozowicz 672*b3bbd9e5SSlawomir Mrozowicz if (session == NULL) 673*b3bbd9e5SSlawomir Mrozowicz return NULL; 674*b3bbd9e5SSlawomir Mrozowicz 675*b3bbd9e5SSlawomir Mrozowicz if (rte_cryptodev_sym_session_init(cdev_id, session, 676*b3bbd9e5SSlawomir Mrozowicz first_xform, sess_mp) < 0) 677*b3bbd9e5SSlawomir Mrozowicz return NULL; 678*b3bbd9e5SSlawomir Mrozowicz 679*b3bbd9e5SSlawomir Mrozowicz return session; 680387259bdSDeclan Doherty } 681387259bdSDeclan Doherty 682387259bdSDeclan Doherty static void 683387259bdSDeclan Doherty l2fwd_crypto_options_print(struct l2fwd_crypto_options *options); 684387259bdSDeclan Doherty 685387259bdSDeclan Doherty /* main processing loop */ 686387259bdSDeclan Doherty static void 687387259bdSDeclan Doherty l2fwd_main_loop(struct l2fwd_crypto_options *options) 688387259bdSDeclan Doherty { 689387259bdSDeclan Doherty struct rte_mbuf *m, *pkts_burst[MAX_PKT_BURST]; 690c0f87eb5SDeclan Doherty struct rte_crypto_op *ops_burst[MAX_PKT_BURST]; 691c0f87eb5SDeclan Doherty 692387259bdSDeclan Doherty unsigned lcore_id = rte_lcore_id(); 693387259bdSDeclan Doherty uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 694268ca735SPablo de Lara unsigned i, j, portid, nb_rx, len; 695387259bdSDeclan Doherty struct lcore_queue_conf *qconf = &lcore_queue_conf[lcore_id]; 696387259bdSDeclan Doherty const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / 697387259bdSDeclan Doherty US_PER_S * BURST_TX_DRAIN_US; 698387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams; 699387259bdSDeclan Doherty struct l2fwd_crypto_params port_cparams[qconf->nb_crypto_devs]; 7002c59bd32SSlawomir Mrozowicz struct rte_cryptodev_sym_session *session; 701387259bdSDeclan Doherty 702387259bdSDeclan Doherty if (qconf->nb_rx_ports == 0) { 703387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); 704387259bdSDeclan Doherty return; 705387259bdSDeclan Doherty } 706387259bdSDeclan Doherty 707387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); 708387259bdSDeclan Doherty 709387259bdSDeclan Doherty for (i = 0; i < qconf->nb_rx_ports; i++) { 710387259bdSDeclan Doherty 711387259bdSDeclan Doherty portid = qconf->rx_port_list[i]; 712387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, 713387259bdSDeclan Doherty portid); 714387259bdSDeclan Doherty } 715387259bdSDeclan Doherty 716387259bdSDeclan Doherty for (i = 0; i < qconf->nb_crypto_devs; i++) { 7171a75e9f3SPablo de Lara port_cparams[i].do_cipher = 0; 7181a75e9f3SPablo de Lara port_cparams[i].do_hash = 0; 7192661f4fbSPablo de Lara port_cparams[i].do_aead = 0; 7201a75e9f3SPablo de Lara 7211a75e9f3SPablo de Lara switch (options->xform_chain) { 7222661f4fbSPablo de Lara case L2FWD_CRYPTO_AEAD: 7232661f4fbSPablo de Lara port_cparams[i].do_aead = 1; 7242661f4fbSPablo de Lara break; 7251a75e9f3SPablo de Lara case L2FWD_CRYPTO_CIPHER_HASH: 7261a75e9f3SPablo de Lara case L2FWD_CRYPTO_HASH_CIPHER: 7271a75e9f3SPablo de Lara port_cparams[i].do_cipher = 1; 7281a75e9f3SPablo de Lara port_cparams[i].do_hash = 1; 7291a75e9f3SPablo de Lara break; 7301a75e9f3SPablo de Lara case L2FWD_CRYPTO_HASH_ONLY: 7311a75e9f3SPablo de Lara port_cparams[i].do_hash = 1; 7321a75e9f3SPablo de Lara break; 7331a75e9f3SPablo de Lara case L2FWD_CRYPTO_CIPHER_ONLY: 7341a75e9f3SPablo de Lara port_cparams[i].do_cipher = 1; 7351a75e9f3SPablo de Lara break; 7361a75e9f3SPablo de Lara } 7371a75e9f3SPablo de Lara 738387259bdSDeclan Doherty port_cparams[i].dev_id = qconf->cryptodev_list[i]; 739387259bdSDeclan Doherty port_cparams[i].qp_id = 0; 740387259bdSDeclan Doherty 74127cf2d1bSPablo de Lara port_cparams[i].block_size = options->block_size; 742387259bdSDeclan Doherty 7431a75e9f3SPablo de Lara if (port_cparams[i].do_hash) { 744acf86169SPablo de Lara port_cparams[i].auth_iv.data = options->auth_iv.data; 745acf86169SPablo de Lara port_cparams[i].auth_iv.length = options->auth_iv.length; 746acf86169SPablo de Lara if (!options->auth_iv_param) 747acf86169SPablo de Lara generate_random_key(port_cparams[i].auth_iv.data, 748acf86169SPablo de Lara port_cparams[i].auth_iv.length); 7492661f4fbSPablo de Lara if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) 7502661f4fbSPablo de Lara port_cparams[i].hash_verify = 1; 7512661f4fbSPablo de Lara else 7522661f4fbSPablo de Lara port_cparams[i].hash_verify = 0; 7532661f4fbSPablo de Lara 7542661f4fbSPablo de Lara port_cparams[i].auth_algo = options->auth_xform.auth.algo; 755acf86169SPablo de Lara /* Set IV parameters */ 756acf86169SPablo de Lara if (options->auth_iv.length) { 757acf86169SPablo de Lara options->auth_xform.auth.iv.offset = 758acf86169SPablo de Lara IV_OFFSET + options->cipher_iv.length; 759acf86169SPablo de Lara options->auth_xform.auth.iv.length = 760acf86169SPablo de Lara options->auth_iv.length; 761acf86169SPablo de Lara } 7622661f4fbSPablo de Lara } 7632661f4fbSPablo de Lara 7642661f4fbSPablo de Lara if (port_cparams[i].do_aead) { 7652661f4fbSPablo de Lara port_cparams[i].aead_algo = options->aead_xform.aead.algo; 76627cf2d1bSPablo de Lara port_cparams[i].digest_length = 7672661f4fbSPablo de Lara options->aead_xform.aead.digest_length; 7682661f4fbSPablo de Lara if (options->aead_xform.aead.add_auth_data_length) { 76927cf2d1bSPablo de Lara port_cparams[i].aad.data = options->aad.data; 770617a7949SPablo de Lara port_cparams[i].aad.phys_addr = options->aad.phys_addr; 7712661f4fbSPablo de Lara port_cparams[i].aad.length = options->aad.length; 772617a7949SPablo de Lara if (!options->aad_param) 77327cf2d1bSPablo de Lara generate_random_key(port_cparams[i].aad.data, 774a158899aSPablo de Lara port_cparams[i].aad.length); 77527cf2d1bSPablo de Lara 77618f421f6SPablo de Lara } else 77718f421f6SPablo de Lara port_cparams[i].aad.length = 0; 77827cf2d1bSPablo de Lara 7792661f4fbSPablo de Lara if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) 78027cf2d1bSPablo de Lara port_cparams[i].hash_verify = 1; 78127cf2d1bSPablo de Lara else 78227cf2d1bSPablo de Lara port_cparams[i].hash_verify = 0; 783d29ea843SPablo de Lara 7842661f4fbSPablo de Lara /* Set IV parameters */ 7852661f4fbSPablo de Lara options->aead_xform.aead.iv.offset = IV_OFFSET; 7862661f4fbSPablo de Lara options->aead_xform.aead.iv.length = options->aead_iv.length; 7871a75e9f3SPablo de Lara } 7881a75e9f3SPablo de Lara 7891a75e9f3SPablo de Lara if (port_cparams[i].do_cipher) { 790acf86169SPablo de Lara port_cparams[i].cipher_iv.data = options->cipher_iv.data; 791acf86169SPablo de Lara port_cparams[i].cipher_iv.length = options->cipher_iv.length; 792acf86169SPablo de Lara if (!options->cipher_iv_param) 793acf86169SPablo de Lara generate_random_key(port_cparams[i].cipher_iv.data, 794acf86169SPablo de Lara port_cparams[i].cipher_iv.length); 795617a7949SPablo de Lara 796d29ea843SPablo de Lara port_cparams[i].cipher_algo = options->cipher_xform.cipher.algo; 7970fbd75a9SPablo de Lara /* Set IV parameters */ 7980fbd75a9SPablo de Lara options->cipher_xform.cipher.iv.offset = IV_OFFSET; 799acf86169SPablo de Lara options->cipher_xform.cipher.iv.length = 800acf86169SPablo de Lara options->cipher_iv.length; 80127cf2d1bSPablo de Lara } 802617a7949SPablo de Lara 8032c59bd32SSlawomir Mrozowicz session = initialize_crypto_session(options, 804387259bdSDeclan Doherty port_cparams[i].dev_id); 8052c59bd32SSlawomir Mrozowicz if (session == NULL) 8062c59bd32SSlawomir Mrozowicz rte_exit(EXIT_FAILURE, "Failed to initialize crypto session\n"); 807387259bdSDeclan Doherty 8082c59bd32SSlawomir Mrozowicz port_cparams[i].session = session; 8092c59bd32SSlawomir Mrozowicz 810387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, " -- lcoreid=%u cryptoid=%u\n", lcore_id, 811387259bdSDeclan Doherty port_cparams[i].dev_id); 812387259bdSDeclan Doherty } 813387259bdSDeclan Doherty 81441e97c2eSPablo de Lara l2fwd_crypto_options_print(options); 81541e97c2eSPablo de Lara 81641e97c2eSPablo de Lara /* 81741e97c2eSPablo de Lara * Initialize previous tsc timestamp before the loop, 81841e97c2eSPablo de Lara * to avoid showing the port statistics immediately, 81941e97c2eSPablo de Lara * so user can see the crypto information. 82041e97c2eSPablo de Lara */ 82141e97c2eSPablo de Lara prev_tsc = rte_rdtsc(); 822387259bdSDeclan Doherty while (1) { 823387259bdSDeclan Doherty 824387259bdSDeclan Doherty cur_tsc = rte_rdtsc(); 825387259bdSDeclan Doherty 826387259bdSDeclan Doherty /* 827268ca735SPablo de Lara * Crypto device/TX burst queue drain 828387259bdSDeclan Doherty */ 829387259bdSDeclan Doherty diff_tsc = cur_tsc - prev_tsc; 830387259bdSDeclan Doherty if (unlikely(diff_tsc > drain_tsc)) { 831268ca735SPablo de Lara /* Enqueue all crypto ops remaining in buffers */ 832268ca735SPablo de Lara for (i = 0; i < qconf->nb_crypto_devs; i++) { 833268ca735SPablo de Lara cparams = &port_cparams[i]; 834268ca735SPablo de Lara len = qconf->op_buf[cparams->dev_id].len; 835268ca735SPablo de Lara l2fwd_crypto_send_burst(qconf, len, cparams); 836268ca735SPablo de Lara qconf->op_buf[cparams->dev_id].len = 0; 837268ca735SPablo de Lara } 838268ca735SPablo de Lara /* Transmit all packets remaining in buffers */ 839387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 840c0f87eb5SDeclan Doherty if (qconf->pkt_buf[portid].len == 0) 841387259bdSDeclan Doherty continue; 842387259bdSDeclan Doherty l2fwd_send_burst(&lcore_queue_conf[lcore_id], 843c0f87eb5SDeclan Doherty qconf->pkt_buf[portid].len, 844387259bdSDeclan Doherty (uint8_t) portid); 845c0f87eb5SDeclan Doherty qconf->pkt_buf[portid].len = 0; 846387259bdSDeclan Doherty } 847387259bdSDeclan Doherty 848387259bdSDeclan Doherty /* if timer is enabled */ 849387259bdSDeclan Doherty if (timer_period > 0) { 850387259bdSDeclan Doherty 851387259bdSDeclan Doherty /* advance the timer */ 852387259bdSDeclan Doherty timer_tsc += diff_tsc; 853387259bdSDeclan Doherty 854387259bdSDeclan Doherty /* if timer has reached its timeout */ 855387259bdSDeclan Doherty if (unlikely(timer_tsc >= 856387259bdSDeclan Doherty (uint64_t)timer_period)) { 857387259bdSDeclan Doherty 858387259bdSDeclan Doherty /* do this only on master core */ 859ad509b4aSDeclan Doherty if (lcore_id == rte_get_master_lcore() 860ad509b4aSDeclan Doherty && options->refresh_period) { 861387259bdSDeclan Doherty print_stats(); 862387259bdSDeclan Doherty timer_tsc = 0; 863387259bdSDeclan Doherty } 864387259bdSDeclan Doherty } 865387259bdSDeclan Doherty } 866387259bdSDeclan Doherty 867387259bdSDeclan Doherty prev_tsc = cur_tsc; 868387259bdSDeclan Doherty } 869387259bdSDeclan Doherty 870387259bdSDeclan Doherty /* 871387259bdSDeclan Doherty * Read packet from RX queues 872387259bdSDeclan Doherty */ 873387259bdSDeclan Doherty for (i = 0; i < qconf->nb_rx_ports; i++) { 874387259bdSDeclan Doherty portid = qconf->rx_port_list[i]; 875387259bdSDeclan Doherty 876387259bdSDeclan Doherty cparams = &port_cparams[i]; 877387259bdSDeclan Doherty 878387259bdSDeclan Doherty nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, 879387259bdSDeclan Doherty pkts_burst, MAX_PKT_BURST); 880387259bdSDeclan Doherty 881387259bdSDeclan Doherty port_statistics[portid].rx += nb_rx; 882387259bdSDeclan Doherty 883c0f87eb5SDeclan Doherty if (nb_rx) { 884387259bdSDeclan Doherty /* 885c0f87eb5SDeclan Doherty * If we can't allocate a crypto_ops, then drop 886387259bdSDeclan Doherty * the rest of the burst and dequeue and 887387259bdSDeclan Doherty * process the packets to free offload structs 888387259bdSDeclan Doherty */ 889c0f87eb5SDeclan Doherty if (rte_crypto_op_bulk_alloc( 890c0f87eb5SDeclan Doherty l2fwd_crypto_op_pool, 891c0f87eb5SDeclan Doherty RTE_CRYPTO_OP_TYPE_SYMMETRIC, 892c0f87eb5SDeclan Doherty ops_burst, nb_rx) != 893c0f87eb5SDeclan Doherty nb_rx) { 894c0f87eb5SDeclan Doherty for (j = 0; j < nb_rx; j++) 895d7acf6baSPablo de Lara rte_pktmbuf_free(pkts_burst[j]); 896c0f87eb5SDeclan Doherty 897c0f87eb5SDeclan Doherty nb_rx = 0; 898387259bdSDeclan Doherty } 899387259bdSDeclan Doherty 900c0f87eb5SDeclan Doherty /* Enqueue packets from Crypto device*/ 901c0f87eb5SDeclan Doherty for (j = 0; j < nb_rx; j++) { 902c0f87eb5SDeclan Doherty m = pkts_burst[j]; 903387259bdSDeclan Doherty 904c0f87eb5SDeclan Doherty l2fwd_simple_crypto_enqueue(m, 905c0f87eb5SDeclan Doherty ops_burst[j], cparams); 906c0f87eb5SDeclan Doherty } 907387259bdSDeclan Doherty } 908387259bdSDeclan Doherty 909387259bdSDeclan Doherty /* Dequeue packets from Crypto device */ 910c0f87eb5SDeclan Doherty do { 911387259bdSDeclan Doherty nb_rx = rte_cryptodev_dequeue_burst( 912387259bdSDeclan Doherty cparams->dev_id, cparams->qp_id, 913c0f87eb5SDeclan Doherty ops_burst, MAX_PKT_BURST); 914c0f87eb5SDeclan Doherty 915c0f87eb5SDeclan Doherty crypto_statistics[cparams->dev_id].dequeued += 916c0f87eb5SDeclan Doherty nb_rx; 917387259bdSDeclan Doherty 918387259bdSDeclan Doherty /* Forward crypto'd packets */ 919387259bdSDeclan Doherty for (j = 0; j < nb_rx; j++) { 920c0f87eb5SDeclan Doherty m = ops_burst[j]->sym->m_src; 921c0f87eb5SDeclan Doherty 922c0f87eb5SDeclan Doherty rte_crypto_op_free(ops_burst[j]); 923387259bdSDeclan Doherty l2fwd_simple_forward(m, portid); 924387259bdSDeclan Doherty } 925c0f87eb5SDeclan Doherty } while (nb_rx == MAX_PKT_BURST); 926387259bdSDeclan Doherty } 927387259bdSDeclan Doherty } 928387259bdSDeclan Doherty } 929387259bdSDeclan Doherty 930387259bdSDeclan Doherty static int 931387259bdSDeclan Doherty l2fwd_launch_one_lcore(void *arg) 932387259bdSDeclan Doherty { 933387259bdSDeclan Doherty l2fwd_main_loop((struct l2fwd_crypto_options *)arg); 934387259bdSDeclan Doherty return 0; 935387259bdSDeclan Doherty } 936387259bdSDeclan Doherty 937387259bdSDeclan Doherty /* Display command line arguments usage */ 938387259bdSDeclan Doherty static void 939387259bdSDeclan Doherty l2fwd_crypto_usage(const char *prgname) 940387259bdSDeclan Doherty { 941912b3a0aSPablo de Lara printf("%s [EAL options] --\n" 942387259bdSDeclan Doherty " -p PORTMASK: hexadecimal bitmask of ports to configure\n" 943387259bdSDeclan Doherty " -q NQ: number of queue (=ports) per lcore (default is 1)\n" 94469a558e3SPablo de Lara " -s manage all ports from single lcore\n" 945a3380989SPablo de Lara " -T PERIOD: statistics will be refreshed each PERIOD seconds" 946387259bdSDeclan Doherty " (0 to disable, 10 default, 86400 maximum)\n" 947387259bdSDeclan Doherty 948912b3a0aSPablo de Lara " --cdev_type HW / SW / ANY\n" 949a3c2e34bSPablo de Lara " --chain HASH_CIPHER / CIPHER_HASH / CIPHER_ONLY /" 9502661f4fbSPablo de Lara " HASH_ONLY / AEAD\n" 951387259bdSDeclan Doherty 952387259bdSDeclan Doherty " --cipher_algo ALGO\n" 953387259bdSDeclan Doherty " --cipher_op ENCRYPT / DECRYPT\n" 954fcdbb3d5SPablo de Lara " --cipher_key KEY (bytes separated with \":\")\n" 955a061e50aSPablo de Lara " --cipher_key_random_size SIZE: size of cipher key when generated randomly\n" 956acf86169SPablo de Lara " --cipher_iv IV (bytes separated with \":\")\n" 957acf86169SPablo de Lara " --cipher_iv_random_size SIZE: size of cipher IV when generated randomly\n" 958387259bdSDeclan Doherty 9593b98cbaaSPablo de Lara " --auth_algo ALGO\n" 960387259bdSDeclan Doherty " --auth_op GENERATE / VERIFY\n" 961fcdbb3d5SPablo de Lara " --auth_key KEY (bytes separated with \":\")\n" 962a061e50aSPablo de Lara " --auth_key_random_size SIZE: size of auth key when generated randomly\n" 963acf86169SPablo de Lara " --auth_iv IV (bytes separated with \":\")\n" 964acf86169SPablo de Lara " --auth_iv_random_size SIZE: size of auth IV when generated randomly\n" 9652661f4fbSPablo de Lara 9662661f4fbSPablo de Lara " --aead_algo ALGO\n" 9672661f4fbSPablo de Lara " --aead_op ENCRYPT / DECRYPT\n" 9682661f4fbSPablo de Lara " --aead_key KEY (bytes separated with \":\")\n" 9692661f4fbSPablo de Lara " --aead_key_random_size SIZE: size of AEAD key when generated randomly\n" 9702661f4fbSPablo de Lara " --aead_iv IV (bytes separated with \":\")\n" 9712661f4fbSPablo de Lara " --aead_iv_random_size SIZE: size of AEAD IV when generated randomly\n" 972fcdbb3d5SPablo de Lara " --aad AAD (bytes separated with \":\")\n" 973a061e50aSPablo de Lara " --aad_random_size SIZE: size of AAD when generated randomly\n" 9742661f4fbSPablo de Lara 975a061e50aSPablo de Lara " --digest_size SIZE: size of digest to be generated/verified\n" 976387259bdSDeclan Doherty 977d2797f51SFan Zhang " --sessionless\n" 978d2797f51SFan Zhang " --cryptodev_mask MASK: hexadecimal bitmask of crypto devices to configure\n", 979387259bdSDeclan Doherty prgname); 980387259bdSDeclan Doherty } 981387259bdSDeclan Doherty 982387259bdSDeclan Doherty /** Parse crypto device type command line argument */ 983387259bdSDeclan Doherty static int 98427cf2d1bSPablo de Lara parse_cryptodev_type(enum cdev_type *type, char *optarg) 985387259bdSDeclan Doherty { 98627cf2d1bSPablo de Lara if (strcmp("HW", optarg) == 0) { 98727cf2d1bSPablo de Lara *type = CDEV_TYPE_HW; 988387259bdSDeclan Doherty return 0; 98927cf2d1bSPablo de Lara } else if (strcmp("SW", optarg) == 0) { 99027cf2d1bSPablo de Lara *type = CDEV_TYPE_SW; 99127cf2d1bSPablo de Lara return 0; 99227cf2d1bSPablo de Lara } else if (strcmp("ANY", optarg) == 0) { 99327cf2d1bSPablo de Lara *type = CDEV_TYPE_ANY; 994387259bdSDeclan Doherty return 0; 995387259bdSDeclan Doherty } 996387259bdSDeclan Doherty 997387259bdSDeclan Doherty return -1; 998387259bdSDeclan Doherty } 999387259bdSDeclan Doherty 1000387259bdSDeclan Doherty /** Parse crypto chain xform command line argument */ 1001387259bdSDeclan Doherty static int 1002387259bdSDeclan Doherty parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) 1003387259bdSDeclan Doherty { 1004387259bdSDeclan Doherty if (strcmp("CIPHER_HASH", optarg) == 0) { 1005387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 1006387259bdSDeclan Doherty return 0; 1007387259bdSDeclan Doherty } else if (strcmp("HASH_CIPHER", optarg) == 0) { 1008387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_HASH_CIPHER; 1009387259bdSDeclan Doherty return 0; 10101a75e9f3SPablo de Lara } else if (strcmp("CIPHER_ONLY", optarg) == 0) { 10111a75e9f3SPablo de Lara options->xform_chain = L2FWD_CRYPTO_CIPHER_ONLY; 10121a75e9f3SPablo de Lara return 0; 10131a75e9f3SPablo de Lara } else if (strcmp("HASH_ONLY", optarg) == 0) { 10141a75e9f3SPablo de Lara options->xform_chain = L2FWD_CRYPTO_HASH_ONLY; 10151a75e9f3SPablo de Lara return 0; 10162661f4fbSPablo de Lara } else if (strcmp("AEAD", optarg) == 0) { 10172661f4fbSPablo de Lara options->xform_chain = L2FWD_CRYPTO_AEAD; 10182661f4fbSPablo de Lara return 0; 1019387259bdSDeclan Doherty } 1020387259bdSDeclan Doherty 1021387259bdSDeclan Doherty return -1; 1022387259bdSDeclan Doherty } 1023387259bdSDeclan Doherty 1024387259bdSDeclan Doherty /** Parse crypto cipher algo option command line argument */ 1025387259bdSDeclan Doherty static int 1026387259bdSDeclan Doherty parse_cipher_algo(enum rte_crypto_cipher_algorithm *algo, char *optarg) 1027387259bdSDeclan Doherty { 102800c58901SPablo de Lara 10294790f99dSPablo de Lara if (rte_cryptodev_get_cipher_algo_enum(algo, optarg) < 0) { 10304790f99dSPablo de Lara RTE_LOG(ERR, USER1, "Cipher algorithm specified " 10314790f99dSPablo de Lara "not supported!\n"); 1032387259bdSDeclan Doherty return -1; 1033387259bdSDeclan Doherty } 1034387259bdSDeclan Doherty 10354790f99dSPablo de Lara return 0; 10364790f99dSPablo de Lara } 10374790f99dSPablo de Lara 1038387259bdSDeclan Doherty /** Parse crypto cipher operation command line argument */ 1039387259bdSDeclan Doherty static int 1040387259bdSDeclan Doherty parse_cipher_op(enum rte_crypto_cipher_operation *op, char *optarg) 1041387259bdSDeclan Doherty { 1042387259bdSDeclan Doherty if (strcmp("ENCRYPT", optarg) == 0) { 1043387259bdSDeclan Doherty *op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1044387259bdSDeclan Doherty return 0; 1045387259bdSDeclan Doherty } else if (strcmp("DECRYPT", optarg) == 0) { 1046387259bdSDeclan Doherty *op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 1047387259bdSDeclan Doherty return 0; 1048387259bdSDeclan Doherty } 1049387259bdSDeclan Doherty 1050387259bdSDeclan Doherty printf("Cipher operation not supported!\n"); 1051387259bdSDeclan Doherty return -1; 1052387259bdSDeclan Doherty } 1053387259bdSDeclan Doherty 1054387259bdSDeclan Doherty /** Parse crypto key command line argument */ 1055387259bdSDeclan Doherty static int 10561df9c010SPablo de Lara parse_key(uint8_t *data, char *input_arg) 1057387259bdSDeclan Doherty { 10581df9c010SPablo de Lara unsigned byte_count; 10591df9c010SPablo de Lara char *token; 10601df9c010SPablo de Lara 10611df9c010SPablo de Lara for (byte_count = 0, token = strtok(input_arg, ":"); 10621df9c010SPablo de Lara (byte_count < MAX_KEY_SIZE) && (token != NULL); 10631df9c010SPablo de Lara token = strtok(NULL, ":")) { 10641df9c010SPablo de Lara 10651df9c010SPablo de Lara int number = (int)strtol(token, NULL, 16); 10661df9c010SPablo de Lara 10671df9c010SPablo de Lara if (errno == EINVAL || errno == ERANGE || number > 0xFF) 1068387259bdSDeclan Doherty return -1; 10691df9c010SPablo de Lara 10701df9c010SPablo de Lara data[byte_count++] = (uint8_t)number; 10711df9c010SPablo de Lara } 10721df9c010SPablo de Lara 1073a061e50aSPablo de Lara return byte_count; 1074a061e50aSPablo de Lara } 1075a061e50aSPablo de Lara 1076a061e50aSPablo de Lara /** Parse size param*/ 1077a061e50aSPablo de Lara static int 1078a061e50aSPablo de Lara parse_size(int *size, const char *q_arg) 1079a061e50aSPablo de Lara { 1080a061e50aSPablo de Lara char *end = NULL; 1081a061e50aSPablo de Lara unsigned long n; 1082a061e50aSPablo de Lara 1083a061e50aSPablo de Lara /* parse hexadecimal string */ 1084a061e50aSPablo de Lara n = strtoul(q_arg, &end, 10); 1085a061e50aSPablo de Lara if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1086a061e50aSPablo de Lara n = 0; 1087a061e50aSPablo de Lara 1088a061e50aSPablo de Lara if (n == 0) { 1089a061e50aSPablo de Lara printf("invalid size\n"); 1090a061e50aSPablo de Lara return -1; 1091a061e50aSPablo de Lara } 1092a061e50aSPablo de Lara 1093a061e50aSPablo de Lara *size = n; 10941df9c010SPablo de Lara return 0; 1095387259bdSDeclan Doherty } 1096387259bdSDeclan Doherty 1097387259bdSDeclan Doherty /** Parse crypto cipher operation command line argument */ 1098387259bdSDeclan Doherty static int 1099387259bdSDeclan Doherty parse_auth_algo(enum rte_crypto_auth_algorithm *algo, char *optarg) 1100387259bdSDeclan Doherty { 11014790f99dSPablo de Lara if (rte_cryptodev_get_auth_algo_enum(algo, optarg) < 0) { 11024790f99dSPablo de Lara RTE_LOG(ERR, USER1, "Authentication algorithm specified " 11034790f99dSPablo de Lara "not supported!\n"); 1104387259bdSDeclan Doherty return -1; 1105387259bdSDeclan Doherty } 1106387259bdSDeclan Doherty 11074790f99dSPablo de Lara return 0; 11084790f99dSPablo de Lara } 11094790f99dSPablo de Lara 1110387259bdSDeclan Doherty static int 1111387259bdSDeclan Doherty parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg) 1112387259bdSDeclan Doherty { 1113387259bdSDeclan Doherty if (strcmp("VERIFY", optarg) == 0) { 1114387259bdSDeclan Doherty *op = RTE_CRYPTO_AUTH_OP_VERIFY; 1115387259bdSDeclan Doherty return 0; 1116387259bdSDeclan Doherty } else if (strcmp("GENERATE", optarg) == 0) { 111772169087SPablo de Lara *op = RTE_CRYPTO_AUTH_OP_GENERATE; 1118387259bdSDeclan Doherty return 0; 1119387259bdSDeclan Doherty } 1120387259bdSDeclan Doherty 1121387259bdSDeclan Doherty printf("Authentication operation specified not supported!\n"); 1122387259bdSDeclan Doherty return -1; 1123387259bdSDeclan Doherty } 1124387259bdSDeclan Doherty 1125d2797f51SFan Zhang static int 11262661f4fbSPablo de Lara parse_aead_algo(enum rte_crypto_aead_algorithm *algo, char *optarg) 11272661f4fbSPablo de Lara { 11282661f4fbSPablo de Lara if (rte_cryptodev_get_aead_algo_enum(algo, optarg) < 0) { 11292661f4fbSPablo de Lara RTE_LOG(ERR, USER1, "AEAD algorithm specified " 11302661f4fbSPablo de Lara "not supported!\n"); 11312661f4fbSPablo de Lara return -1; 11322661f4fbSPablo de Lara } 11332661f4fbSPablo de Lara 11342661f4fbSPablo de Lara return 0; 11352661f4fbSPablo de Lara } 11362661f4fbSPablo de Lara 11372661f4fbSPablo de Lara static int 11382661f4fbSPablo de Lara parse_aead_op(enum rte_crypto_aead_operation *op, char *optarg) 11392661f4fbSPablo de Lara { 11402661f4fbSPablo de Lara if (strcmp("ENCRYPT", optarg) == 0) { 11412661f4fbSPablo de Lara *op = RTE_CRYPTO_AEAD_OP_ENCRYPT; 11422661f4fbSPablo de Lara return 0; 11432661f4fbSPablo de Lara } else if (strcmp("DECRYPT", optarg) == 0) { 11442661f4fbSPablo de Lara *op = RTE_CRYPTO_AEAD_OP_DECRYPT; 11452661f4fbSPablo de Lara return 0; 11462661f4fbSPablo de Lara } 11472661f4fbSPablo de Lara 11482661f4fbSPablo de Lara printf("AEAD operation specified not supported!\n"); 11492661f4fbSPablo de Lara return -1; 11502661f4fbSPablo de Lara } 11512661f4fbSPablo de Lara static int 1152d2797f51SFan Zhang parse_cryptodev_mask(struct l2fwd_crypto_options *options, 1153d2797f51SFan Zhang const char *q_arg) 1154d2797f51SFan Zhang { 1155d2797f51SFan Zhang char *end = NULL; 1156d2797f51SFan Zhang uint64_t pm; 1157d2797f51SFan Zhang 1158d2797f51SFan Zhang /* parse hexadecimal string */ 1159d2797f51SFan Zhang pm = strtoul(q_arg, &end, 16); 1160d2797f51SFan Zhang if ((pm == '\0') || (end == NULL) || (*end != '\0')) 1161d2797f51SFan Zhang pm = 0; 1162d2797f51SFan Zhang 1163d2797f51SFan Zhang options->cryptodev_mask = pm; 1164d2797f51SFan Zhang if (options->cryptodev_mask == 0) { 1165d2797f51SFan Zhang printf("invalid cryptodev_mask specified\n"); 1166d2797f51SFan Zhang return -1; 1167d2797f51SFan Zhang } 1168d2797f51SFan Zhang 1169d2797f51SFan Zhang return 0; 1170d2797f51SFan Zhang } 1171d2797f51SFan Zhang 1172387259bdSDeclan Doherty /** Parse long options */ 1173387259bdSDeclan Doherty static int 1174387259bdSDeclan Doherty l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, 1175387259bdSDeclan Doherty struct option *lgopts, int option_index) 1176387259bdSDeclan Doherty { 117727cf2d1bSPablo de Lara int retval; 117827cf2d1bSPablo de Lara 117949f79e86SPablo de Lara if (strcmp(lgopts[option_index].name, "cdev_type") == 0) { 118049f79e86SPablo de Lara retval = parse_cryptodev_type(&options->type, optarg); 118149f79e86SPablo de Lara if (retval == 0) 118299218e76SPablo de Lara snprintf(options->string_type, MAX_STR_LEN, 118399218e76SPablo de Lara "%s", optarg); 118449f79e86SPablo de Lara return retval; 118549f79e86SPablo de Lara } 1186387259bdSDeclan Doherty 1187387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "chain") == 0) 1188387259bdSDeclan Doherty return parse_crypto_opt_chain(options, optarg); 1189387259bdSDeclan Doherty 1190387259bdSDeclan Doherty /* Cipher options */ 119100c58901SPablo de Lara else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0) 119200c58901SPablo de Lara return parse_cipher_algo(&options->cipher_xform.cipher.algo, 1193387259bdSDeclan Doherty optarg); 1194387259bdSDeclan Doherty 1195387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "cipher_op") == 0) 1196387259bdSDeclan Doherty return parse_cipher_op(&options->cipher_xform.cipher.op, 1197387259bdSDeclan Doherty optarg); 1198387259bdSDeclan Doherty 1199a7f4562bSFiona Trahe else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) { 12001df9c010SPablo de Lara options->ckey_param = 1; 1201a061e50aSPablo de Lara options->cipher_xform.cipher.key.length = 1202a061e50aSPablo de Lara parse_key(options->cipher_xform.cipher.key.data, optarg); 1203a061e50aSPablo de Lara if (options->cipher_xform.cipher.key.length > 0) 1204a061e50aSPablo de Lara return 0; 1205a061e50aSPablo de Lara else 1206a061e50aSPablo de Lara return -1; 12071df9c010SPablo de Lara } 1208387259bdSDeclan Doherty 1209a061e50aSPablo de Lara else if (strcmp(lgopts[option_index].name, "cipher_key_random_size") == 0) 1210a061e50aSPablo de Lara return parse_size(&options->ckey_random_size, optarg); 1211a061e50aSPablo de Lara 1212acf86169SPablo de Lara else if (strcmp(lgopts[option_index].name, "cipher_iv") == 0) { 1213acf86169SPablo de Lara options->cipher_iv_param = 1; 1214acf86169SPablo de Lara options->cipher_iv.length = 1215acf86169SPablo de Lara parse_key(options->cipher_iv.data, optarg); 1216acf86169SPablo de Lara if (options->cipher_iv.length > 0) 1217a061e50aSPablo de Lara return 0; 1218a061e50aSPablo de Lara else 1219a061e50aSPablo de Lara return -1; 12201df9c010SPablo de Lara } 1221387259bdSDeclan Doherty 1222acf86169SPablo de Lara else if (strcmp(lgopts[option_index].name, "cipher_iv_random_size") == 0) 1223acf86169SPablo de Lara return parse_size(&options->cipher_iv_random_size, optarg); 1224a061e50aSPablo de Lara 1225387259bdSDeclan Doherty /* Authentication options */ 122627cf2d1bSPablo de Lara else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) { 122700c58901SPablo de Lara return parse_auth_algo(&options->auth_xform.auth.algo, 1228387259bdSDeclan Doherty optarg); 122927cf2d1bSPablo de Lara } 1230387259bdSDeclan Doherty 1231387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "auth_op") == 0) 123272169087SPablo de Lara return parse_auth_op(&options->auth_xform.auth.op, 1233387259bdSDeclan Doherty optarg); 1234387259bdSDeclan Doherty 1235a7f4562bSFiona Trahe else if (strcmp(lgopts[option_index].name, "auth_key") == 0) { 12361df9c010SPablo de Lara options->akey_param = 1; 1237a061e50aSPablo de Lara options->auth_xform.auth.key.length = 1238a061e50aSPablo de Lara parse_key(options->auth_xform.auth.key.data, optarg); 1239a061e50aSPablo de Lara if (options->auth_xform.auth.key.length > 0) 1240a061e50aSPablo de Lara return 0; 1241a061e50aSPablo de Lara else 1242a061e50aSPablo de Lara return -1; 1243a061e50aSPablo de Lara } 1244a061e50aSPablo de Lara 1245a061e50aSPablo de Lara else if (strcmp(lgopts[option_index].name, "auth_key_random_size") == 0) { 1246a061e50aSPablo de Lara return parse_size(&options->akey_random_size, optarg); 12471df9c010SPablo de Lara } 1248387259bdSDeclan Doherty 1249acf86169SPablo de Lara else if (strcmp(lgopts[option_index].name, "auth_iv") == 0) { 1250acf86169SPablo de Lara options->auth_iv_param = 1; 1251acf86169SPablo de Lara options->auth_iv.length = 1252acf86169SPablo de Lara parse_key(options->auth_iv.data, optarg); 1253acf86169SPablo de Lara if (options->auth_iv.length > 0) 1254acf86169SPablo de Lara return 0; 1255acf86169SPablo de Lara else 1256acf86169SPablo de Lara return -1; 1257acf86169SPablo de Lara } 1258acf86169SPablo de Lara 1259acf86169SPablo de Lara else if (strcmp(lgopts[option_index].name, "auth_iv_random_size") == 0) 1260acf86169SPablo de Lara return parse_size(&options->auth_iv_random_size, optarg); 1261acf86169SPablo de Lara 12622661f4fbSPablo de Lara /* AEAD options */ 12632661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_algo") == 0) { 12642661f4fbSPablo de Lara return parse_aead_algo(&options->aead_xform.aead.algo, 12652661f4fbSPablo de Lara optarg); 12662661f4fbSPablo de Lara } 12672661f4fbSPablo de Lara 12682661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_op") == 0) 12692661f4fbSPablo de Lara return parse_aead_op(&options->aead_xform.aead.op, 12702661f4fbSPablo de Lara optarg); 12712661f4fbSPablo de Lara 12722661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_key") == 0) { 12732661f4fbSPablo de Lara options->aead_key_param = 1; 12742661f4fbSPablo de Lara options->aead_xform.aead.key.length = 12752661f4fbSPablo de Lara parse_key(options->aead_xform.aead.key.data, optarg); 12762661f4fbSPablo de Lara if (options->aead_xform.aead.key.length > 0) 12772661f4fbSPablo de Lara return 0; 12782661f4fbSPablo de Lara else 12792661f4fbSPablo de Lara return -1; 12802661f4fbSPablo de Lara } 12812661f4fbSPablo de Lara 12822661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_key_random_size") == 0) 12832661f4fbSPablo de Lara return parse_size(&options->aead_key_random_size, optarg); 12842661f4fbSPablo de Lara 12852661f4fbSPablo de Lara 12862661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_iv") == 0) { 12872661f4fbSPablo de Lara options->aead_iv_param = 1; 12882661f4fbSPablo de Lara options->aead_iv.length = 12892661f4fbSPablo de Lara parse_key(options->aead_iv.data, optarg); 12902661f4fbSPablo de Lara if (options->aead_iv.length > 0) 12912661f4fbSPablo de Lara return 0; 12922661f4fbSPablo de Lara else 12932661f4fbSPablo de Lara return -1; 12942661f4fbSPablo de Lara } 12952661f4fbSPablo de Lara 12962661f4fbSPablo de Lara else if (strcmp(lgopts[option_index].name, "aead_iv_random_size") == 0) 12972661f4fbSPablo de Lara return parse_size(&options->aead_iv_random_size, optarg); 12982661f4fbSPablo de Lara 1299617a7949SPablo de Lara else if (strcmp(lgopts[option_index].name, "aad") == 0) { 1300617a7949SPablo de Lara options->aad_param = 1; 1301a061e50aSPablo de Lara options->aad.length = 1302a061e50aSPablo de Lara parse_key(options->aad.data, optarg); 1303a061e50aSPablo de Lara if (options->aad.length > 0) 1304a061e50aSPablo de Lara return 0; 1305a061e50aSPablo de Lara else 1306a061e50aSPablo de Lara return -1; 1307a061e50aSPablo de Lara } 1308a061e50aSPablo de Lara 1309a061e50aSPablo de Lara else if (strcmp(lgopts[option_index].name, "aad_random_size") == 0) { 1310a061e50aSPablo de Lara return parse_size(&options->aad_random_size, optarg); 1311a061e50aSPablo de Lara } 1312a061e50aSPablo de Lara 1313a061e50aSPablo de Lara else if (strcmp(lgopts[option_index].name, "digest_size") == 0) { 1314a061e50aSPablo de Lara return parse_size(&options->digest_size, optarg); 1315617a7949SPablo de Lara } 1316617a7949SPablo de Lara 13171df9c010SPablo de Lara else if (strcmp(lgopts[option_index].name, "sessionless") == 0) { 1318387259bdSDeclan Doherty options->sessionless = 1; 1319387259bdSDeclan Doherty return 0; 1320387259bdSDeclan Doherty } 1321387259bdSDeclan Doherty 1322d2797f51SFan Zhang else if (strcmp(lgopts[option_index].name, "cryptodev_mask") == 0) 1323d2797f51SFan Zhang return parse_cryptodev_mask(options, optarg); 1324d2797f51SFan Zhang 1325387259bdSDeclan Doherty return -1; 1326387259bdSDeclan Doherty } 1327387259bdSDeclan Doherty 1328387259bdSDeclan Doherty /** Parse port mask */ 1329387259bdSDeclan Doherty static int 1330387259bdSDeclan Doherty l2fwd_crypto_parse_portmask(struct l2fwd_crypto_options *options, 1331387259bdSDeclan Doherty const char *q_arg) 1332387259bdSDeclan Doherty { 1333387259bdSDeclan Doherty char *end = NULL; 1334387259bdSDeclan Doherty unsigned long pm; 1335387259bdSDeclan Doherty 1336387259bdSDeclan Doherty /* parse hexadecimal string */ 1337387259bdSDeclan Doherty pm = strtoul(q_arg, &end, 16); 1338387259bdSDeclan Doherty if ((pm == '\0') || (end == NULL) || (*end != '\0')) 1339387259bdSDeclan Doherty pm = 0; 1340387259bdSDeclan Doherty 1341387259bdSDeclan Doherty options->portmask = pm; 1342387259bdSDeclan Doherty if (options->portmask == 0) { 1343387259bdSDeclan Doherty printf("invalid portmask specified\n"); 1344387259bdSDeclan Doherty return -1; 1345387259bdSDeclan Doherty } 1346387259bdSDeclan Doherty 1347387259bdSDeclan Doherty return pm; 1348387259bdSDeclan Doherty } 1349387259bdSDeclan Doherty 1350387259bdSDeclan Doherty /** Parse number of queues */ 1351387259bdSDeclan Doherty static int 1352387259bdSDeclan Doherty l2fwd_crypto_parse_nqueue(struct l2fwd_crypto_options *options, 1353387259bdSDeclan Doherty const char *q_arg) 1354387259bdSDeclan Doherty { 1355387259bdSDeclan Doherty char *end = NULL; 1356387259bdSDeclan Doherty unsigned long n; 1357387259bdSDeclan Doherty 1358387259bdSDeclan Doherty /* parse hexadecimal string */ 1359387259bdSDeclan Doherty n = strtoul(q_arg, &end, 10); 1360387259bdSDeclan Doherty if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1361387259bdSDeclan Doherty n = 0; 1362387259bdSDeclan Doherty else if (n >= MAX_RX_QUEUE_PER_LCORE) 1363387259bdSDeclan Doherty n = 0; 1364387259bdSDeclan Doherty 1365387259bdSDeclan Doherty options->nb_ports_per_lcore = n; 1366387259bdSDeclan Doherty if (options->nb_ports_per_lcore == 0) { 1367387259bdSDeclan Doherty printf("invalid number of ports selected\n"); 1368387259bdSDeclan Doherty return -1; 1369387259bdSDeclan Doherty } 1370387259bdSDeclan Doherty 1371387259bdSDeclan Doherty return 0; 1372387259bdSDeclan Doherty } 1373387259bdSDeclan Doherty 1374387259bdSDeclan Doherty /** Parse timer period */ 1375387259bdSDeclan Doherty static int 1376387259bdSDeclan Doherty l2fwd_crypto_parse_timer_period(struct l2fwd_crypto_options *options, 1377387259bdSDeclan Doherty const char *q_arg) 1378387259bdSDeclan Doherty { 1379387259bdSDeclan Doherty char *end = NULL; 13803c96262cSPablo de Lara unsigned long n; 1381387259bdSDeclan Doherty 1382387259bdSDeclan Doherty /* parse number string */ 13833c96262cSPablo de Lara n = (unsigned)strtol(q_arg, &end, 10); 1384387259bdSDeclan Doherty if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1385387259bdSDeclan Doherty n = 0; 1386387259bdSDeclan Doherty 1387ad509b4aSDeclan Doherty if (n >= MAX_TIMER_PERIOD) { 13883c96262cSPablo de Lara printf("Warning refresh period specified %lu is greater than " 13893c96262cSPablo de Lara "max value %lu! using max value", 1390ad509b4aSDeclan Doherty n, MAX_TIMER_PERIOD); 1391ad509b4aSDeclan Doherty n = MAX_TIMER_PERIOD; 1392ad509b4aSDeclan Doherty } 1393387259bdSDeclan Doherty 1394387259bdSDeclan Doherty options->refresh_period = n * 1000 * TIMER_MILLISECOND; 1395387259bdSDeclan Doherty 1396387259bdSDeclan Doherty return 0; 1397387259bdSDeclan Doherty } 1398387259bdSDeclan Doherty 1399387259bdSDeclan Doherty /** Generate default options for application */ 1400387259bdSDeclan Doherty static void 1401387259bdSDeclan Doherty l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) 1402387259bdSDeclan Doherty { 1403387259bdSDeclan Doherty options->portmask = 0xffffffff; 1404387259bdSDeclan Doherty options->nb_ports_per_lcore = 1; 1405387259bdSDeclan Doherty options->refresh_period = 10000; 1406387259bdSDeclan Doherty options->single_lcore = 0; 14073c96262cSPablo de Lara options->sessionless = 0; 1408387259bdSDeclan Doherty 1409387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 1410387259bdSDeclan Doherty 1411387259bdSDeclan Doherty /* Cipher Data */ 14121bd407faSFiona Trahe options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1413387259bdSDeclan Doherty options->cipher_xform.next = NULL; 14141df9c010SPablo de Lara options->ckey_param = 0; 1415a061e50aSPablo de Lara options->ckey_random_size = -1; 1416a061e50aSPablo de Lara options->cipher_xform.cipher.key.length = 0; 1417acf86169SPablo de Lara options->cipher_iv_param = 0; 1418acf86169SPablo de Lara options->cipher_iv_random_size = -1; 1419acf86169SPablo de Lara options->cipher_iv.length = 0; 1420387259bdSDeclan Doherty 1421387259bdSDeclan Doherty options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; 1422387259bdSDeclan Doherty options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1423387259bdSDeclan Doherty 1424387259bdSDeclan Doherty /* Authentication Data */ 14251bd407faSFiona Trahe options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1426387259bdSDeclan Doherty options->auth_xform.next = NULL; 14271df9c010SPablo de Lara options->akey_param = 0; 1428a061e50aSPablo de Lara options->akey_random_size = -1; 1429a061e50aSPablo de Lara options->auth_xform.auth.key.length = 0; 1430acf86169SPablo de Lara options->auth_iv_param = 0; 1431acf86169SPablo de Lara options->auth_iv_random_size = -1; 1432acf86169SPablo de Lara options->auth_iv.length = 0; 1433387259bdSDeclan Doherty 1434387259bdSDeclan Doherty options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; 143527cf2d1bSPablo de Lara options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; 1436387259bdSDeclan Doherty 14372661f4fbSPablo de Lara /* AEAD Data */ 14382661f4fbSPablo de Lara options->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; 14392661f4fbSPablo de Lara options->aead_xform.next = NULL; 14402661f4fbSPablo de Lara options->aead_key_param = 0; 14412661f4fbSPablo de Lara options->aead_key_random_size = -1; 14422661f4fbSPablo de Lara options->aead_xform.aead.key.length = 0; 14432661f4fbSPablo de Lara options->aead_iv_param = 0; 14442661f4fbSPablo de Lara options->aead_iv_random_size = -1; 14452661f4fbSPablo de Lara options->aead_iv.length = 0; 14462661f4fbSPablo de Lara 1447b79e4c00SPablo de Lara options->auth_xform.aead.algo = RTE_CRYPTO_AEAD_AES_GCM; 1448b79e4c00SPablo de Lara options->auth_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT; 1449b79e4c00SPablo de Lara 14502661f4fbSPablo de Lara options->aad_param = 0; 14512661f4fbSPablo de Lara options->aad_random_size = -1; 14522661f4fbSPablo de Lara options->aad.length = 0; 14532661f4fbSPablo de Lara 14542661f4fbSPablo de Lara options->digest_size = -1; 14552661f4fbSPablo de Lara 145627cf2d1bSPablo de Lara options->type = CDEV_TYPE_ANY; 1457d2797f51SFan Zhang options->cryptodev_mask = UINT64_MAX; 1458387259bdSDeclan Doherty } 1459387259bdSDeclan Doherty 1460387259bdSDeclan Doherty static void 146141e97c2eSPablo de Lara display_cipher_info(struct l2fwd_crypto_options *options) 146241e97c2eSPablo de Lara { 146341e97c2eSPablo de Lara printf("\n---- Cipher information ---\n"); 146441e97c2eSPablo de Lara printf("Algorithm: %s\n", 14654790f99dSPablo de Lara rte_crypto_cipher_algorithm_strings[options->cipher_xform.cipher.algo]); 146641e97c2eSPablo de Lara rte_hexdump(stdout, "Cipher key:", 146741e97c2eSPablo de Lara options->cipher_xform.cipher.key.data, 146841e97c2eSPablo de Lara options->cipher_xform.cipher.key.length); 1469acf86169SPablo de Lara rte_hexdump(stdout, "IV:", options->cipher_iv.data, options->cipher_iv.length); 147041e97c2eSPablo de Lara } 147141e97c2eSPablo de Lara 147241e97c2eSPablo de Lara static void 147341e97c2eSPablo de Lara display_auth_info(struct l2fwd_crypto_options *options) 147441e97c2eSPablo de Lara { 147541e97c2eSPablo de Lara printf("\n---- Authentication information ---\n"); 147641e97c2eSPablo de Lara printf("Algorithm: %s\n", 14774eb45d2dSPablo de Lara rte_crypto_auth_algorithm_strings[options->auth_xform.auth.algo]); 147841e97c2eSPablo de Lara rte_hexdump(stdout, "Auth key:", 147941e97c2eSPablo de Lara options->auth_xform.auth.key.data, 148041e97c2eSPablo de Lara options->auth_xform.auth.key.length); 1481acf86169SPablo de Lara rte_hexdump(stdout, "IV:", options->auth_iv.data, options->auth_iv.length); 14822661f4fbSPablo de Lara } 14832661f4fbSPablo de Lara 14842661f4fbSPablo de Lara static void 14852661f4fbSPablo de Lara display_aead_info(struct l2fwd_crypto_options *options) 14862661f4fbSPablo de Lara { 14872661f4fbSPablo de Lara printf("\n---- AEAD information ---\n"); 14882661f4fbSPablo de Lara printf("Algorithm: %s\n", 14892661f4fbSPablo de Lara rte_crypto_aead_algorithm_strings[options->aead_xform.aead.algo]); 14902661f4fbSPablo de Lara rte_hexdump(stdout, "AEAD key:", 14912661f4fbSPablo de Lara options->aead_xform.aead.key.data, 14922661f4fbSPablo de Lara options->aead_xform.aead.key.length); 14932661f4fbSPablo de Lara rte_hexdump(stdout, "IV:", options->aead_iv.data, options->aead_iv.length); 149441e97c2eSPablo de Lara rte_hexdump(stdout, "AAD:", options->aad.data, options->aad.length); 149541e97c2eSPablo de Lara } 149641e97c2eSPablo de Lara 149741e97c2eSPablo de Lara static void 1498387259bdSDeclan Doherty l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) 1499387259bdSDeclan Doherty { 150041e97c2eSPablo de Lara char string_cipher_op[MAX_STR_LEN]; 150141e97c2eSPablo de Lara char string_auth_op[MAX_STR_LEN]; 15022661f4fbSPablo de Lara char string_aead_op[MAX_STR_LEN]; 150341e97c2eSPablo de Lara 150441e97c2eSPablo de Lara if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 150541e97c2eSPablo de Lara strcpy(string_cipher_op, "Encrypt"); 150641e97c2eSPablo de Lara else 150741e97c2eSPablo de Lara strcpy(string_cipher_op, "Decrypt"); 150841e97c2eSPablo de Lara 150941e97c2eSPablo de Lara if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) 151041e97c2eSPablo de Lara strcpy(string_auth_op, "Auth generate"); 151141e97c2eSPablo de Lara else 151241e97c2eSPablo de Lara strcpy(string_auth_op, "Auth verify"); 151341e97c2eSPablo de Lara 15142661f4fbSPablo de Lara if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) 15152661f4fbSPablo de Lara strcpy(string_aead_op, "Authenticated encryption"); 15162661f4fbSPablo de Lara else 15172661f4fbSPablo de Lara strcpy(string_aead_op, "Authenticated decryption"); 15182661f4fbSPablo de Lara 15192661f4fbSPablo de Lara 1520387259bdSDeclan Doherty printf("Options:-\nn"); 1521387259bdSDeclan Doherty printf("portmask: %x\n", options->portmask); 1522387259bdSDeclan Doherty printf("ports per lcore: %u\n", options->nb_ports_per_lcore); 1523387259bdSDeclan Doherty printf("refresh period : %u\n", options->refresh_period); 1524387259bdSDeclan Doherty printf("single lcore mode: %s\n", 1525387259bdSDeclan Doherty options->single_lcore ? "enabled" : "disabled"); 1526387259bdSDeclan Doherty printf("stats_printing: %s\n", 1527ad509b4aSDeclan Doherty options->refresh_period == 0 ? "disabled" : "enabled"); 1528387259bdSDeclan Doherty 1529387259bdSDeclan Doherty printf("sessionless crypto: %s\n", 1530387259bdSDeclan Doherty options->sessionless ? "enabled" : "disabled"); 153141e97c2eSPablo de Lara 153241e97c2eSPablo de Lara if (options->ckey_param && (options->ckey_random_size != -1)) 153341e97c2eSPablo de Lara printf("Cipher key already parsed, ignoring size of random key\n"); 153441e97c2eSPablo de Lara 153541e97c2eSPablo de Lara if (options->akey_param && (options->akey_random_size != -1)) 153641e97c2eSPablo de Lara printf("Auth key already parsed, ignoring size of random key\n"); 153741e97c2eSPablo de Lara 1538acf86169SPablo de Lara if (options->cipher_iv_param && (options->cipher_iv_random_size != -1)) 1539acf86169SPablo de Lara printf("Cipher IV already parsed, ignoring size of random IV\n"); 1540acf86169SPablo de Lara 1541acf86169SPablo de Lara if (options->auth_iv_param && (options->auth_iv_random_size != -1)) 1542acf86169SPablo de Lara printf("Auth IV already parsed, ignoring size of random IV\n"); 154341e97c2eSPablo de Lara 154441e97c2eSPablo de Lara if (options->aad_param && (options->aad_random_size != -1)) 154541e97c2eSPablo de Lara printf("AAD already parsed, ignoring size of random AAD\n"); 154641e97c2eSPablo de Lara 154741e97c2eSPablo de Lara printf("\nCrypto chain: "); 154841e97c2eSPablo de Lara switch (options->xform_chain) { 15492661f4fbSPablo de Lara case L2FWD_CRYPTO_AEAD: 15502661f4fbSPablo de Lara printf("Input --> %s --> Output\n", string_aead_op); 15512661f4fbSPablo de Lara display_aead_info(options); 15522661f4fbSPablo de Lara break; 155341e97c2eSPablo de Lara case L2FWD_CRYPTO_CIPHER_HASH: 155441e97c2eSPablo de Lara printf("Input --> %s --> %s --> Output\n", 155541e97c2eSPablo de Lara string_cipher_op, string_auth_op); 155641e97c2eSPablo de Lara display_cipher_info(options); 155741e97c2eSPablo de Lara display_auth_info(options); 155841e97c2eSPablo de Lara break; 155941e97c2eSPablo de Lara case L2FWD_CRYPTO_HASH_CIPHER: 156041e97c2eSPablo de Lara printf("Input --> %s --> %s --> Output\n", 156141e97c2eSPablo de Lara string_auth_op, string_cipher_op); 156241e97c2eSPablo de Lara display_cipher_info(options); 156341e97c2eSPablo de Lara display_auth_info(options); 156441e97c2eSPablo de Lara break; 156541e97c2eSPablo de Lara case L2FWD_CRYPTO_HASH_ONLY: 156641e97c2eSPablo de Lara printf("Input --> %s --> Output\n", string_auth_op); 156741e97c2eSPablo de Lara display_auth_info(options); 156841e97c2eSPablo de Lara break; 156941e97c2eSPablo de Lara case L2FWD_CRYPTO_CIPHER_ONLY: 157041e97c2eSPablo de Lara printf("Input --> %s --> Output\n", string_cipher_op); 157141e97c2eSPablo de Lara display_cipher_info(options); 157241e97c2eSPablo de Lara break; 157341e97c2eSPablo de Lara } 1574387259bdSDeclan Doherty } 1575387259bdSDeclan Doherty 1576387259bdSDeclan Doherty /* Parse the argument given in the command line of the application */ 1577387259bdSDeclan Doherty static int 1578387259bdSDeclan Doherty l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options, 1579387259bdSDeclan Doherty int argc, char **argv) 1580387259bdSDeclan Doherty { 1581387259bdSDeclan Doherty int opt, retval, option_index; 1582387259bdSDeclan Doherty char **argvopt = argv, *prgname = argv[0]; 1583387259bdSDeclan Doherty 1584387259bdSDeclan Doherty static struct option lgopts[] = { 1585387259bdSDeclan Doherty { "sessionless", no_argument, 0, 0 }, 1586387259bdSDeclan Doherty 1587387259bdSDeclan Doherty { "cdev_type", required_argument, 0, 0 }, 1588387259bdSDeclan Doherty { "chain", required_argument, 0, 0 }, 1589387259bdSDeclan Doherty 1590387259bdSDeclan Doherty { "cipher_algo", required_argument, 0, 0 }, 1591387259bdSDeclan Doherty { "cipher_op", required_argument, 0, 0 }, 1592387259bdSDeclan Doherty { "cipher_key", required_argument, 0, 0 }, 1593a061e50aSPablo de Lara { "cipher_key_random_size", required_argument, 0, 0 }, 1594acf86169SPablo de Lara { "cipher_iv", required_argument, 0, 0 }, 1595acf86169SPablo de Lara { "cipher_iv_random_size", required_argument, 0, 0 }, 1596387259bdSDeclan Doherty 1597387259bdSDeclan Doherty { "auth_algo", required_argument, 0, 0 }, 1598387259bdSDeclan Doherty { "auth_op", required_argument, 0, 0 }, 1599387259bdSDeclan Doherty { "auth_key", required_argument, 0, 0 }, 1600a061e50aSPablo de Lara { "auth_key_random_size", required_argument, 0, 0 }, 1601acf86169SPablo de Lara { "auth_iv", required_argument, 0, 0 }, 1602acf86169SPablo de Lara { "auth_iv_random_size", required_argument, 0, 0 }, 1603387259bdSDeclan Doherty 16042661f4fbSPablo de Lara { "aead_algo", required_argument, 0, 0 }, 16052661f4fbSPablo de Lara { "aead_op", required_argument, 0, 0 }, 16062661f4fbSPablo de Lara { "aead_key", required_argument, 0, 0 }, 16072661f4fbSPablo de Lara { "aead_key_random_size", required_argument, 0, 0 }, 16082661f4fbSPablo de Lara { "aead_iv", required_argument, 0, 0 }, 16092661f4fbSPablo de Lara { "aead_iv_random_size", required_argument, 0, 0 }, 16102661f4fbSPablo de Lara 1611617a7949SPablo de Lara { "aad", required_argument, 0, 0 }, 1612a061e50aSPablo de Lara { "aad_random_size", required_argument, 0, 0 }, 16132661f4fbSPablo de Lara 1614a061e50aSPablo de Lara { "digest_size", required_argument, 0, 0 }, 1615387259bdSDeclan Doherty 1616387259bdSDeclan Doherty { "sessionless", no_argument, 0, 0 }, 1617d2797f51SFan Zhang { "cryptodev_mask", required_argument, 0, 0}, 16183c96262cSPablo de Lara 1619387259bdSDeclan Doherty { NULL, 0, 0, 0 } 1620387259bdSDeclan Doherty }; 1621387259bdSDeclan Doherty 1622387259bdSDeclan Doherty l2fwd_crypto_default_options(options); 1623387259bdSDeclan Doherty 1624f1ae15baSPablo de Lara while ((opt = getopt_long(argc, argvopt, "p:q:sT:", lgopts, 1625387259bdSDeclan Doherty &option_index)) != EOF) { 1626387259bdSDeclan Doherty switch (opt) { 1627387259bdSDeclan Doherty /* long options */ 1628387259bdSDeclan Doherty case 0: 1629387259bdSDeclan Doherty retval = l2fwd_crypto_parse_args_long_options(options, 1630387259bdSDeclan Doherty lgopts, option_index); 1631387259bdSDeclan Doherty if (retval < 0) { 1632387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1633387259bdSDeclan Doherty return -1; 1634387259bdSDeclan Doherty } 1635387259bdSDeclan Doherty break; 1636387259bdSDeclan Doherty 1637387259bdSDeclan Doherty /* portmask */ 1638387259bdSDeclan Doherty case 'p': 1639387259bdSDeclan Doherty retval = l2fwd_crypto_parse_portmask(options, optarg); 1640387259bdSDeclan Doherty if (retval < 0) { 1641387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1642387259bdSDeclan Doherty return -1; 1643387259bdSDeclan Doherty } 1644387259bdSDeclan Doherty break; 1645387259bdSDeclan Doherty 1646387259bdSDeclan Doherty /* nqueue */ 1647387259bdSDeclan Doherty case 'q': 1648387259bdSDeclan Doherty retval = l2fwd_crypto_parse_nqueue(options, optarg); 1649387259bdSDeclan Doherty if (retval < 0) { 1650387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1651387259bdSDeclan Doherty return -1; 1652387259bdSDeclan Doherty } 1653387259bdSDeclan Doherty break; 1654387259bdSDeclan Doherty 1655387259bdSDeclan Doherty /* single */ 1656387259bdSDeclan Doherty case 's': 1657387259bdSDeclan Doherty options->single_lcore = 1; 1658387259bdSDeclan Doherty 1659387259bdSDeclan Doherty break; 1660387259bdSDeclan Doherty 1661387259bdSDeclan Doherty /* timer period */ 1662a3380989SPablo de Lara case 'T': 1663387259bdSDeclan Doherty retval = l2fwd_crypto_parse_timer_period(options, 1664387259bdSDeclan Doherty optarg); 1665387259bdSDeclan Doherty if (retval < 0) { 1666387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1667387259bdSDeclan Doherty return -1; 1668387259bdSDeclan Doherty } 1669387259bdSDeclan Doherty break; 1670387259bdSDeclan Doherty 1671387259bdSDeclan Doherty default: 1672387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1673387259bdSDeclan Doherty return -1; 1674387259bdSDeclan Doherty } 1675387259bdSDeclan Doherty } 1676387259bdSDeclan Doherty 1677387259bdSDeclan Doherty 1678387259bdSDeclan Doherty if (optind >= 0) 1679387259bdSDeclan Doherty argv[optind-1] = prgname; 1680387259bdSDeclan Doherty 1681387259bdSDeclan Doherty retval = optind-1; 16829d5ca532SKeith Wiles optind = 1; /* reset getopt lib */ 1683387259bdSDeclan Doherty 1684387259bdSDeclan Doherty return retval; 1685387259bdSDeclan Doherty } 1686387259bdSDeclan Doherty 1687387259bdSDeclan Doherty /* Check the link status of all ports in up to 9s, and print them finally */ 1688387259bdSDeclan Doherty static void 1689387259bdSDeclan Doherty check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) 1690387259bdSDeclan Doherty { 1691387259bdSDeclan Doherty #define CHECK_INTERVAL 100 /* 100ms */ 1692387259bdSDeclan Doherty #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1693387259bdSDeclan Doherty uint8_t portid, count, all_ports_up, print_flag = 0; 1694387259bdSDeclan Doherty struct rte_eth_link link; 1695387259bdSDeclan Doherty 1696387259bdSDeclan Doherty printf("\nChecking link status"); 1697387259bdSDeclan Doherty fflush(stdout); 1698387259bdSDeclan Doherty for (count = 0; count <= MAX_CHECK_TIME; count++) { 1699387259bdSDeclan Doherty all_ports_up = 1; 1700387259bdSDeclan Doherty for (portid = 0; portid < port_num; portid++) { 1701387259bdSDeclan Doherty if ((port_mask & (1 << portid)) == 0) 1702387259bdSDeclan Doherty continue; 1703387259bdSDeclan Doherty memset(&link, 0, sizeof(link)); 1704387259bdSDeclan Doherty rte_eth_link_get_nowait(portid, &link); 1705387259bdSDeclan Doherty /* print link status if flag set */ 1706387259bdSDeclan Doherty if (print_flag == 1) { 1707387259bdSDeclan Doherty if (link.link_status) 1708387259bdSDeclan Doherty printf("Port %d Link Up - speed %u " 1709387259bdSDeclan Doherty "Mbps - %s\n", (uint8_t)portid, 1710387259bdSDeclan Doherty (unsigned)link.link_speed, 1711387259bdSDeclan Doherty (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1712387259bdSDeclan Doherty ("full-duplex") : ("half-duplex\n")); 1713387259bdSDeclan Doherty else 1714387259bdSDeclan Doherty printf("Port %d Link Down\n", 1715387259bdSDeclan Doherty (uint8_t)portid); 1716387259bdSDeclan Doherty continue; 1717387259bdSDeclan Doherty } 1718387259bdSDeclan Doherty /* clear all_ports_up flag if any link down */ 171909419f23SThomas Monjalon if (link.link_status == ETH_LINK_DOWN) { 1720387259bdSDeclan Doherty all_ports_up = 0; 1721387259bdSDeclan Doherty break; 1722387259bdSDeclan Doherty } 1723387259bdSDeclan Doherty } 1724387259bdSDeclan Doherty /* after finally printing all link status, get out */ 1725387259bdSDeclan Doherty if (print_flag == 1) 1726387259bdSDeclan Doherty break; 1727387259bdSDeclan Doherty 1728387259bdSDeclan Doherty if (all_ports_up == 0) { 1729387259bdSDeclan Doherty printf("."); 1730387259bdSDeclan Doherty fflush(stdout); 1731387259bdSDeclan Doherty rte_delay_ms(CHECK_INTERVAL); 1732387259bdSDeclan Doherty } 1733387259bdSDeclan Doherty 1734387259bdSDeclan Doherty /* set the print_flag if all ports up or timeout */ 1735387259bdSDeclan Doherty if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1736387259bdSDeclan Doherty print_flag = 1; 1737387259bdSDeclan Doherty printf("done\n"); 1738387259bdSDeclan Doherty } 1739387259bdSDeclan Doherty } 1740387259bdSDeclan Doherty } 1741387259bdSDeclan Doherty 174227cf2d1bSPablo de Lara /* Check if device has to be HW/SW or any */ 1743387259bdSDeclan Doherty static int 17444baea68dSPablo de Lara check_type(const struct l2fwd_crypto_options *options, 17454baea68dSPablo de Lara const struct rte_cryptodev_info *dev_info) 174627cf2d1bSPablo de Lara { 174727cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_HW && 174827cf2d1bSPablo de Lara (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 174927cf2d1bSPablo de Lara return 0; 175027cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_SW && 175127cf2d1bSPablo de Lara !(dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 175227cf2d1bSPablo de Lara return 0; 175327cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_ANY) 175427cf2d1bSPablo de Lara return 0; 175527cf2d1bSPablo de Lara 175627cf2d1bSPablo de Lara return -1; 175727cf2d1bSPablo de Lara } 175827cf2d1bSPablo de Lara 17594baea68dSPablo de Lara static const struct rte_cryptodev_capabilities * 17604baea68dSPablo de Lara check_device_support_cipher_algo(const struct l2fwd_crypto_options *options, 17614baea68dSPablo de Lara const struct rte_cryptodev_info *dev_info, 17624baea68dSPablo de Lara uint8_t cdev_id) 17634baea68dSPablo de Lara { 17644baea68dSPablo de Lara unsigned int i = 0; 17654baea68dSPablo de Lara const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 17664baea68dSPablo de Lara enum rte_crypto_cipher_algorithm cap_cipher_algo; 17674baea68dSPablo de Lara enum rte_crypto_cipher_algorithm opt_cipher_algo = 17684baea68dSPablo de Lara options->cipher_xform.cipher.algo; 17694baea68dSPablo de Lara 17704baea68dSPablo de Lara while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 17714baea68dSPablo de Lara cap_cipher_algo = cap->sym.cipher.algo; 17724baea68dSPablo de Lara if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 17734baea68dSPablo de Lara if (cap_cipher_algo == opt_cipher_algo) { 17744baea68dSPablo de Lara if (check_type(options, dev_info) == 0) 17754baea68dSPablo de Lara break; 17764baea68dSPablo de Lara } 17774baea68dSPablo de Lara } 17784baea68dSPablo de Lara cap = &dev_info->capabilities[++i]; 17794baea68dSPablo de Lara } 17804baea68dSPablo de Lara 17814baea68dSPablo de Lara if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 17824baea68dSPablo de Lara printf("Algorithm %s not supported by cryptodev %u" 17834baea68dSPablo de Lara " or device not of preferred type (%s)\n", 17844baea68dSPablo de Lara rte_crypto_cipher_algorithm_strings[opt_cipher_algo], 17854baea68dSPablo de Lara cdev_id, 17864baea68dSPablo de Lara options->string_type); 17874baea68dSPablo de Lara return NULL; 17884baea68dSPablo de Lara } 17894baea68dSPablo de Lara 17904baea68dSPablo de Lara return cap; 17914baea68dSPablo de Lara } 17924baea68dSPablo de Lara 17934baea68dSPablo de Lara static const struct rte_cryptodev_capabilities * 17944baea68dSPablo de Lara check_device_support_auth_algo(const struct l2fwd_crypto_options *options, 17954baea68dSPablo de Lara const struct rte_cryptodev_info *dev_info, 17964baea68dSPablo de Lara uint8_t cdev_id) 17974baea68dSPablo de Lara { 17984baea68dSPablo de Lara unsigned int i = 0; 17994baea68dSPablo de Lara const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 18004baea68dSPablo de Lara enum rte_crypto_auth_algorithm cap_auth_algo; 18014baea68dSPablo de Lara enum rte_crypto_auth_algorithm opt_auth_algo = 18024baea68dSPablo de Lara options->auth_xform.auth.algo; 18034baea68dSPablo de Lara 18044baea68dSPablo de Lara while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 18054baea68dSPablo de Lara cap_auth_algo = cap->sym.auth.algo; 18064baea68dSPablo de Lara if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) { 18074baea68dSPablo de Lara if (cap_auth_algo == opt_auth_algo) { 18084baea68dSPablo de Lara if (check_type(options, dev_info) == 0) 18094baea68dSPablo de Lara break; 18104baea68dSPablo de Lara } 18114baea68dSPablo de Lara } 18124baea68dSPablo de Lara cap = &dev_info->capabilities[++i]; 18134baea68dSPablo de Lara } 18144baea68dSPablo de Lara 18154baea68dSPablo de Lara if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 18164baea68dSPablo de Lara printf("Algorithm %s not supported by cryptodev %u" 18174baea68dSPablo de Lara " or device not of preferred type (%s)\n", 18184baea68dSPablo de Lara rte_crypto_auth_algorithm_strings[opt_auth_algo], 18194baea68dSPablo de Lara cdev_id, 18204baea68dSPablo de Lara options->string_type); 18214baea68dSPablo de Lara return NULL; 18224baea68dSPablo de Lara } 18234baea68dSPablo de Lara 18244baea68dSPablo de Lara return cap; 18254baea68dSPablo de Lara } 18264baea68dSPablo de Lara 18272661f4fbSPablo de Lara static const struct rte_cryptodev_capabilities * 18282661f4fbSPablo de Lara check_device_support_aead_algo(const struct l2fwd_crypto_options *options, 18292661f4fbSPablo de Lara const struct rte_cryptodev_info *dev_info, 18302661f4fbSPablo de Lara uint8_t cdev_id) 18312661f4fbSPablo de Lara { 18322661f4fbSPablo de Lara unsigned int i = 0; 18332661f4fbSPablo de Lara const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; 18342661f4fbSPablo de Lara enum rte_crypto_aead_algorithm cap_aead_algo; 18352661f4fbSPablo de Lara enum rte_crypto_aead_algorithm opt_aead_algo = 18362661f4fbSPablo de Lara options->aead_xform.aead.algo; 18372661f4fbSPablo de Lara 18382661f4fbSPablo de Lara while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 18392661f4fbSPablo de Lara cap_aead_algo = cap->sym.aead.algo; 18402661f4fbSPablo de Lara if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) { 18412661f4fbSPablo de Lara if (cap_aead_algo == opt_aead_algo) { 18422661f4fbSPablo de Lara if (check_type(options, dev_info) == 0) 18432661f4fbSPablo de Lara break; 18442661f4fbSPablo de Lara } 18452661f4fbSPablo de Lara } 18462661f4fbSPablo de Lara cap = &dev_info->capabilities[++i]; 18472661f4fbSPablo de Lara } 18482661f4fbSPablo de Lara 18492661f4fbSPablo de Lara if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 18502661f4fbSPablo de Lara printf("Algorithm %s not supported by cryptodev %u" 18512661f4fbSPablo de Lara " or device not of preferred type (%s)\n", 18522661f4fbSPablo de Lara rte_crypto_aead_algorithm_strings[opt_aead_algo], 18532661f4fbSPablo de Lara cdev_id, 18542661f4fbSPablo de Lara options->string_type); 18552661f4fbSPablo de Lara return NULL; 18562661f4fbSPablo de Lara } 18572661f4fbSPablo de Lara 18582661f4fbSPablo de Lara return cap; 18592661f4fbSPablo de Lara } 18602661f4fbSPablo de Lara 1861d2797f51SFan Zhang /* Check if the device is enabled by cryptodev_mask */ 1862d2797f51SFan Zhang static int 1863d2797f51SFan Zhang check_cryptodev_mask(struct l2fwd_crypto_options *options, 1864d2797f51SFan Zhang uint8_t cdev_id) 1865d2797f51SFan Zhang { 1866d2797f51SFan Zhang if (options->cryptodev_mask & (1 << cdev_id)) 1867d2797f51SFan Zhang return 0; 1868d2797f51SFan Zhang 1869d2797f51SFan Zhang return -1; 1870d2797f51SFan Zhang } 1871d2797f51SFan Zhang 1872a061e50aSPablo de Lara static inline int 1873a061e50aSPablo de Lara check_supported_size(uint16_t length, uint16_t min, uint16_t max, 1874a061e50aSPablo de Lara uint16_t increment) 1875a061e50aSPablo de Lara { 1876a061e50aSPablo de Lara uint16_t supp_size; 1877a061e50aSPablo de Lara 187837ebd9e1SPablo de Lara /* Single value */ 187937ebd9e1SPablo de Lara if (increment == 0) { 188037ebd9e1SPablo de Lara if (length == min) 188137ebd9e1SPablo de Lara return 0; 188237ebd9e1SPablo de Lara else 188337ebd9e1SPablo de Lara return -1; 188437ebd9e1SPablo de Lara } 188537ebd9e1SPablo de Lara 188637ebd9e1SPablo de Lara /* Range of values */ 1887a061e50aSPablo de Lara for (supp_size = min; supp_size <= max; supp_size += increment) { 1888a061e50aSPablo de Lara if (length == supp_size) 1889a061e50aSPablo de Lara return 0; 1890a061e50aSPablo de Lara } 1891a061e50aSPablo de Lara 1892a061e50aSPablo de Lara return -1; 1893a061e50aSPablo de Lara } 18940fbd75a9SPablo de Lara 18950fbd75a9SPablo de Lara static int 18960fbd75a9SPablo de Lara check_iv_param(const struct rte_crypto_param_range *iv_range_size, 18970fbd75a9SPablo de Lara unsigned int iv_param, int iv_random_size, 18980fbd75a9SPablo de Lara uint16_t *iv_length) 18990fbd75a9SPablo de Lara { 19000fbd75a9SPablo de Lara /* 19010fbd75a9SPablo de Lara * Check if length of provided IV is supported 19020fbd75a9SPablo de Lara * by the algorithm chosen. 19030fbd75a9SPablo de Lara */ 19040fbd75a9SPablo de Lara if (iv_param) { 19050fbd75a9SPablo de Lara if (check_supported_size(*iv_length, 19060fbd75a9SPablo de Lara iv_range_size->min, 19070fbd75a9SPablo de Lara iv_range_size->max, 19080fbd75a9SPablo de Lara iv_range_size->increment) 19090fbd75a9SPablo de Lara != 0) { 19100fbd75a9SPablo de Lara printf("Unsupported IV length\n"); 19110fbd75a9SPablo de Lara return -1; 19120fbd75a9SPablo de Lara } 19130fbd75a9SPablo de Lara /* 19140fbd75a9SPablo de Lara * Check if length of IV to be randomly generated 19150fbd75a9SPablo de Lara * is supported by the algorithm chosen. 19160fbd75a9SPablo de Lara */ 19170fbd75a9SPablo de Lara } else if (iv_random_size != -1) { 19180fbd75a9SPablo de Lara if (check_supported_size(iv_random_size, 19190fbd75a9SPablo de Lara iv_range_size->min, 19200fbd75a9SPablo de Lara iv_range_size->max, 19210fbd75a9SPablo de Lara iv_range_size->increment) 19220fbd75a9SPablo de Lara != 0) { 19230fbd75a9SPablo de Lara printf("Unsupported IV length\n"); 19240fbd75a9SPablo de Lara return -1; 19250fbd75a9SPablo de Lara } 19260fbd75a9SPablo de Lara *iv_length = iv_random_size; 19270fbd75a9SPablo de Lara /* No size provided, use minimum size. */ 19280fbd75a9SPablo de Lara } else 19290fbd75a9SPablo de Lara *iv_length = iv_range_size->min; 19300fbd75a9SPablo de Lara 19310fbd75a9SPablo de Lara return 0; 19320fbd75a9SPablo de Lara } 19330fbd75a9SPablo de Lara 193427cf2d1bSPablo de Lara static int 193527cf2d1bSPablo de Lara initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, 193627cf2d1bSPablo de Lara uint8_t *enabled_cdevs) 1937387259bdSDeclan Doherty { 19384baea68dSPablo de Lara unsigned int cdev_id, cdev_count, enabled_cdev_count = 0; 193927cf2d1bSPablo de Lara const struct rte_cryptodev_capabilities *cap; 19402c59bd32SSlawomir Mrozowicz unsigned int sess_sz, max_sess_sz = 0; 1941387259bdSDeclan Doherty int retval; 1942387259bdSDeclan Doherty 194327cf2d1bSPablo de Lara cdev_count = rte_cryptodev_count(); 194427cf2d1bSPablo de Lara if (cdev_count == 0) { 194527cf2d1bSPablo de Lara printf("No crypto devices available\n"); 1946387259bdSDeclan Doherty return -1; 1947387259bdSDeclan Doherty } 1948387259bdSDeclan Doherty 19492c59bd32SSlawomir Mrozowicz for (cdev_id = 0; cdev_id < cdev_count; cdev_id++) { 1950*b3bbd9e5SSlawomir Mrozowicz sess_sz = rte_cryptodev_get_private_session_size(cdev_id); 19512c59bd32SSlawomir Mrozowicz if (sess_sz > max_sess_sz) 19522c59bd32SSlawomir Mrozowicz max_sess_sz = sess_sz; 19532c59bd32SSlawomir Mrozowicz } 19542c59bd32SSlawomir Mrozowicz 195527cf2d1bSPablo de Lara for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports; 1956387259bdSDeclan Doherty cdev_id++) { 1957387259bdSDeclan Doherty struct rte_cryptodev_qp_conf qp_conf; 1958387259bdSDeclan Doherty struct rte_cryptodev_info dev_info; 19592c59bd32SSlawomir Mrozowicz uint8_t socket_id = rte_cryptodev_socket_id(cdev_id); 1960387259bdSDeclan Doherty 1961387259bdSDeclan Doherty struct rte_cryptodev_config conf = { 1962387259bdSDeclan Doherty .nb_queue_pairs = 1, 19632c59bd32SSlawomir Mrozowicz .socket_id = socket_id, 1964387259bdSDeclan Doherty }; 1965387259bdSDeclan Doherty 1966d2797f51SFan Zhang if (check_cryptodev_mask(options, (uint8_t)cdev_id)) 1967d2797f51SFan Zhang continue; 1968d2797f51SFan Zhang 1969387259bdSDeclan Doherty rte_cryptodev_info_get(cdev_id, &dev_info); 1970387259bdSDeclan Doherty 19712c59bd32SSlawomir Mrozowicz if (session_pool_socket[socket_id] == NULL) { 19722c59bd32SSlawomir Mrozowicz char mp_name[RTE_MEMPOOL_NAMESIZE]; 19732c59bd32SSlawomir Mrozowicz struct rte_mempool *sess_mp; 19742c59bd32SSlawomir Mrozowicz 19752c59bd32SSlawomir Mrozowicz snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, 19762c59bd32SSlawomir Mrozowicz "sess_mp_%u", socket_id); 19772c59bd32SSlawomir Mrozowicz 19782c59bd32SSlawomir Mrozowicz /* 19792c59bd32SSlawomir Mrozowicz * Create enough objects for session headers and 19802c59bd32SSlawomir Mrozowicz * device private data 19812c59bd32SSlawomir Mrozowicz */ 19822c59bd32SSlawomir Mrozowicz sess_mp = rte_mempool_create(mp_name, 19832c59bd32SSlawomir Mrozowicz MAX_SESSIONS * 2, 19842c59bd32SSlawomir Mrozowicz max_sess_sz, 19852c59bd32SSlawomir Mrozowicz SESSION_POOL_CACHE_SIZE, 19862c59bd32SSlawomir Mrozowicz 0, NULL, NULL, NULL, 19872c59bd32SSlawomir Mrozowicz NULL, socket_id, 19882c59bd32SSlawomir Mrozowicz 0); 19892c59bd32SSlawomir Mrozowicz 19902c59bd32SSlawomir Mrozowicz if (sess_mp == NULL) { 19912c59bd32SSlawomir Mrozowicz printf("Cannot create session pool on socket %d\n", 19922c59bd32SSlawomir Mrozowicz socket_id); 19932c59bd32SSlawomir Mrozowicz return -ENOMEM; 19942c59bd32SSlawomir Mrozowicz } 19952c59bd32SSlawomir Mrozowicz 19962c59bd32SSlawomir Mrozowicz printf("Allocated session pool on socket %d\n", socket_id); 19972c59bd32SSlawomir Mrozowicz session_pool_socket[socket_id] = sess_mp; 19982c59bd32SSlawomir Mrozowicz } 19992c59bd32SSlawomir Mrozowicz 20002661f4fbSPablo de Lara /* Set AEAD parameters */ 20012661f4fbSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_AEAD) { 20022661f4fbSPablo de Lara /* Check if device supports AEAD algo */ 20032661f4fbSPablo de Lara cap = check_device_support_aead_algo(options, &dev_info, 20042661f4fbSPablo de Lara cdev_id); 20052661f4fbSPablo de Lara if (cap == NULL) 20062661f4fbSPablo de Lara continue; 20072661f4fbSPablo de Lara 20082661f4fbSPablo de Lara options->block_size = cap->sym.aead.block_size; 20092661f4fbSPablo de Lara 20102661f4fbSPablo de Lara check_iv_param(&cap->sym.aead.iv_size, 20112661f4fbSPablo de Lara options->aead_iv_param, 20122661f4fbSPablo de Lara options->aead_iv_random_size, 20132661f4fbSPablo de Lara &options->aead_iv.length); 20142661f4fbSPablo de Lara 20152661f4fbSPablo de Lara /* 20162661f4fbSPablo de Lara * Check if length of provided AEAD key is supported 20172661f4fbSPablo de Lara * by the algorithm chosen. 20182661f4fbSPablo de Lara */ 20192661f4fbSPablo de Lara if (options->aead_key_param) { 20202661f4fbSPablo de Lara if (check_supported_size( 20212661f4fbSPablo de Lara options->aead_xform.aead.key.length, 20222661f4fbSPablo de Lara cap->sym.aead.key_size.min, 20232661f4fbSPablo de Lara cap->sym.aead.key_size.max, 20242661f4fbSPablo de Lara cap->sym.aead.key_size.increment) 20252661f4fbSPablo de Lara != 0) { 20262661f4fbSPablo de Lara printf("Unsupported aead key length\n"); 20272661f4fbSPablo de Lara return -1; 20282661f4fbSPablo de Lara } 20292661f4fbSPablo de Lara /* 20302661f4fbSPablo de Lara * Check if length of the aead key to be randomly generated 20312661f4fbSPablo de Lara * is supported by the algorithm chosen. 20322661f4fbSPablo de Lara */ 20332661f4fbSPablo de Lara } else if (options->aead_key_random_size != -1) { 20342661f4fbSPablo de Lara if (check_supported_size(options->ckey_random_size, 20352661f4fbSPablo de Lara cap->sym.aead.key_size.min, 20362661f4fbSPablo de Lara cap->sym.aead.key_size.max, 20372661f4fbSPablo de Lara cap->sym.aead.key_size.increment) 20382661f4fbSPablo de Lara != 0) { 20392661f4fbSPablo de Lara printf("Unsupported aead key length\n"); 20402661f4fbSPablo de Lara return -1; 20412661f4fbSPablo de Lara } 20422661f4fbSPablo de Lara options->aead_xform.aead.key.length = 20432661f4fbSPablo de Lara options->ckey_random_size; 20442661f4fbSPablo de Lara /* No size provided, use minimum size. */ 20452661f4fbSPablo de Lara } else 20462661f4fbSPablo de Lara options->aead_xform.aead.key.length = 20472661f4fbSPablo de Lara cap->sym.aead.key_size.min; 20482661f4fbSPablo de Lara 20492661f4fbSPablo de Lara if (!options->aead_key_param) 20502661f4fbSPablo de Lara generate_random_key( 20512661f4fbSPablo de Lara options->aead_xform.aead.key.data, 20522661f4fbSPablo de Lara options->aead_xform.aead.key.length); 20532661f4fbSPablo de Lara 20542661f4fbSPablo de Lara /* 20552661f4fbSPablo de Lara * Check if length of provided AAD is supported 20562661f4fbSPablo de Lara * by the algorithm chosen. 20572661f4fbSPablo de Lara */ 20582661f4fbSPablo de Lara if (options->aad_param) { 20592661f4fbSPablo de Lara if (check_supported_size(options->aad.length, 20602661f4fbSPablo de Lara cap->sym.aead.aad_size.min, 20612661f4fbSPablo de Lara cap->sym.aead.aad_size.max, 20622661f4fbSPablo de Lara cap->sym.aead.aad_size.increment) 20632661f4fbSPablo de Lara != 0) { 20642661f4fbSPablo de Lara printf("Unsupported AAD length\n"); 20652661f4fbSPablo de Lara return -1; 20662661f4fbSPablo de Lara } 20672661f4fbSPablo de Lara /* 20682661f4fbSPablo de Lara * Check if length of AAD to be randomly generated 20692661f4fbSPablo de Lara * is supported by the algorithm chosen. 20702661f4fbSPablo de Lara */ 20712661f4fbSPablo de Lara } else if (options->aad_random_size != -1) { 20722661f4fbSPablo de Lara if (check_supported_size(options->aad_random_size, 20732661f4fbSPablo de Lara cap->sym.aead.aad_size.min, 20742661f4fbSPablo de Lara cap->sym.aead.aad_size.max, 20752661f4fbSPablo de Lara cap->sym.aead.aad_size.increment) 20762661f4fbSPablo de Lara != 0) { 20772661f4fbSPablo de Lara printf("Unsupported AAD length\n"); 20782661f4fbSPablo de Lara return -1; 20792661f4fbSPablo de Lara } 20802661f4fbSPablo de Lara options->aad.length = options->aad_random_size; 20812661f4fbSPablo de Lara /* No size provided, use minimum size. */ 20822661f4fbSPablo de Lara } else 20832661f4fbSPablo de Lara options->aad.length = cap->sym.auth.aad_size.min; 20842661f4fbSPablo de Lara 20852661f4fbSPablo de Lara options->aead_xform.aead.add_auth_data_length = 20862661f4fbSPablo de Lara options->aad.length; 20872661f4fbSPablo de Lara 20882661f4fbSPablo de Lara /* Check if digest size is supported by the algorithm. */ 20892661f4fbSPablo de Lara if (options->digest_size != -1) { 20902661f4fbSPablo de Lara if (check_supported_size(options->digest_size, 20912661f4fbSPablo de Lara cap->sym.aead.digest_size.min, 20922661f4fbSPablo de Lara cap->sym.aead.digest_size.max, 20932661f4fbSPablo de Lara cap->sym.aead.digest_size.increment) 20942661f4fbSPablo de Lara != 0) { 20952661f4fbSPablo de Lara printf("Unsupported digest length\n"); 20962661f4fbSPablo de Lara return -1; 20972661f4fbSPablo de Lara } 20982661f4fbSPablo de Lara options->aead_xform.aead.digest_length = 20992661f4fbSPablo de Lara options->digest_size; 21002661f4fbSPablo de Lara /* No size provided, use minimum size. */ 21012661f4fbSPablo de Lara } else 21022661f4fbSPablo de Lara options->aead_xform.aead.digest_length = 21032661f4fbSPablo de Lara cap->sym.aead.digest_size.min; 21042661f4fbSPablo de Lara } 21052661f4fbSPablo de Lara 210627cf2d1bSPablo de Lara /* Set cipher parameters */ 210727cf2d1bSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 210827cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 210927cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 211027cf2d1bSPablo de Lara /* Check if device supports cipher algo */ 21114baea68dSPablo de Lara cap = check_device_support_cipher_algo(options, &dev_info, 21124baea68dSPablo de Lara cdev_id); 21134baea68dSPablo de Lara if (cap == NULL) 211427cf2d1bSPablo de Lara continue; 211527cf2d1bSPablo de Lara 211627cf2d1bSPablo de Lara options->block_size = cap->sym.cipher.block_size; 21170fbd75a9SPablo de Lara 2118acf86169SPablo de Lara check_iv_param(&cap->sym.cipher.iv_size, 2119acf86169SPablo de Lara options->cipher_iv_param, 2120acf86169SPablo de Lara options->cipher_iv_random_size, 2121acf86169SPablo de Lara &options->cipher_iv.length); 2122a061e50aSPablo de Lara 2123a061e50aSPablo de Lara /* 2124a061e50aSPablo de Lara * Check if length of provided cipher key is supported 2125a061e50aSPablo de Lara * by the algorithm chosen. 2126a061e50aSPablo de Lara */ 2127a061e50aSPablo de Lara if (options->ckey_param) { 2128a061e50aSPablo de Lara if (check_supported_size( 2129a061e50aSPablo de Lara options->cipher_xform.cipher.key.length, 2130a061e50aSPablo de Lara cap->sym.cipher.key_size.min, 2131a061e50aSPablo de Lara cap->sym.cipher.key_size.max, 2132a061e50aSPablo de Lara cap->sym.cipher.key_size.increment) 2133a061e50aSPablo de Lara != 0) { 2134a061e50aSPablo de Lara printf("Unsupported cipher key length\n"); 2135a061e50aSPablo de Lara return -1; 2136a061e50aSPablo de Lara } 2137a061e50aSPablo de Lara /* 2138a061e50aSPablo de Lara * Check if length of the cipher key to be randomly generated 2139a061e50aSPablo de Lara * is supported by the algorithm chosen. 2140a061e50aSPablo de Lara */ 2141a061e50aSPablo de Lara } else if (options->ckey_random_size != -1) { 2142a061e50aSPablo de Lara if (check_supported_size(options->ckey_random_size, 2143a061e50aSPablo de Lara cap->sym.cipher.key_size.min, 2144a061e50aSPablo de Lara cap->sym.cipher.key_size.max, 2145a061e50aSPablo de Lara cap->sym.cipher.key_size.increment) 2146a061e50aSPablo de Lara != 0) { 2147a061e50aSPablo de Lara printf("Unsupported cipher key length\n"); 2148a061e50aSPablo de Lara return -1; 2149a061e50aSPablo de Lara } 2150a061e50aSPablo de Lara options->cipher_xform.cipher.key.length = 2151a061e50aSPablo de Lara options->ckey_random_size; 2152a061e50aSPablo de Lara /* No size provided, use minimum size. */ 2153a061e50aSPablo de Lara } else 215427cf2d1bSPablo de Lara options->cipher_xform.cipher.key.length = 215527cf2d1bSPablo de Lara cap->sym.cipher.key_size.min; 2156a061e50aSPablo de Lara 215727cf2d1bSPablo de Lara if (!options->ckey_param) 215827cf2d1bSPablo de Lara generate_random_key( 215927cf2d1bSPablo de Lara options->cipher_xform.cipher.key.data, 216027cf2d1bSPablo de Lara options->cipher_xform.cipher.key.length); 216127cf2d1bSPablo de Lara 216227cf2d1bSPablo de Lara } 216327cf2d1bSPablo de Lara 216427cf2d1bSPablo de Lara /* Set auth parameters */ 216527cf2d1bSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 216627cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 216727cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { 216827cf2d1bSPablo de Lara /* Check if device supports auth algo */ 21694baea68dSPablo de Lara cap = check_device_support_auth_algo(options, &dev_info, 21704baea68dSPablo de Lara cdev_id); 21714baea68dSPablo de Lara if (cap == NULL) 217227cf2d1bSPablo de Lara continue; 217327cf2d1bSPablo de Lara 2174acf86169SPablo de Lara check_iv_param(&cap->sym.auth.iv_size, 2175acf86169SPablo de Lara options->auth_iv_param, 2176acf86169SPablo de Lara options->auth_iv_random_size, 2177acf86169SPablo de Lara &options->auth_iv.length); 2178a061e50aSPablo de Lara /* 2179a061e50aSPablo de Lara * Check if length of provided auth key is supported 2180a061e50aSPablo de Lara * by the algorithm chosen. 2181a061e50aSPablo de Lara */ 2182a061e50aSPablo de Lara if (options->akey_param) { 2183a061e50aSPablo de Lara if (check_supported_size( 2184a061e50aSPablo de Lara options->auth_xform.auth.key.length, 2185a061e50aSPablo de Lara cap->sym.auth.key_size.min, 2186a061e50aSPablo de Lara cap->sym.auth.key_size.max, 2187a061e50aSPablo de Lara cap->sym.auth.key_size.increment) 2188a061e50aSPablo de Lara != 0) { 2189a061e50aSPablo de Lara printf("Unsupported auth key length\n"); 2190a061e50aSPablo de Lara return -1; 2191a061e50aSPablo de Lara } 2192a061e50aSPablo de Lara /* 2193a061e50aSPablo de Lara * Check if length of the auth key to be randomly generated 2194a061e50aSPablo de Lara * is supported by the algorithm chosen. 2195a061e50aSPablo de Lara */ 2196a061e50aSPablo de Lara } else if (options->akey_random_size != -1) { 2197a061e50aSPablo de Lara if (check_supported_size(options->akey_random_size, 2198a061e50aSPablo de Lara cap->sym.auth.key_size.min, 2199a061e50aSPablo de Lara cap->sym.auth.key_size.max, 2200a061e50aSPablo de Lara cap->sym.auth.key_size.increment) 2201a061e50aSPablo de Lara != 0) { 2202a061e50aSPablo de Lara printf("Unsupported auth key length\n"); 2203a061e50aSPablo de Lara return -1; 2204a061e50aSPablo de Lara } 2205a061e50aSPablo de Lara options->auth_xform.auth.key.length = 2206a061e50aSPablo de Lara options->akey_random_size; 2207a061e50aSPablo de Lara /* No size provided, use minimum size. */ 2208a061e50aSPablo de Lara } else 220927cf2d1bSPablo de Lara options->auth_xform.auth.key.length = 221027cf2d1bSPablo de Lara cap->sym.auth.key_size.min; 221127cf2d1bSPablo de Lara 221227cf2d1bSPablo de Lara if (!options->akey_param) 221327cf2d1bSPablo de Lara generate_random_key( 221427cf2d1bSPablo de Lara options->auth_xform.auth.key.data, 221527cf2d1bSPablo de Lara options->auth_xform.auth.key.length); 2216a061e50aSPablo de Lara 2217a061e50aSPablo de Lara /* Check if digest size is supported by the algorithm. */ 2218a061e50aSPablo de Lara if (options->digest_size != -1) { 2219a061e50aSPablo de Lara if (check_supported_size(options->digest_size, 2220a061e50aSPablo de Lara cap->sym.auth.digest_size.min, 2221a061e50aSPablo de Lara cap->sym.auth.digest_size.max, 2222a061e50aSPablo de Lara cap->sym.auth.digest_size.increment) 2223a061e50aSPablo de Lara != 0) { 2224a061e50aSPablo de Lara printf("Unsupported digest length\n"); 2225a061e50aSPablo de Lara return -1; 2226a061e50aSPablo de Lara } 2227a061e50aSPablo de Lara options->auth_xform.auth.digest_length = 2228a061e50aSPablo de Lara options->digest_size; 2229a061e50aSPablo de Lara /* No size provided, use minimum size. */ 2230a061e50aSPablo de Lara } else 2231a061e50aSPablo de Lara options->auth_xform.auth.digest_length = 2232a061e50aSPablo de Lara cap->sym.auth.digest_size.min; 223327cf2d1bSPablo de Lara } 2234387259bdSDeclan Doherty 22352c59bd32SSlawomir Mrozowicz retval = rte_cryptodev_configure(cdev_id, &conf, 22362c59bd32SSlawomir Mrozowicz session_pool_socket[socket_id]); 2237387259bdSDeclan Doherty if (retval < 0) { 2238387259bdSDeclan Doherty printf("Failed to configure cryptodev %u", cdev_id); 2239387259bdSDeclan Doherty return -1; 2240387259bdSDeclan Doherty } 2241387259bdSDeclan Doherty 2242387259bdSDeclan Doherty qp_conf.nb_descriptors = 2048; 2243387259bdSDeclan Doherty 2244387259bdSDeclan Doherty retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, 22452c59bd32SSlawomir Mrozowicz socket_id); 2246387259bdSDeclan Doherty if (retval < 0) { 2247387259bdSDeclan Doherty printf("Failed to setup queue pair %u on cryptodev %u", 2248387259bdSDeclan Doherty 0, cdev_id); 2249387259bdSDeclan Doherty return -1; 2250387259bdSDeclan Doherty } 2251387259bdSDeclan Doherty 2252800386e6SHemant Agrawal retval = rte_cryptodev_start(cdev_id); 2253800386e6SHemant Agrawal if (retval < 0) { 2254800386e6SHemant Agrawal printf("Failed to start device %u: error %d\n", 2255800386e6SHemant Agrawal cdev_id, retval); 2256800386e6SHemant Agrawal return -1; 2257800386e6SHemant Agrawal } 2258800386e6SHemant Agrawal 2259ad476dd3SPablo de Lara l2fwd_enabled_crypto_mask |= (((uint64_t)1) << cdev_id); 2260387259bdSDeclan Doherty 226127cf2d1bSPablo de Lara enabled_cdevs[cdev_id] = 1; 2262387259bdSDeclan Doherty enabled_cdev_count++; 2263387259bdSDeclan Doherty } 2264387259bdSDeclan Doherty 2265387259bdSDeclan Doherty return enabled_cdev_count; 2266387259bdSDeclan Doherty } 2267387259bdSDeclan Doherty 2268387259bdSDeclan Doherty static int 2269387259bdSDeclan Doherty initialize_ports(struct l2fwd_crypto_options *options) 2270387259bdSDeclan Doherty { 2271387259bdSDeclan Doherty uint8_t last_portid, portid; 2272387259bdSDeclan Doherty unsigned enabled_portcount = 0; 2273387259bdSDeclan Doherty unsigned nb_ports = rte_eth_dev_count(); 2274387259bdSDeclan Doherty 2275387259bdSDeclan Doherty if (nb_ports == 0) { 2276387259bdSDeclan Doherty printf("No Ethernet ports - bye\n"); 2277387259bdSDeclan Doherty return -1; 2278387259bdSDeclan Doherty } 2279387259bdSDeclan Doherty 2280387259bdSDeclan Doherty /* Reset l2fwd_dst_ports */ 2281387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) 2282387259bdSDeclan Doherty l2fwd_dst_ports[portid] = 0; 2283387259bdSDeclan Doherty 2284387259bdSDeclan Doherty for (last_portid = 0, portid = 0; portid < nb_ports; portid++) { 2285387259bdSDeclan Doherty int retval; 2286387259bdSDeclan Doherty 2287387259bdSDeclan Doherty /* Skip ports that are not enabled */ 2288387259bdSDeclan Doherty if ((options->portmask & (1 << portid)) == 0) 2289387259bdSDeclan Doherty continue; 2290387259bdSDeclan Doherty 2291387259bdSDeclan Doherty /* init port */ 2292387259bdSDeclan Doherty printf("Initializing port %u... ", (unsigned) portid); 2293387259bdSDeclan Doherty fflush(stdout); 2294387259bdSDeclan Doherty retval = rte_eth_dev_configure(portid, 1, 1, &port_conf); 2295387259bdSDeclan Doherty if (retval < 0) { 2296387259bdSDeclan Doherty printf("Cannot configure device: err=%d, port=%u\n", 2297387259bdSDeclan Doherty retval, (unsigned) portid); 2298387259bdSDeclan Doherty return -1; 2299387259bdSDeclan Doherty } 2300387259bdSDeclan Doherty 2301387259bdSDeclan Doherty /* init one RX queue */ 2302387259bdSDeclan Doherty fflush(stdout); 2303387259bdSDeclan Doherty retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, 2304387259bdSDeclan Doherty rte_eth_dev_socket_id(portid), 2305387259bdSDeclan Doherty NULL, l2fwd_pktmbuf_pool); 2306387259bdSDeclan Doherty if (retval < 0) { 2307387259bdSDeclan Doherty printf("rte_eth_rx_queue_setup:err=%d, port=%u\n", 2308387259bdSDeclan Doherty retval, (unsigned) portid); 2309387259bdSDeclan Doherty return -1; 2310387259bdSDeclan Doherty } 2311387259bdSDeclan Doherty 2312387259bdSDeclan Doherty /* init one TX queue on each port */ 2313387259bdSDeclan Doherty fflush(stdout); 2314387259bdSDeclan Doherty retval = rte_eth_tx_queue_setup(portid, 0, nb_txd, 2315387259bdSDeclan Doherty rte_eth_dev_socket_id(portid), 2316387259bdSDeclan Doherty NULL); 2317387259bdSDeclan Doherty if (retval < 0) { 2318387259bdSDeclan Doherty printf("rte_eth_tx_queue_setup:err=%d, port=%u\n", 2319387259bdSDeclan Doherty retval, (unsigned) portid); 2320387259bdSDeclan Doherty 2321387259bdSDeclan Doherty return -1; 2322387259bdSDeclan Doherty } 2323387259bdSDeclan Doherty 2324387259bdSDeclan Doherty /* Start device */ 2325387259bdSDeclan Doherty retval = rte_eth_dev_start(portid); 2326387259bdSDeclan Doherty if (retval < 0) { 2327387259bdSDeclan Doherty printf("rte_eth_dev_start:err=%d, port=%u\n", 2328387259bdSDeclan Doherty retval, (unsigned) portid); 2329387259bdSDeclan Doherty return -1; 2330387259bdSDeclan Doherty } 2331387259bdSDeclan Doherty 2332387259bdSDeclan Doherty rte_eth_promiscuous_enable(portid); 2333387259bdSDeclan Doherty 2334387259bdSDeclan Doherty rte_eth_macaddr_get(portid, &l2fwd_ports_eth_addr[portid]); 2335387259bdSDeclan Doherty 2336387259bdSDeclan Doherty printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", 2337387259bdSDeclan Doherty (unsigned) portid, 2338387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[0], 2339387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[1], 2340387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[2], 2341387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[3], 2342387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[4], 2343387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[5]); 2344387259bdSDeclan Doherty 2345387259bdSDeclan Doherty /* initialize port stats */ 2346387259bdSDeclan Doherty memset(&port_statistics, 0, sizeof(port_statistics)); 2347387259bdSDeclan Doherty 2348387259bdSDeclan Doherty /* Setup port forwarding table */ 2349387259bdSDeclan Doherty if (enabled_portcount % 2) { 2350387259bdSDeclan Doherty l2fwd_dst_ports[portid] = last_portid; 2351387259bdSDeclan Doherty l2fwd_dst_ports[last_portid] = portid; 2352387259bdSDeclan Doherty } else { 2353387259bdSDeclan Doherty last_portid = portid; 2354387259bdSDeclan Doherty } 2355387259bdSDeclan Doherty 2356387259bdSDeclan Doherty l2fwd_enabled_port_mask |= (1 << portid); 2357387259bdSDeclan Doherty enabled_portcount++; 2358387259bdSDeclan Doherty } 2359387259bdSDeclan Doherty 2360387259bdSDeclan Doherty if (enabled_portcount == 1) { 2361387259bdSDeclan Doherty l2fwd_dst_ports[last_portid] = last_portid; 2362387259bdSDeclan Doherty } else if (enabled_portcount % 2) { 2363387259bdSDeclan Doherty printf("odd number of ports in portmask- bye\n"); 2364387259bdSDeclan Doherty return -1; 2365387259bdSDeclan Doherty } 2366387259bdSDeclan Doherty 2367387259bdSDeclan Doherty check_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask); 2368387259bdSDeclan Doherty 2369387259bdSDeclan Doherty return enabled_portcount; 2370387259bdSDeclan Doherty } 2371387259bdSDeclan Doherty 23721df9c010SPablo de Lara static void 23731df9c010SPablo de Lara reserve_key_memory(struct l2fwd_crypto_options *options) 23741df9c010SPablo de Lara { 23751df9c010SPablo de Lara options->cipher_xform.cipher.key.data = rte_malloc("crypto key", 23761df9c010SPablo de Lara MAX_KEY_SIZE, 0); 23771df9c010SPablo de Lara if (options->cipher_xform.cipher.key.data == NULL) 23781df9c010SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key"); 23791df9c010SPablo de Lara 23801df9c010SPablo de Lara options->auth_xform.auth.key.data = rte_malloc("auth key", 23811df9c010SPablo de Lara MAX_KEY_SIZE, 0); 23821df9c010SPablo de Lara if (options->auth_xform.auth.key.data == NULL) 23831df9c010SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key"); 23841df9c010SPablo de Lara 23852661f4fbSPablo de Lara options->aead_xform.aead.key.data = rte_malloc("aead key", 23862661f4fbSPablo de Lara MAX_KEY_SIZE, 0); 23872661f4fbSPablo de Lara if (options->aead_xform.aead.key.data == NULL) 23882661f4fbSPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD key"); 23892661f4fbSPablo de Lara 2390acf86169SPablo de Lara options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0); 2391acf86169SPablo de Lara if (options->cipher_iv.data == NULL) 2392acf86169SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher IV"); 2393acf86169SPablo de Lara 2394acf86169SPablo de Lara options->auth_iv.data = rte_malloc("auth iv", MAX_KEY_SIZE, 0); 2395acf86169SPablo de Lara if (options->auth_iv.data == NULL) 2396acf86169SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth IV"); 2397617a7949SPablo de Lara 23982661f4fbSPablo de Lara options->aead_iv.data = rte_malloc("aead_iv", MAX_KEY_SIZE, 0); 23992661f4fbSPablo de Lara if (options->aead_iv.data == NULL) 24002661f4fbSPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv"); 24012661f4fbSPablo de Lara 2402617a7949SPablo de Lara options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); 2403617a7949SPablo de Lara if (options->aad.data == NULL) 2404617a7949SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD"); 2405617a7949SPablo de Lara options->aad.phys_addr = rte_malloc_virt2phy(options->aad.data); 24061df9c010SPablo de Lara } 24071df9c010SPablo de Lara 2408387259bdSDeclan Doherty int 2409387259bdSDeclan Doherty main(int argc, char **argv) 2410387259bdSDeclan Doherty { 2411387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 2412387259bdSDeclan Doherty struct l2fwd_crypto_options options; 2413387259bdSDeclan Doherty 2414387259bdSDeclan Doherty uint8_t nb_ports, nb_cryptodevs, portid, cdev_id; 2415387259bdSDeclan Doherty unsigned lcore_id, rx_lcore_id; 2416387259bdSDeclan Doherty int ret, enabled_cdevcount, enabled_portcount; 241727cf2d1bSPablo de Lara uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS] = {0}; 2418387259bdSDeclan Doherty 2419387259bdSDeclan Doherty /* init EAL */ 2420387259bdSDeclan Doherty ret = rte_eal_init(argc, argv); 2421387259bdSDeclan Doherty if (ret < 0) 2422387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); 2423387259bdSDeclan Doherty argc -= ret; 2424387259bdSDeclan Doherty argv += ret; 2425387259bdSDeclan Doherty 24261df9c010SPablo de Lara /* reserve memory for Cipher/Auth key and IV */ 24271df9c010SPablo de Lara reserve_key_memory(&options); 24281df9c010SPablo de Lara 2429387259bdSDeclan Doherty /* parse application arguments (after the EAL ones) */ 2430387259bdSDeclan Doherty ret = l2fwd_crypto_parse_args(&options, argc, argv); 2431387259bdSDeclan Doherty if (ret < 0) 2432387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Invalid L2FWD-CRYPTO arguments\n"); 2433387259bdSDeclan Doherty 2434387259bdSDeclan Doherty /* create the mbuf pool */ 2435c0f87eb5SDeclan Doherty l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512, 2436c0f87eb5SDeclan Doherty sizeof(struct rte_crypto_op), 2437c0f87eb5SDeclan Doherty RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 2438387259bdSDeclan Doherty if (l2fwd_pktmbuf_pool == NULL) 2439387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); 2440387259bdSDeclan Doherty 2441387259bdSDeclan Doherty /* create crypto op pool */ 2442c0f87eb5SDeclan Doherty l2fwd_crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool", 2443e636243eSPablo de Lara RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, MAXIMUM_IV_LENGTH, 2444c0f87eb5SDeclan Doherty rte_socket_id()); 2445c0f87eb5SDeclan Doherty if (l2fwd_crypto_op_pool == NULL) 2446387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n"); 2447387259bdSDeclan Doherty 2448387259bdSDeclan Doherty /* Enable Ethernet ports */ 2449387259bdSDeclan Doherty enabled_portcount = initialize_ports(&options); 2450387259bdSDeclan Doherty if (enabled_portcount < 1) 2451387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Failed to initial Ethernet ports\n"); 2452387259bdSDeclan Doherty 2453387259bdSDeclan Doherty nb_ports = rte_eth_dev_count(); 2454387259bdSDeclan Doherty /* Initialize the port/queue configuration of each logical core */ 2455387259bdSDeclan Doherty for (rx_lcore_id = 0, qconf = NULL, portid = 0; 2456387259bdSDeclan Doherty portid < nb_ports; portid++) { 2457387259bdSDeclan Doherty 2458387259bdSDeclan Doherty /* skip ports that are not enabled */ 2459387259bdSDeclan Doherty if ((options.portmask & (1 << portid)) == 0) 2460387259bdSDeclan Doherty continue; 2461387259bdSDeclan Doherty 2462387259bdSDeclan Doherty if (options.single_lcore && qconf == NULL) { 2463387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2464387259bdSDeclan Doherty rx_lcore_id++; 2465387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 2466387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 2467387259bdSDeclan Doherty "Not enough cores\n"); 2468387259bdSDeclan Doherty } 2469387259bdSDeclan Doherty } else if (!options.single_lcore) { 2470387259bdSDeclan Doherty /* get the lcore_id for this port */ 2471387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2472387259bdSDeclan Doherty lcore_queue_conf[rx_lcore_id].nb_rx_ports == 2473387259bdSDeclan Doherty options.nb_ports_per_lcore) { 2474387259bdSDeclan Doherty rx_lcore_id++; 2475387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 2476387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 2477387259bdSDeclan Doherty "Not enough cores\n"); 2478387259bdSDeclan Doherty } 2479387259bdSDeclan Doherty } 2480387259bdSDeclan Doherty 2481387259bdSDeclan Doherty /* Assigned a new logical core in the loop above. */ 2482387259bdSDeclan Doherty if (qconf != &lcore_queue_conf[rx_lcore_id]) 2483387259bdSDeclan Doherty qconf = &lcore_queue_conf[rx_lcore_id]; 2484387259bdSDeclan Doherty 2485387259bdSDeclan Doherty qconf->rx_port_list[qconf->nb_rx_ports] = portid; 2486387259bdSDeclan Doherty qconf->nb_rx_ports++; 2487387259bdSDeclan Doherty 2488387259bdSDeclan Doherty printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned)portid); 2489387259bdSDeclan Doherty } 2490387259bdSDeclan Doherty 2491387259bdSDeclan Doherty /* Enable Crypto devices */ 249227cf2d1bSPablo de Lara enabled_cdevcount = initialize_cryptodevs(&options, enabled_portcount, 249327cf2d1bSPablo de Lara enabled_cdevs); 249427cf2d1bSPablo de Lara if (enabled_cdevcount < 0) 249527cf2d1bSPablo de Lara rte_exit(EXIT_FAILURE, "Failed to initialize crypto devices\n"); 249627cf2d1bSPablo de Lara 249727cf2d1bSPablo de Lara if (enabled_cdevcount < enabled_portcount) 249827cf2d1bSPablo de Lara rte_exit(EXIT_FAILURE, "Number of capable crypto devices (%d) " 249927cf2d1bSPablo de Lara "has to be more or equal to number of ports (%d)\n", 250027cf2d1bSPablo de Lara enabled_cdevcount, enabled_portcount); 2501387259bdSDeclan Doherty 2502387259bdSDeclan Doherty nb_cryptodevs = rte_cryptodev_count(); 250327cf2d1bSPablo de Lara 250427cf2d1bSPablo de Lara /* Initialize the port/cryptodev configuration of each logical core */ 2505387259bdSDeclan Doherty for (rx_lcore_id = 0, qconf = NULL, cdev_id = 0; 2506387259bdSDeclan Doherty cdev_id < nb_cryptodevs && enabled_cdevcount; 2507387259bdSDeclan Doherty cdev_id++) { 250827cf2d1bSPablo de Lara /* Crypto op not supported by crypto device */ 250927cf2d1bSPablo de Lara if (!enabled_cdevs[cdev_id]) 2510387259bdSDeclan Doherty continue; 2511387259bdSDeclan Doherty 2512387259bdSDeclan Doherty if (options.single_lcore && qconf == NULL) { 2513387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 2514387259bdSDeclan Doherty rx_lcore_id++; 2515387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 2516387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 2517387259bdSDeclan Doherty "Not enough cores\n"); 2518387259bdSDeclan Doherty } 2519387259bdSDeclan Doherty } else if (!options.single_lcore) { 2520387259bdSDeclan Doherty /* get the lcore_id for this port */ 2521387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 2522387259bdSDeclan Doherty lcore_queue_conf[rx_lcore_id].nb_crypto_devs == 2523387259bdSDeclan Doherty options.nb_ports_per_lcore) { 2524387259bdSDeclan Doherty rx_lcore_id++; 2525387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 2526387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 2527387259bdSDeclan Doherty "Not enough cores\n"); 2528387259bdSDeclan Doherty } 2529387259bdSDeclan Doherty } 2530387259bdSDeclan Doherty 2531387259bdSDeclan Doherty /* Assigned a new logical core in the loop above. */ 2532387259bdSDeclan Doherty if (qconf != &lcore_queue_conf[rx_lcore_id]) 2533387259bdSDeclan Doherty qconf = &lcore_queue_conf[rx_lcore_id]; 2534387259bdSDeclan Doherty 2535387259bdSDeclan Doherty qconf->cryptodev_list[qconf->nb_crypto_devs] = cdev_id; 2536387259bdSDeclan Doherty qconf->nb_crypto_devs++; 2537387259bdSDeclan Doherty 2538387259bdSDeclan Doherty enabled_cdevcount--; 2539387259bdSDeclan Doherty 2540387259bdSDeclan Doherty printf("Lcore %u: cryptodev %u\n", rx_lcore_id, 2541387259bdSDeclan Doherty (unsigned)cdev_id); 2542387259bdSDeclan Doherty } 2543387259bdSDeclan Doherty 2544387259bdSDeclan Doherty /* launch per-lcore init on every lcore */ 2545387259bdSDeclan Doherty rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, (void *)&options, 2546387259bdSDeclan Doherty CALL_MASTER); 2547387259bdSDeclan Doherty RTE_LCORE_FOREACH_SLAVE(lcore_id) { 2548387259bdSDeclan Doherty if (rte_eal_wait_lcore(lcore_id) < 0) 2549387259bdSDeclan Doherty return -1; 2550387259bdSDeclan Doherty } 2551387259bdSDeclan Doherty 2552387259bdSDeclan Doherty return 0; 2553387259bdSDeclan Doherty } 2554