1387259bdSDeclan Doherty /*- 2387259bdSDeclan Doherty * BSD LICENSE 3387259bdSDeclan Doherty * 41bd407faSFiona Trahe * 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> 48387259bdSDeclan Doherty 49387259bdSDeclan Doherty #include <rte_atomic.h> 50387259bdSDeclan Doherty #include <rte_branch_prediction.h> 51387259bdSDeclan Doherty #include <rte_common.h> 52387259bdSDeclan Doherty #include <rte_cryptodev.h> 53387259bdSDeclan Doherty #include <rte_cycles.h> 54387259bdSDeclan Doherty #include <rte_debug.h> 55387259bdSDeclan Doherty #include <rte_eal.h> 56387259bdSDeclan Doherty #include <rte_ether.h> 57387259bdSDeclan Doherty #include <rte_ethdev.h> 58387259bdSDeclan Doherty #include <rte_interrupts.h> 59387259bdSDeclan Doherty #include <rte_ip.h> 60387259bdSDeclan Doherty #include <rte_launch.h> 61387259bdSDeclan Doherty #include <rte_lcore.h> 62387259bdSDeclan Doherty #include <rte_log.h> 63387259bdSDeclan Doherty #include <rte_malloc.h> 64387259bdSDeclan Doherty #include <rte_mbuf.h> 65387259bdSDeclan Doherty #include <rte_memcpy.h> 66387259bdSDeclan Doherty #include <rte_memory.h> 67387259bdSDeclan Doherty #include <rte_mempool.h> 68387259bdSDeclan Doherty #include <rte_memzone.h> 69387259bdSDeclan Doherty #include <rte_pci.h> 70387259bdSDeclan Doherty #include <rte_per_lcore.h> 71387259bdSDeclan Doherty #include <rte_prefetch.h> 72387259bdSDeclan Doherty #include <rte_random.h> 73387259bdSDeclan Doherty #include <rte_ring.h> 74387259bdSDeclan Doherty 7527cf2d1bSPablo de Lara enum cdev_type { 7627cf2d1bSPablo de Lara CDEV_TYPE_ANY, 7727cf2d1bSPablo de Lara CDEV_TYPE_HW, 7827cf2d1bSPablo de Lara CDEV_TYPE_SW 7927cf2d1bSPablo de Lara }; 8027cf2d1bSPablo de Lara 81387259bdSDeclan Doherty #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 82387259bdSDeclan Doherty 83387259bdSDeclan Doherty #define NB_MBUF 8192 84387259bdSDeclan Doherty 8527cf2d1bSPablo de Lara #define MAX_STR_LEN 32 861df9c010SPablo de Lara #define MAX_KEY_SIZE 128 87387259bdSDeclan Doherty #define MAX_PKT_BURST 32 88387259bdSDeclan Doherty #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ 89387259bdSDeclan Doherty 90387259bdSDeclan Doherty /* 91387259bdSDeclan Doherty * Configurable number of RX/TX ring descriptors 92387259bdSDeclan Doherty */ 93387259bdSDeclan Doherty #define RTE_TEST_RX_DESC_DEFAULT 128 94387259bdSDeclan Doherty #define RTE_TEST_TX_DESC_DEFAULT 512 953c96262cSPablo de Lara 96387259bdSDeclan Doherty static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 97387259bdSDeclan Doherty static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; 98387259bdSDeclan Doherty 99387259bdSDeclan Doherty /* ethernet addresses of ports */ 100387259bdSDeclan Doherty static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; 101387259bdSDeclan Doherty 102387259bdSDeclan Doherty /* mask of enabled ports */ 103387259bdSDeclan Doherty static uint64_t l2fwd_enabled_port_mask; 104387259bdSDeclan Doherty static uint64_t l2fwd_enabled_crypto_mask; 105387259bdSDeclan Doherty 106387259bdSDeclan Doherty /* list of enabled ports */ 107387259bdSDeclan Doherty static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; 108387259bdSDeclan Doherty 109387259bdSDeclan Doherty 110387259bdSDeclan Doherty struct pkt_buffer { 111387259bdSDeclan Doherty unsigned len; 112387259bdSDeclan Doherty struct rte_mbuf *buffer[MAX_PKT_BURST]; 113387259bdSDeclan Doherty }; 114387259bdSDeclan Doherty 115c0f87eb5SDeclan Doherty struct op_buffer { 116c0f87eb5SDeclan Doherty unsigned len; 117c0f87eb5SDeclan Doherty struct rte_crypto_op *buffer[MAX_PKT_BURST]; 118c0f87eb5SDeclan Doherty }; 119c0f87eb5SDeclan Doherty 120387259bdSDeclan Doherty #define MAX_RX_QUEUE_PER_LCORE 16 121387259bdSDeclan Doherty #define MAX_TX_QUEUE_PER_PORT 16 122387259bdSDeclan Doherty 123387259bdSDeclan Doherty enum l2fwd_crypto_xform_chain { 124387259bdSDeclan Doherty L2FWD_CRYPTO_CIPHER_HASH, 1251a75e9f3SPablo de Lara L2FWD_CRYPTO_HASH_CIPHER, 1261a75e9f3SPablo de Lara L2FWD_CRYPTO_CIPHER_ONLY, 1271a75e9f3SPablo de Lara L2FWD_CRYPTO_HASH_ONLY 128387259bdSDeclan Doherty }; 129387259bdSDeclan Doherty 130a7f4562bSFiona Trahe struct l2fwd_key { 131a7f4562bSFiona Trahe uint8_t *data; 132a7f4562bSFiona Trahe uint32_t length; 133a7f4562bSFiona Trahe phys_addr_t phys_addr; 134a7f4562bSFiona Trahe }; 135a7f4562bSFiona Trahe 136387259bdSDeclan Doherty /** l2fwd crypto application command line options */ 137387259bdSDeclan Doherty struct l2fwd_crypto_options { 138387259bdSDeclan Doherty unsigned portmask; 139387259bdSDeclan Doherty unsigned nb_ports_per_lcore; 140387259bdSDeclan Doherty unsigned refresh_period; 141387259bdSDeclan Doherty unsigned single_lcore:1; 142387259bdSDeclan Doherty 14327cf2d1bSPablo de Lara enum cdev_type type; 144387259bdSDeclan Doherty unsigned sessionless:1; 145387259bdSDeclan Doherty 146387259bdSDeclan Doherty enum l2fwd_crypto_xform_chain xform_chain; 147387259bdSDeclan Doherty 1481bd407faSFiona Trahe struct rte_crypto_sym_xform cipher_xform; 1491df9c010SPablo de Lara unsigned ckey_param; 150387259bdSDeclan Doherty 1511df9c010SPablo de Lara struct l2fwd_key iv; 1521df9c010SPablo de Lara unsigned iv_param; 153387259bdSDeclan Doherty 1541bd407faSFiona Trahe struct rte_crypto_sym_xform auth_xform; 1551df9c010SPablo de Lara uint8_t akey_param; 156617a7949SPablo de Lara 157617a7949SPablo de Lara struct l2fwd_key aad; 158617a7949SPablo de Lara unsigned aad_param; 15927cf2d1bSPablo de Lara 16027cf2d1bSPablo de Lara uint16_t block_size; 16127cf2d1bSPablo de Lara char string_auth_algo[MAX_STR_LEN]; 16227cf2d1bSPablo de Lara char string_cipher_algo[MAX_STR_LEN]; 16327cf2d1bSPablo de Lara char string_type[MAX_STR_LEN]; 164387259bdSDeclan Doherty }; 165387259bdSDeclan Doherty 166387259bdSDeclan Doherty /** l2fwd crypto lcore params */ 167387259bdSDeclan Doherty struct l2fwd_crypto_params { 168387259bdSDeclan Doherty uint8_t dev_id; 169387259bdSDeclan Doherty uint8_t qp_id; 170387259bdSDeclan Doherty 171387259bdSDeclan Doherty unsigned digest_length; 172387259bdSDeclan Doherty unsigned block_size; 17327cf2d1bSPablo de Lara 1741df9c010SPablo de Lara struct l2fwd_key iv; 175617a7949SPablo de Lara struct l2fwd_key aad; 1761bd407faSFiona Trahe struct rte_cryptodev_sym_session *session; 1771a75e9f3SPablo de Lara 1781a75e9f3SPablo de Lara uint8_t do_cipher; 1791a75e9f3SPablo de Lara uint8_t do_hash; 18027cf2d1bSPablo de Lara uint8_t hash_verify; 181*d29ea843SPablo de Lara 182*d29ea843SPablo de Lara enum rte_crypto_cipher_algorithm cipher_algo; 183*d29ea843SPablo de Lara enum rte_crypto_auth_algorithm auth_algo; 184387259bdSDeclan Doherty }; 185387259bdSDeclan Doherty 186387259bdSDeclan Doherty /** lcore configuration */ 187387259bdSDeclan Doherty struct lcore_queue_conf { 188387259bdSDeclan Doherty unsigned nb_rx_ports; 189387259bdSDeclan Doherty unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; 190387259bdSDeclan Doherty 191387259bdSDeclan Doherty unsigned nb_crypto_devs; 192387259bdSDeclan Doherty unsigned cryptodev_list[MAX_RX_QUEUE_PER_LCORE]; 193387259bdSDeclan Doherty 194c0f87eb5SDeclan Doherty struct op_buffer op_buf[RTE_MAX_ETHPORTS]; 195c0f87eb5SDeclan Doherty struct pkt_buffer pkt_buf[RTE_MAX_ETHPORTS]; 196387259bdSDeclan Doherty } __rte_cache_aligned; 197387259bdSDeclan Doherty 198387259bdSDeclan Doherty struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; 199387259bdSDeclan Doherty 200387259bdSDeclan Doherty static const struct rte_eth_conf port_conf = { 201387259bdSDeclan Doherty .rxmode = { 2021df9c010SPablo de Lara .mq_mode = ETH_MQ_RX_NONE, 2031df9c010SPablo de Lara .max_rx_pkt_len = ETHER_MAX_LEN, 204387259bdSDeclan Doherty .split_hdr_size = 0, 205387259bdSDeclan Doherty .header_split = 0, /**< Header Split disabled */ 206387259bdSDeclan Doherty .hw_ip_checksum = 0, /**< IP checksum offload disabled */ 207387259bdSDeclan Doherty .hw_vlan_filter = 0, /**< VLAN filtering disabled */ 208387259bdSDeclan Doherty .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ 209387259bdSDeclan Doherty .hw_strip_crc = 0, /**< CRC stripped by hardware */ 210387259bdSDeclan Doherty }, 211387259bdSDeclan Doherty .txmode = { 212387259bdSDeclan Doherty .mq_mode = ETH_MQ_TX_NONE, 213387259bdSDeclan Doherty }, 214387259bdSDeclan Doherty }; 215387259bdSDeclan Doherty 216387259bdSDeclan Doherty struct rte_mempool *l2fwd_pktmbuf_pool; 217c0f87eb5SDeclan Doherty struct rte_mempool *l2fwd_crypto_op_pool; 218387259bdSDeclan Doherty 219387259bdSDeclan Doherty /* Per-port statistics struct */ 220387259bdSDeclan Doherty struct l2fwd_port_statistics { 221387259bdSDeclan Doherty uint64_t tx; 222387259bdSDeclan Doherty uint64_t rx; 223387259bdSDeclan Doherty 224387259bdSDeclan Doherty uint64_t crypto_enqueued; 225387259bdSDeclan Doherty uint64_t crypto_dequeued; 226387259bdSDeclan Doherty 227387259bdSDeclan Doherty uint64_t dropped; 228387259bdSDeclan Doherty } __rte_cache_aligned; 229387259bdSDeclan Doherty 230387259bdSDeclan Doherty struct l2fwd_crypto_statistics { 231387259bdSDeclan Doherty uint64_t enqueued; 232387259bdSDeclan Doherty uint64_t dequeued; 233387259bdSDeclan Doherty 234387259bdSDeclan Doherty uint64_t errors; 235387259bdSDeclan Doherty } __rte_cache_aligned; 236387259bdSDeclan Doherty 237387259bdSDeclan Doherty struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; 238387259bdSDeclan Doherty struct l2fwd_crypto_statistics crypto_statistics[RTE_MAX_ETHPORTS]; 239387259bdSDeclan Doherty 240387259bdSDeclan Doherty /* A tsc-based timer responsible for triggering statistics printout */ 241387259bdSDeclan Doherty #define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ 2423c96262cSPablo de Lara #define MAX_TIMER_PERIOD 86400UL /* 1 day max */ 243387259bdSDeclan Doherty 244387259bdSDeclan Doherty /* default period is 10 seconds */ 245387259bdSDeclan Doherty static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; 246387259bdSDeclan Doherty 247387259bdSDeclan Doherty /* Print out statistics on packets dropped */ 248387259bdSDeclan Doherty static void 249387259bdSDeclan Doherty print_stats(void) 250387259bdSDeclan Doherty { 25128523d9aSPablo de Lara uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; 25228523d9aSPablo de Lara uint64_t total_packets_enqueued, total_packets_dequeued, 25328523d9aSPablo de Lara total_packets_errors; 254387259bdSDeclan Doherty unsigned portid; 255387259bdSDeclan Doherty uint64_t cdevid; 256387259bdSDeclan Doherty 25728523d9aSPablo de Lara total_packets_dropped = 0; 25828523d9aSPablo de Lara total_packets_tx = 0; 25928523d9aSPablo de Lara total_packets_rx = 0; 26028523d9aSPablo de Lara total_packets_enqueued = 0; 26128523d9aSPablo de Lara total_packets_dequeued = 0; 26228523d9aSPablo de Lara total_packets_errors = 0; 263387259bdSDeclan Doherty 264387259bdSDeclan Doherty const char clr[] = { 27, '[', '2', 'J', '\0' }; 265387259bdSDeclan Doherty const char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 266387259bdSDeclan Doherty 267387259bdSDeclan Doherty /* Clear screen and move to top left */ 268387259bdSDeclan Doherty printf("%s%s", clr, topLeft); 269387259bdSDeclan Doherty 270387259bdSDeclan Doherty printf("\nPort statistics ===================================="); 271387259bdSDeclan Doherty 272387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 273387259bdSDeclan Doherty /* skip disabled ports */ 274387259bdSDeclan Doherty if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) 275387259bdSDeclan Doherty continue; 276387259bdSDeclan Doherty printf("\nStatistics for port %u ------------------------------" 277387259bdSDeclan Doherty "\nPackets sent: %32"PRIu64 278387259bdSDeclan Doherty "\nPackets received: %28"PRIu64 279387259bdSDeclan Doherty "\nPackets dropped: %29"PRIu64, 280387259bdSDeclan Doherty portid, 281387259bdSDeclan Doherty port_statistics[portid].tx, 282387259bdSDeclan Doherty port_statistics[portid].rx, 283387259bdSDeclan Doherty port_statistics[portid].dropped); 284387259bdSDeclan Doherty 285387259bdSDeclan Doherty total_packets_dropped += port_statistics[portid].dropped; 286387259bdSDeclan Doherty total_packets_tx += port_statistics[portid].tx; 287387259bdSDeclan Doherty total_packets_rx += port_statistics[portid].rx; 288387259bdSDeclan Doherty } 289387259bdSDeclan Doherty printf("\nCrypto statistics =================================="); 290387259bdSDeclan Doherty 291387259bdSDeclan Doherty for (cdevid = 0; cdevid < RTE_CRYPTO_MAX_DEVS; cdevid++) { 292387259bdSDeclan Doherty /* skip disabled ports */ 293387259bdSDeclan Doherty if ((l2fwd_enabled_crypto_mask & (1lu << cdevid)) == 0) 294387259bdSDeclan Doherty continue; 295387259bdSDeclan Doherty printf("\nStatistics for cryptodev %"PRIu64 296387259bdSDeclan Doherty " -------------------------" 297387259bdSDeclan Doherty "\nPackets enqueued: %28"PRIu64 298387259bdSDeclan Doherty "\nPackets dequeued: %28"PRIu64 299387259bdSDeclan Doherty "\nPackets errors: %30"PRIu64, 300387259bdSDeclan Doherty cdevid, 301387259bdSDeclan Doherty crypto_statistics[cdevid].enqueued, 302387259bdSDeclan Doherty crypto_statistics[cdevid].dequeued, 303387259bdSDeclan Doherty crypto_statistics[cdevid].errors); 304387259bdSDeclan Doherty 305387259bdSDeclan Doherty total_packets_enqueued += crypto_statistics[cdevid].enqueued; 306387259bdSDeclan Doherty total_packets_dequeued += crypto_statistics[cdevid].dequeued; 307387259bdSDeclan Doherty total_packets_errors += crypto_statistics[cdevid].errors; 308387259bdSDeclan Doherty } 309387259bdSDeclan Doherty printf("\nAggregate statistics ===============================" 310387259bdSDeclan Doherty "\nTotal packets received: %22"PRIu64 311387259bdSDeclan Doherty "\nTotal packets enqueued: %22"PRIu64 312387259bdSDeclan Doherty "\nTotal packets dequeued: %22"PRIu64 313387259bdSDeclan Doherty "\nTotal packets sent: %26"PRIu64 314387259bdSDeclan Doherty "\nTotal packets dropped: %23"PRIu64 315387259bdSDeclan Doherty "\nTotal packets crypto errors: %17"PRIu64, 316387259bdSDeclan Doherty total_packets_rx, 317387259bdSDeclan Doherty total_packets_enqueued, 318387259bdSDeclan Doherty total_packets_dequeued, 319387259bdSDeclan Doherty total_packets_tx, 320387259bdSDeclan Doherty total_packets_dropped, 321387259bdSDeclan Doherty total_packets_errors); 322387259bdSDeclan Doherty printf("\n====================================================\n"); 323387259bdSDeclan Doherty } 324387259bdSDeclan Doherty 325387259bdSDeclan Doherty 326387259bdSDeclan Doherty 327387259bdSDeclan Doherty static int 328387259bdSDeclan Doherty l2fwd_crypto_send_burst(struct lcore_queue_conf *qconf, unsigned n, 329387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams) 330387259bdSDeclan Doherty { 331c0f87eb5SDeclan Doherty struct rte_crypto_op **op_buffer; 332387259bdSDeclan Doherty unsigned ret; 333387259bdSDeclan Doherty 334c0f87eb5SDeclan Doherty op_buffer = (struct rte_crypto_op **) 335c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].buffer; 336387259bdSDeclan Doherty 337c0f87eb5SDeclan Doherty ret = rte_cryptodev_enqueue_burst(cparams->dev_id, 338c0f87eb5SDeclan Doherty cparams->qp_id, op_buffer, (uint16_t) n); 339c0f87eb5SDeclan Doherty 340387259bdSDeclan Doherty crypto_statistics[cparams->dev_id].enqueued += ret; 341387259bdSDeclan Doherty if (unlikely(ret < n)) { 342387259bdSDeclan Doherty crypto_statistics[cparams->dev_id].errors += (n - ret); 343387259bdSDeclan Doherty do { 344c0f87eb5SDeclan Doherty rte_pktmbuf_free(op_buffer[ret]->sym->m_src); 345c0f87eb5SDeclan Doherty rte_crypto_op_free(op_buffer[ret]); 346387259bdSDeclan Doherty } while (++ret < n); 347387259bdSDeclan Doherty } 348387259bdSDeclan Doherty 349387259bdSDeclan Doherty return 0; 350387259bdSDeclan Doherty } 351387259bdSDeclan Doherty 352387259bdSDeclan Doherty static int 353c0f87eb5SDeclan Doherty l2fwd_crypto_enqueue(struct rte_crypto_op *op, 354c0f87eb5SDeclan Doherty struct l2fwd_crypto_params *cparams) 355387259bdSDeclan Doherty { 356387259bdSDeclan Doherty unsigned lcore_id, len; 357387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 358387259bdSDeclan Doherty 359387259bdSDeclan Doherty lcore_id = rte_lcore_id(); 360387259bdSDeclan Doherty 361387259bdSDeclan Doherty qconf = &lcore_queue_conf[lcore_id]; 362c0f87eb5SDeclan Doherty len = qconf->op_buf[cparams->dev_id].len; 363c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].buffer[len] = op; 364387259bdSDeclan Doherty len++; 365387259bdSDeclan Doherty 366c0f87eb5SDeclan Doherty /* enough ops to be sent */ 367387259bdSDeclan Doherty if (len == MAX_PKT_BURST) { 368387259bdSDeclan Doherty l2fwd_crypto_send_burst(qconf, MAX_PKT_BURST, cparams); 369387259bdSDeclan Doherty len = 0; 370387259bdSDeclan Doherty } 371387259bdSDeclan Doherty 372c0f87eb5SDeclan Doherty qconf->op_buf[cparams->dev_id].len = len; 373387259bdSDeclan Doherty return 0; 374387259bdSDeclan Doherty } 375387259bdSDeclan Doherty 376387259bdSDeclan Doherty static int 377387259bdSDeclan Doherty l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, 378c0f87eb5SDeclan Doherty struct rte_crypto_op *op, 379387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams) 380387259bdSDeclan Doherty { 381387259bdSDeclan Doherty struct ether_hdr *eth_hdr; 382387259bdSDeclan Doherty struct ipv4_hdr *ip_hdr; 383387259bdSDeclan Doherty 384387259bdSDeclan Doherty unsigned ipdata_offset, pad_len, data_len; 385387259bdSDeclan Doherty char *padding; 386387259bdSDeclan Doherty 387387259bdSDeclan Doherty eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); 388387259bdSDeclan Doherty 389387259bdSDeclan Doherty if (eth_hdr->ether_type != rte_cpu_to_be_16(ETHER_TYPE_IPv4)) 390387259bdSDeclan Doherty return -1; 391387259bdSDeclan Doherty 392387259bdSDeclan Doherty ipdata_offset = sizeof(struct ether_hdr); 393387259bdSDeclan Doherty 394387259bdSDeclan Doherty ip_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(m, char *) + 395387259bdSDeclan Doherty ipdata_offset); 396387259bdSDeclan Doherty 397387259bdSDeclan Doherty ipdata_offset += (ip_hdr->version_ihl & IPV4_HDR_IHL_MASK) 398387259bdSDeclan Doherty * IPV4_IHL_MULTIPLIER; 399387259bdSDeclan Doherty 400387259bdSDeclan Doherty 401387259bdSDeclan Doherty /* Zero pad data to be crypto'd so it is block aligned */ 402387259bdSDeclan Doherty data_len = rte_pktmbuf_data_len(m) - ipdata_offset; 403387259bdSDeclan Doherty pad_len = data_len % cparams->block_size ? cparams->block_size - 404387259bdSDeclan Doherty (data_len % cparams->block_size) : 0; 405387259bdSDeclan Doherty 406387259bdSDeclan Doherty if (pad_len) { 407387259bdSDeclan Doherty padding = rte_pktmbuf_append(m, pad_len); 408387259bdSDeclan Doherty if (unlikely(!padding)) 409387259bdSDeclan Doherty return -1; 410387259bdSDeclan Doherty 411387259bdSDeclan Doherty data_len += pad_len; 412387259bdSDeclan Doherty memset(padding, 0, pad_len); 413387259bdSDeclan Doherty } 414387259bdSDeclan Doherty 415387259bdSDeclan Doherty /* Set crypto operation data parameters */ 416c0f87eb5SDeclan Doherty rte_crypto_op_attach_sym_session(op, cparams->session); 417387259bdSDeclan Doherty 4181a75e9f3SPablo de Lara if (cparams->do_hash) { 41927cf2d1bSPablo de Lara if (!cparams->hash_verify) { 420387259bdSDeclan Doherty /* Append space for digest to end of packet */ 421c0f87eb5SDeclan Doherty op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, 422387259bdSDeclan Doherty cparams->digest_length); 42327cf2d1bSPablo de Lara } else { 42427cf2d1bSPablo de Lara op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, 42527cf2d1bSPablo de Lara cparams->digest_length); 42627cf2d1bSPablo de Lara } 42727cf2d1bSPablo de Lara 428c0f87eb5SDeclan Doherty op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, 429387259bdSDeclan Doherty rte_pktmbuf_pkt_len(m) - cparams->digest_length); 430c0f87eb5SDeclan Doherty op->sym->auth.digest.length = cparams->digest_length; 431387259bdSDeclan Doherty 432*d29ea843SPablo de Lara /* For SNOW3G algorithms, offset/length must be in bits */ 433*d29ea843SPablo de Lara if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) { 434*d29ea843SPablo de Lara op->sym->auth.data.offset = ipdata_offset << 3; 435*d29ea843SPablo de Lara op->sym->auth.data.length = data_len << 3; 436*d29ea843SPablo de Lara } else { 437c0f87eb5SDeclan Doherty op->sym->auth.data.offset = ipdata_offset; 438c0f87eb5SDeclan Doherty op->sym->auth.data.length = data_len; 439*d29ea843SPablo de Lara } 440387259bdSDeclan Doherty 441617a7949SPablo de Lara if (cparams->aad.length) { 442617a7949SPablo de Lara op->sym->auth.aad.data = cparams->aad.data; 443617a7949SPablo de Lara op->sym->auth.aad.phys_addr = cparams->aad.phys_addr; 444617a7949SPablo de Lara op->sym->auth.aad.length = cparams->aad.length; 445617a7949SPablo de Lara } 4461a75e9f3SPablo de Lara } 4471a75e9f3SPablo de Lara 4481a75e9f3SPablo de Lara if (cparams->do_cipher) { 4491a75e9f3SPablo de Lara op->sym->cipher.iv.data = cparams->iv.data; 4501a75e9f3SPablo de Lara op->sym->cipher.iv.phys_addr = cparams->iv.phys_addr; 4511a75e9f3SPablo de Lara op->sym->cipher.iv.length = cparams->iv.length; 452617a7949SPablo de Lara 453*d29ea843SPablo de Lara /* For SNOW3G algorithms, offset/length must be in bits */ 454*d29ea843SPablo de Lara if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2) { 455*d29ea843SPablo de Lara op->sym->cipher.data.offset = ipdata_offset << 3; 456*d29ea843SPablo de Lara if (cparams->do_hash && cparams->hash_verify) 457*d29ea843SPablo de Lara /* Do not cipher the hash tag */ 458*d29ea843SPablo de Lara op->sym->cipher.data.length = (data_len - 459*d29ea843SPablo de Lara cparams->digest_length) << 3; 460*d29ea843SPablo de Lara else 461*d29ea843SPablo de Lara op->sym->cipher.data.length = data_len << 3; 462*d29ea843SPablo de Lara 463*d29ea843SPablo de Lara } else { 464c0f87eb5SDeclan Doherty op->sym->cipher.data.offset = ipdata_offset; 46527cf2d1bSPablo de Lara if (cparams->do_hash && cparams->hash_verify) 46627cf2d1bSPablo de Lara /* Do not cipher the hash tag */ 46727cf2d1bSPablo de Lara op->sym->cipher.data.length = data_len - 46827cf2d1bSPablo de Lara cparams->digest_length; 46927cf2d1bSPablo de Lara else 470c0f87eb5SDeclan Doherty op->sym->cipher.data.length = data_len; 4711a75e9f3SPablo de Lara } 472*d29ea843SPablo de Lara } 473387259bdSDeclan Doherty 474c0f87eb5SDeclan Doherty op->sym->m_src = m; 475c0f87eb5SDeclan Doherty 476c0f87eb5SDeclan Doherty return l2fwd_crypto_enqueue(op, cparams); 477387259bdSDeclan Doherty } 478387259bdSDeclan Doherty 479387259bdSDeclan Doherty 480387259bdSDeclan Doherty /* Send the burst of packets on an output interface */ 481387259bdSDeclan Doherty static int 482c0f87eb5SDeclan Doherty l2fwd_send_burst(struct lcore_queue_conf *qconf, unsigned n, 483c0f87eb5SDeclan Doherty uint8_t port) 484387259bdSDeclan Doherty { 485387259bdSDeclan Doherty struct rte_mbuf **pkt_buffer; 486387259bdSDeclan Doherty unsigned ret; 487387259bdSDeclan Doherty 488c0f87eb5SDeclan Doherty pkt_buffer = (struct rte_mbuf **)qconf->pkt_buf[port].buffer; 489387259bdSDeclan Doherty 490c0f87eb5SDeclan Doherty ret = rte_eth_tx_burst(port, 0, pkt_buffer, (uint16_t)n); 491387259bdSDeclan Doherty port_statistics[port].tx += ret; 492387259bdSDeclan Doherty if (unlikely(ret < n)) { 493387259bdSDeclan Doherty port_statistics[port].dropped += (n - ret); 494387259bdSDeclan Doherty do { 495387259bdSDeclan Doherty rte_pktmbuf_free(pkt_buffer[ret]); 496387259bdSDeclan Doherty } while (++ret < n); 497387259bdSDeclan Doherty } 498387259bdSDeclan Doherty 499387259bdSDeclan Doherty return 0; 500387259bdSDeclan Doherty } 501387259bdSDeclan Doherty 502387259bdSDeclan Doherty /* Enqueue packets for TX and prepare them to be sent */ 503387259bdSDeclan Doherty static int 504387259bdSDeclan Doherty l2fwd_send_packet(struct rte_mbuf *m, uint8_t port) 505387259bdSDeclan Doherty { 506387259bdSDeclan Doherty unsigned lcore_id, len; 507387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 508387259bdSDeclan Doherty 509387259bdSDeclan Doherty lcore_id = rte_lcore_id(); 510387259bdSDeclan Doherty 511387259bdSDeclan Doherty qconf = &lcore_queue_conf[lcore_id]; 512c0f87eb5SDeclan Doherty len = qconf->pkt_buf[port].len; 513c0f87eb5SDeclan Doherty qconf->pkt_buf[port].buffer[len] = m; 514387259bdSDeclan Doherty len++; 515387259bdSDeclan Doherty 516387259bdSDeclan Doherty /* enough pkts to be sent */ 517387259bdSDeclan Doherty if (unlikely(len == MAX_PKT_BURST)) { 518387259bdSDeclan Doherty l2fwd_send_burst(qconf, MAX_PKT_BURST, port); 519387259bdSDeclan Doherty len = 0; 520387259bdSDeclan Doherty } 521387259bdSDeclan Doherty 522c0f87eb5SDeclan Doherty qconf->pkt_buf[port].len = len; 523387259bdSDeclan Doherty return 0; 524387259bdSDeclan Doherty } 525387259bdSDeclan Doherty 526387259bdSDeclan Doherty static void 527387259bdSDeclan Doherty l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid) 528387259bdSDeclan Doherty { 529387259bdSDeclan Doherty struct ether_hdr *eth; 530387259bdSDeclan Doherty void *tmp; 531387259bdSDeclan Doherty unsigned dst_port; 532387259bdSDeclan Doherty 533387259bdSDeclan Doherty dst_port = l2fwd_dst_ports[portid]; 534387259bdSDeclan Doherty eth = rte_pktmbuf_mtod(m, struct ether_hdr *); 535387259bdSDeclan Doherty 536387259bdSDeclan Doherty /* 02:00:00:00:00:xx */ 537387259bdSDeclan Doherty tmp = ð->d_addr.addr_bytes[0]; 538387259bdSDeclan Doherty *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40); 539387259bdSDeclan Doherty 540387259bdSDeclan Doherty /* src addr */ 541387259bdSDeclan Doherty ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], ð->s_addr); 542387259bdSDeclan Doherty 543387259bdSDeclan Doherty l2fwd_send_packet(m, (uint8_t) dst_port); 544387259bdSDeclan Doherty } 545387259bdSDeclan Doherty 546387259bdSDeclan Doherty /** Generate random key */ 547387259bdSDeclan Doherty static void 548387259bdSDeclan Doherty generate_random_key(uint8_t *key, unsigned length) 549387259bdSDeclan Doherty { 550387259bdSDeclan Doherty unsigned i; 551387259bdSDeclan Doherty 552387259bdSDeclan Doherty for (i = 0; i < length; i++) 553387259bdSDeclan Doherty key[i] = rand() % 0xff; 554387259bdSDeclan Doherty } 555387259bdSDeclan Doherty 5561bd407faSFiona Trahe static struct rte_cryptodev_sym_session * 557387259bdSDeclan Doherty initialize_crypto_session(struct l2fwd_crypto_options *options, 558387259bdSDeclan Doherty uint8_t cdev_id) 559387259bdSDeclan Doherty { 5601bd407faSFiona Trahe struct rte_crypto_sym_xform *first_xform; 561387259bdSDeclan Doherty 562387259bdSDeclan Doherty if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { 563387259bdSDeclan Doherty first_xform = &options->cipher_xform; 564387259bdSDeclan Doherty first_xform->next = &options->auth_xform; 5651a75e9f3SPablo de Lara } else if (options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER) { 566387259bdSDeclan Doherty first_xform = &options->auth_xform; 567387259bdSDeclan Doherty first_xform->next = &options->cipher_xform; 5681a75e9f3SPablo de Lara } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 5691a75e9f3SPablo de Lara first_xform = &options->cipher_xform; 5701a75e9f3SPablo de Lara } else { 5711a75e9f3SPablo de Lara first_xform = &options->auth_xform; 572387259bdSDeclan Doherty } 573387259bdSDeclan Doherty 574387259bdSDeclan Doherty /* Setup Cipher Parameters */ 5751bd407faSFiona Trahe return rte_cryptodev_sym_session_create(cdev_id, first_xform); 576387259bdSDeclan Doherty } 577387259bdSDeclan Doherty 578387259bdSDeclan Doherty static void 579387259bdSDeclan Doherty l2fwd_crypto_options_print(struct l2fwd_crypto_options *options); 580387259bdSDeclan Doherty 581387259bdSDeclan Doherty /* main processing loop */ 582387259bdSDeclan Doherty static void 583387259bdSDeclan Doherty l2fwd_main_loop(struct l2fwd_crypto_options *options) 584387259bdSDeclan Doherty { 585387259bdSDeclan Doherty struct rte_mbuf *m, *pkts_burst[MAX_PKT_BURST]; 586c0f87eb5SDeclan Doherty struct rte_crypto_op *ops_burst[MAX_PKT_BURST]; 587c0f87eb5SDeclan Doherty 588387259bdSDeclan Doherty unsigned lcore_id = rte_lcore_id(); 589387259bdSDeclan Doherty uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 590387259bdSDeclan Doherty unsigned i, j, portid, nb_rx; 591387259bdSDeclan Doherty struct lcore_queue_conf *qconf = &lcore_queue_conf[lcore_id]; 592387259bdSDeclan Doherty const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / 593387259bdSDeclan Doherty US_PER_S * BURST_TX_DRAIN_US; 594387259bdSDeclan Doherty struct l2fwd_crypto_params *cparams; 595387259bdSDeclan Doherty struct l2fwd_crypto_params port_cparams[qconf->nb_crypto_devs]; 596387259bdSDeclan Doherty 597387259bdSDeclan Doherty if (qconf->nb_rx_ports == 0) { 598387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); 599387259bdSDeclan Doherty return; 600387259bdSDeclan Doherty } 601387259bdSDeclan Doherty 602387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); 603387259bdSDeclan Doherty 604387259bdSDeclan Doherty l2fwd_crypto_options_print(options); 605387259bdSDeclan Doherty 606387259bdSDeclan Doherty for (i = 0; i < qconf->nb_rx_ports; i++) { 607387259bdSDeclan Doherty 608387259bdSDeclan Doherty portid = qconf->rx_port_list[i]; 609387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, 610387259bdSDeclan Doherty portid); 611387259bdSDeclan Doherty } 612387259bdSDeclan Doherty 613387259bdSDeclan Doherty for (i = 0; i < qconf->nb_crypto_devs; i++) { 6141a75e9f3SPablo de Lara port_cparams[i].do_cipher = 0; 6151a75e9f3SPablo de Lara port_cparams[i].do_hash = 0; 6161a75e9f3SPablo de Lara 6171a75e9f3SPablo de Lara switch (options->xform_chain) { 6181a75e9f3SPablo de Lara case L2FWD_CRYPTO_CIPHER_HASH: 6191a75e9f3SPablo de Lara case L2FWD_CRYPTO_HASH_CIPHER: 6201a75e9f3SPablo de Lara port_cparams[i].do_cipher = 1; 6211a75e9f3SPablo de Lara port_cparams[i].do_hash = 1; 6221a75e9f3SPablo de Lara break; 6231a75e9f3SPablo de Lara case L2FWD_CRYPTO_HASH_ONLY: 6241a75e9f3SPablo de Lara port_cparams[i].do_hash = 1; 6251a75e9f3SPablo de Lara break; 6261a75e9f3SPablo de Lara case L2FWD_CRYPTO_CIPHER_ONLY: 6271a75e9f3SPablo de Lara port_cparams[i].do_cipher = 1; 6281a75e9f3SPablo de Lara break; 6291a75e9f3SPablo de Lara } 6301a75e9f3SPablo de Lara 631387259bdSDeclan Doherty port_cparams[i].dev_id = qconf->cryptodev_list[i]; 632387259bdSDeclan Doherty port_cparams[i].qp_id = 0; 633387259bdSDeclan Doherty 63427cf2d1bSPablo de Lara port_cparams[i].block_size = options->block_size; 635387259bdSDeclan Doherty 6361a75e9f3SPablo de Lara if (port_cparams[i].do_hash) { 63727cf2d1bSPablo de Lara port_cparams[i].digest_length = 63827cf2d1bSPablo de Lara options->auth_xform.auth.digest_length; 63927cf2d1bSPablo de Lara if (options->auth_xform.auth.add_auth_data_length) { 64027cf2d1bSPablo de Lara port_cparams[i].aad.data = options->aad.data; 641617a7949SPablo de Lara port_cparams[i].aad.length = 642617a7949SPablo de Lara options->auth_xform.auth.add_auth_data_length; 643617a7949SPablo de Lara port_cparams[i].aad.phys_addr = options->aad.phys_addr; 644617a7949SPablo de Lara if (!options->aad_param) 64527cf2d1bSPablo de Lara generate_random_key(port_cparams[i].aad.data, 64627cf2d1bSPablo de Lara sizeof(port_cparams[i].aad.length)); 64727cf2d1bSPablo de Lara 64827cf2d1bSPablo de Lara } 64927cf2d1bSPablo de Lara 65027cf2d1bSPablo de Lara if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) 65127cf2d1bSPablo de Lara port_cparams[i].hash_verify = 1; 65227cf2d1bSPablo de Lara else 65327cf2d1bSPablo de Lara port_cparams[i].hash_verify = 0; 654*d29ea843SPablo de Lara 655*d29ea843SPablo de Lara port_cparams[i].auth_algo = options->auth_xform.auth.algo; 6561a75e9f3SPablo de Lara } 6571a75e9f3SPablo de Lara 6581a75e9f3SPablo de Lara if (port_cparams[i].do_cipher) { 6591a75e9f3SPablo de Lara port_cparams[i].iv.data = options->iv.data; 66027cf2d1bSPablo de Lara port_cparams[i].iv.length = options->iv.length; 6611a75e9f3SPablo de Lara port_cparams[i].iv.phys_addr = options->iv.phys_addr; 6621a75e9f3SPablo de Lara if (!options->iv_param) 66327cf2d1bSPablo de Lara generate_random_key(port_cparams[i].iv.data, 66427cf2d1bSPablo de Lara sizeof(port_cparams[i].iv.length)); 665617a7949SPablo de Lara 666*d29ea843SPablo de Lara port_cparams[i].cipher_algo = options->cipher_xform.cipher.algo; 66727cf2d1bSPablo de Lara } 668617a7949SPablo de Lara 669387259bdSDeclan Doherty port_cparams[i].session = initialize_crypto_session(options, 670387259bdSDeclan Doherty port_cparams[i].dev_id); 671387259bdSDeclan Doherty 672387259bdSDeclan Doherty if (port_cparams[i].session == NULL) 673387259bdSDeclan Doherty return; 674387259bdSDeclan Doherty RTE_LOG(INFO, L2FWD, " -- lcoreid=%u cryptoid=%u\n", lcore_id, 675387259bdSDeclan Doherty port_cparams[i].dev_id); 676387259bdSDeclan Doherty } 677387259bdSDeclan Doherty 678387259bdSDeclan Doherty while (1) { 679387259bdSDeclan Doherty 680387259bdSDeclan Doherty cur_tsc = rte_rdtsc(); 681387259bdSDeclan Doherty 682387259bdSDeclan Doherty /* 683387259bdSDeclan Doherty * TX burst queue drain 684387259bdSDeclan Doherty */ 685387259bdSDeclan Doherty diff_tsc = cur_tsc - prev_tsc; 686387259bdSDeclan Doherty if (unlikely(diff_tsc > drain_tsc)) { 687387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 688c0f87eb5SDeclan Doherty if (qconf->pkt_buf[portid].len == 0) 689387259bdSDeclan Doherty continue; 690387259bdSDeclan Doherty l2fwd_send_burst(&lcore_queue_conf[lcore_id], 691c0f87eb5SDeclan Doherty qconf->pkt_buf[portid].len, 692387259bdSDeclan Doherty (uint8_t) portid); 693c0f87eb5SDeclan Doherty qconf->pkt_buf[portid].len = 0; 694387259bdSDeclan Doherty } 695387259bdSDeclan Doherty 696387259bdSDeclan Doherty /* if timer is enabled */ 697387259bdSDeclan Doherty if (timer_period > 0) { 698387259bdSDeclan Doherty 699387259bdSDeclan Doherty /* advance the timer */ 700387259bdSDeclan Doherty timer_tsc += diff_tsc; 701387259bdSDeclan Doherty 702387259bdSDeclan Doherty /* if timer has reached its timeout */ 703387259bdSDeclan Doherty if (unlikely(timer_tsc >= 704387259bdSDeclan Doherty (uint64_t)timer_period)) { 705387259bdSDeclan Doherty 706387259bdSDeclan Doherty /* do this only on master core */ 707ad509b4aSDeclan Doherty if (lcore_id == rte_get_master_lcore() 708ad509b4aSDeclan Doherty && options->refresh_period) { 709387259bdSDeclan Doherty print_stats(); 710387259bdSDeclan Doherty timer_tsc = 0; 711387259bdSDeclan Doherty } 712387259bdSDeclan Doherty } 713387259bdSDeclan Doherty } 714387259bdSDeclan Doherty 715387259bdSDeclan Doherty prev_tsc = cur_tsc; 716387259bdSDeclan Doherty } 717387259bdSDeclan Doherty 718387259bdSDeclan Doherty /* 719387259bdSDeclan Doherty * Read packet from RX queues 720387259bdSDeclan Doherty */ 721387259bdSDeclan Doherty for (i = 0; i < qconf->nb_rx_ports; i++) { 722387259bdSDeclan Doherty portid = qconf->rx_port_list[i]; 723387259bdSDeclan Doherty 724387259bdSDeclan Doherty cparams = &port_cparams[i]; 725387259bdSDeclan Doherty 726387259bdSDeclan Doherty nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, 727387259bdSDeclan Doherty pkts_burst, MAX_PKT_BURST); 728387259bdSDeclan Doherty 729387259bdSDeclan Doherty port_statistics[portid].rx += nb_rx; 730387259bdSDeclan Doherty 731c0f87eb5SDeclan Doherty if (nb_rx) { 732387259bdSDeclan Doherty /* 733c0f87eb5SDeclan Doherty * If we can't allocate a crypto_ops, then drop 734387259bdSDeclan Doherty * the rest of the burst and dequeue and 735387259bdSDeclan Doherty * process the packets to free offload structs 736387259bdSDeclan Doherty */ 737c0f87eb5SDeclan Doherty if (rte_crypto_op_bulk_alloc( 738c0f87eb5SDeclan Doherty l2fwd_crypto_op_pool, 739c0f87eb5SDeclan Doherty RTE_CRYPTO_OP_TYPE_SYMMETRIC, 740c0f87eb5SDeclan Doherty ops_burst, nb_rx) != 741c0f87eb5SDeclan Doherty nb_rx) { 742c0f87eb5SDeclan Doherty for (j = 0; j < nb_rx; j++) 743c0f87eb5SDeclan Doherty rte_pktmbuf_free(pkts_burst[i]); 744c0f87eb5SDeclan Doherty 745c0f87eb5SDeclan Doherty nb_rx = 0; 746387259bdSDeclan Doherty } 747387259bdSDeclan Doherty 748c0f87eb5SDeclan Doherty /* Enqueue packets from Crypto device*/ 749c0f87eb5SDeclan Doherty for (j = 0; j < nb_rx; j++) { 750c0f87eb5SDeclan Doherty m = pkts_burst[j]; 751387259bdSDeclan Doherty 752c0f87eb5SDeclan Doherty l2fwd_simple_crypto_enqueue(m, 753c0f87eb5SDeclan Doherty ops_burst[j], cparams); 754c0f87eb5SDeclan Doherty } 755387259bdSDeclan Doherty } 756387259bdSDeclan Doherty 757387259bdSDeclan Doherty /* Dequeue packets from Crypto device */ 758c0f87eb5SDeclan Doherty do { 759387259bdSDeclan Doherty nb_rx = rte_cryptodev_dequeue_burst( 760387259bdSDeclan Doherty cparams->dev_id, cparams->qp_id, 761c0f87eb5SDeclan Doherty ops_burst, MAX_PKT_BURST); 762c0f87eb5SDeclan Doherty 763c0f87eb5SDeclan Doherty crypto_statistics[cparams->dev_id].dequeued += 764c0f87eb5SDeclan Doherty nb_rx; 765387259bdSDeclan Doherty 766387259bdSDeclan Doherty /* Forward crypto'd packets */ 767387259bdSDeclan Doherty for (j = 0; j < nb_rx; j++) { 768c0f87eb5SDeclan Doherty m = ops_burst[j]->sym->m_src; 769c0f87eb5SDeclan Doherty 770c0f87eb5SDeclan Doherty rte_crypto_op_free(ops_burst[j]); 771387259bdSDeclan Doherty l2fwd_simple_forward(m, portid); 772387259bdSDeclan Doherty } 773c0f87eb5SDeclan Doherty } while (nb_rx == MAX_PKT_BURST); 774387259bdSDeclan Doherty } 775387259bdSDeclan Doherty } 776387259bdSDeclan Doherty } 777387259bdSDeclan Doherty 778387259bdSDeclan Doherty static int 779387259bdSDeclan Doherty l2fwd_launch_one_lcore(void *arg) 780387259bdSDeclan Doherty { 781387259bdSDeclan Doherty l2fwd_main_loop((struct l2fwd_crypto_options *)arg); 782387259bdSDeclan Doherty return 0; 783387259bdSDeclan Doherty } 784387259bdSDeclan Doherty 785387259bdSDeclan Doherty /* Display command line arguments usage */ 786387259bdSDeclan Doherty static void 787387259bdSDeclan Doherty l2fwd_crypto_usage(const char *prgname) 788387259bdSDeclan Doherty { 789912b3a0aSPablo de Lara printf("%s [EAL options] --\n" 790387259bdSDeclan Doherty " -p PORTMASK: hexadecimal bitmask of ports to configure\n" 791387259bdSDeclan Doherty " -q NQ: number of queue (=ports) per lcore (default is 1)\n" 792387259bdSDeclan Doherty " -s manage all ports from single lcore" 793387259bdSDeclan Doherty " -t PERIOD: statistics will be refreshed each PERIOD seconds" 794387259bdSDeclan Doherty " (0 to disable, 10 default, 86400 maximum)\n" 795387259bdSDeclan Doherty 796912b3a0aSPablo de Lara " --cdev_type HW / SW / ANY\n" 797387259bdSDeclan Doherty " --chain HASH_CIPHER / CIPHER_HASH\n" 798387259bdSDeclan Doherty 799387259bdSDeclan Doherty " --cipher_algo ALGO\n" 800387259bdSDeclan Doherty " --cipher_op ENCRYPT / DECRYPT\n" 801387259bdSDeclan Doherty " --cipher_key KEY\n" 8023b98cbaaSPablo de Lara " --iv IV\n" 803387259bdSDeclan Doherty 8043b98cbaaSPablo de Lara " --auth_algo ALGO\n" 805387259bdSDeclan Doherty " --auth_op GENERATE / VERIFY\n" 806387259bdSDeclan Doherty " --auth_key KEY\n" 807617a7949SPablo de Lara " --aad AAD\n" 808387259bdSDeclan Doherty 809387259bdSDeclan Doherty " --sessionless\n", 810387259bdSDeclan Doherty prgname); 811387259bdSDeclan Doherty } 812387259bdSDeclan Doherty 813387259bdSDeclan Doherty /** Parse crypto device type command line argument */ 814387259bdSDeclan Doherty static int 81527cf2d1bSPablo de Lara parse_cryptodev_type(enum cdev_type *type, char *optarg) 816387259bdSDeclan Doherty { 81727cf2d1bSPablo de Lara if (strcmp("HW", optarg) == 0) { 81827cf2d1bSPablo de Lara *type = CDEV_TYPE_HW; 819387259bdSDeclan Doherty return 0; 82027cf2d1bSPablo de Lara } else if (strcmp("SW", optarg) == 0) { 82127cf2d1bSPablo de Lara *type = CDEV_TYPE_SW; 82227cf2d1bSPablo de Lara return 0; 82327cf2d1bSPablo de Lara } else if (strcmp("ANY", optarg) == 0) { 82427cf2d1bSPablo de Lara *type = CDEV_TYPE_ANY; 825387259bdSDeclan Doherty return 0; 826387259bdSDeclan Doherty } 827387259bdSDeclan Doherty 828387259bdSDeclan Doherty return -1; 829387259bdSDeclan Doherty } 830387259bdSDeclan Doherty 831387259bdSDeclan Doherty /** Parse crypto chain xform command line argument */ 832387259bdSDeclan Doherty static int 833387259bdSDeclan Doherty parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) 834387259bdSDeclan Doherty { 835387259bdSDeclan Doherty if (strcmp("CIPHER_HASH", optarg) == 0) { 836387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 837387259bdSDeclan Doherty return 0; 838387259bdSDeclan Doherty } else if (strcmp("HASH_CIPHER", optarg) == 0) { 839387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_HASH_CIPHER; 840387259bdSDeclan Doherty return 0; 8411a75e9f3SPablo de Lara } else if (strcmp("CIPHER_ONLY", optarg) == 0) { 8421a75e9f3SPablo de Lara options->xform_chain = L2FWD_CRYPTO_CIPHER_ONLY; 8431a75e9f3SPablo de Lara return 0; 8441a75e9f3SPablo de Lara } else if (strcmp("HASH_ONLY", optarg) == 0) { 8451a75e9f3SPablo de Lara options->xform_chain = L2FWD_CRYPTO_HASH_ONLY; 8461a75e9f3SPablo de Lara return 0; 847387259bdSDeclan Doherty } 848387259bdSDeclan Doherty 849387259bdSDeclan Doherty return -1; 850387259bdSDeclan Doherty } 851387259bdSDeclan Doherty 852387259bdSDeclan Doherty /** Parse crypto cipher algo option command line argument */ 853387259bdSDeclan Doherty static int 854387259bdSDeclan Doherty parse_cipher_algo(enum rte_crypto_cipher_algorithm *algo, char *optarg) 855387259bdSDeclan Doherty { 856387259bdSDeclan Doherty if (strcmp("AES_CBC", optarg) == 0) { 857387259bdSDeclan Doherty *algo = RTE_CRYPTO_CIPHER_AES_CBC; 858387259bdSDeclan Doherty return 0; 859387259bdSDeclan Doherty } else if (strcmp("AES_GCM", optarg) == 0) { 860387259bdSDeclan Doherty *algo = RTE_CRYPTO_CIPHER_AES_GCM; 861387259bdSDeclan Doherty return 0; 862*d29ea843SPablo de Lara } else if (strcmp("SNOW3G_UEA2", optarg) == 0) { 863*d29ea843SPablo de Lara *algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2; 864*d29ea843SPablo de Lara return 0; 865387259bdSDeclan Doherty } 866387259bdSDeclan Doherty 867387259bdSDeclan Doherty printf("Cipher algorithm not supported!\n"); 868387259bdSDeclan Doherty return -1; 869387259bdSDeclan Doherty } 870387259bdSDeclan Doherty 871387259bdSDeclan Doherty /** Parse crypto cipher operation command line argument */ 872387259bdSDeclan Doherty static int 873387259bdSDeclan Doherty parse_cipher_op(enum rte_crypto_cipher_operation *op, char *optarg) 874387259bdSDeclan Doherty { 875387259bdSDeclan Doherty if (strcmp("ENCRYPT", optarg) == 0) { 876387259bdSDeclan Doherty *op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 877387259bdSDeclan Doherty return 0; 878387259bdSDeclan Doherty } else if (strcmp("DECRYPT", optarg) == 0) { 879387259bdSDeclan Doherty *op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 880387259bdSDeclan Doherty return 0; 881387259bdSDeclan Doherty } 882387259bdSDeclan Doherty 883387259bdSDeclan Doherty printf("Cipher operation not supported!\n"); 884387259bdSDeclan Doherty return -1; 885387259bdSDeclan Doherty } 886387259bdSDeclan Doherty 887387259bdSDeclan Doherty /** Parse crypto key command line argument */ 888387259bdSDeclan Doherty static int 8891df9c010SPablo de Lara parse_key(uint8_t *data, char *input_arg) 890387259bdSDeclan Doherty { 8911df9c010SPablo de Lara unsigned byte_count; 8921df9c010SPablo de Lara char *token; 8931df9c010SPablo de Lara 8941df9c010SPablo de Lara for (byte_count = 0, token = strtok(input_arg, ":"); 8951df9c010SPablo de Lara (byte_count < MAX_KEY_SIZE) && (token != NULL); 8961df9c010SPablo de Lara token = strtok(NULL, ":")) { 8971df9c010SPablo de Lara 8981df9c010SPablo de Lara int number = (int)strtol(token, NULL, 16); 8991df9c010SPablo de Lara 9001df9c010SPablo de Lara if (errno == EINVAL || errno == ERANGE || number > 0xFF) 901387259bdSDeclan Doherty return -1; 9021df9c010SPablo de Lara 9031df9c010SPablo de Lara data[byte_count++] = (uint8_t)number; 9041df9c010SPablo de Lara } 9051df9c010SPablo de Lara 9061df9c010SPablo de Lara return 0; 907387259bdSDeclan Doherty } 908387259bdSDeclan Doherty 909387259bdSDeclan Doherty /** Parse crypto cipher operation command line argument */ 910387259bdSDeclan Doherty static int 911387259bdSDeclan Doherty parse_auth_algo(enum rte_crypto_auth_algorithm *algo, char *optarg) 912387259bdSDeclan Doherty { 913ef120cbcSPablo de Lara if (strcmp("MD5_HMAC", optarg) == 0) { 914ef120cbcSPablo de Lara *algo = RTE_CRYPTO_AUTH_MD5_HMAC; 915387259bdSDeclan Doherty return 0; 916387259bdSDeclan Doherty } else if (strcmp("SHA1_HMAC", optarg) == 0) { 917387259bdSDeclan Doherty *algo = RTE_CRYPTO_AUTH_SHA1_HMAC; 918387259bdSDeclan Doherty return 0; 919387259bdSDeclan Doherty } else if (strcmp("SHA224_HMAC", optarg) == 0) { 920387259bdSDeclan Doherty *algo = RTE_CRYPTO_AUTH_SHA224_HMAC; 921387259bdSDeclan Doherty return 0; 922387259bdSDeclan Doherty } else if (strcmp("SHA256_HMAC", optarg) == 0) { 923387259bdSDeclan Doherty *algo = RTE_CRYPTO_AUTH_SHA256_HMAC; 924387259bdSDeclan Doherty return 0; 925ef120cbcSPablo de Lara } else if (strcmp("SHA384_HMAC", optarg) == 0) { 926ef120cbcSPablo de Lara *algo = RTE_CRYPTO_AUTH_SHA384_HMAC; 927387259bdSDeclan Doherty return 0; 928387259bdSDeclan Doherty } else if (strcmp("SHA512_HMAC", optarg) == 0) { 929ef120cbcSPablo de Lara *algo = RTE_CRYPTO_AUTH_SHA512_HMAC; 930387259bdSDeclan Doherty return 0; 931*d29ea843SPablo de Lara } else if (strcmp("SNOW3G_UIA2", optarg) == 0) { 932*d29ea843SPablo de Lara *algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2; 933*d29ea843SPablo de Lara return 0; 934387259bdSDeclan Doherty } 935387259bdSDeclan Doherty 936387259bdSDeclan Doherty printf("Authentication algorithm specified not supported!\n"); 937387259bdSDeclan Doherty return -1; 938387259bdSDeclan Doherty } 939387259bdSDeclan Doherty 940387259bdSDeclan Doherty static int 941387259bdSDeclan Doherty parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg) 942387259bdSDeclan Doherty { 943387259bdSDeclan Doherty if (strcmp("VERIFY", optarg) == 0) { 944387259bdSDeclan Doherty *op = RTE_CRYPTO_AUTH_OP_VERIFY; 945387259bdSDeclan Doherty return 0; 946387259bdSDeclan Doherty } else if (strcmp("GENERATE", optarg) == 0) { 94772169087SPablo de Lara *op = RTE_CRYPTO_AUTH_OP_GENERATE; 948387259bdSDeclan Doherty return 0; 949387259bdSDeclan Doherty } 950387259bdSDeclan Doherty 951387259bdSDeclan Doherty printf("Authentication operation specified not supported!\n"); 952387259bdSDeclan Doherty return -1; 953387259bdSDeclan Doherty } 954387259bdSDeclan Doherty 955387259bdSDeclan Doherty /** Parse long options */ 956387259bdSDeclan Doherty static int 957387259bdSDeclan Doherty l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, 958387259bdSDeclan Doherty struct option *lgopts, int option_index) 959387259bdSDeclan Doherty { 96027cf2d1bSPablo de Lara int retval; 96127cf2d1bSPablo de Lara 962387259bdSDeclan Doherty if (strcmp(lgopts[option_index].name, "cdev_type") == 0) 96327cf2d1bSPablo de Lara return parse_cryptodev_type(&options->type, optarg); 964387259bdSDeclan Doherty 965387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "chain") == 0) 966387259bdSDeclan Doherty return parse_crypto_opt_chain(options, optarg); 967387259bdSDeclan Doherty 968387259bdSDeclan Doherty /* Cipher options */ 96927cf2d1bSPablo de Lara else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0) { 97027cf2d1bSPablo de Lara retval = parse_cipher_algo(&options->cipher_xform.cipher.algo, 971387259bdSDeclan Doherty optarg); 97227cf2d1bSPablo de Lara if (retval == 0) 97327cf2d1bSPablo de Lara strcpy(options->string_cipher_algo, optarg); 97427cf2d1bSPablo de Lara return retval; 97527cf2d1bSPablo de Lara } 976387259bdSDeclan Doherty 977387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "cipher_op") == 0) 978387259bdSDeclan Doherty return parse_cipher_op(&options->cipher_xform.cipher.op, 979387259bdSDeclan Doherty optarg); 980387259bdSDeclan Doherty 981a7f4562bSFiona Trahe else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) { 9821df9c010SPablo de Lara options->ckey_param = 1; 9831df9c010SPablo de Lara return parse_key(options->cipher_xform.cipher.key.data, optarg); 9841df9c010SPablo de Lara } 985387259bdSDeclan Doherty 9861df9c010SPablo de Lara else if (strcmp(lgopts[option_index].name, "iv") == 0) { 9871df9c010SPablo de Lara options->iv_param = 1; 9881df9c010SPablo de Lara return parse_key(options->iv.data, optarg); 9891df9c010SPablo de Lara } 990387259bdSDeclan Doherty 991387259bdSDeclan Doherty /* Authentication options */ 99227cf2d1bSPablo de Lara else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) { 99327cf2d1bSPablo de Lara retval = parse_auth_algo(&options->auth_xform.auth.algo, 994387259bdSDeclan Doherty optarg); 99527cf2d1bSPablo de Lara if (retval == 0) 99627cf2d1bSPablo de Lara strcpy(options->string_auth_algo, optarg); 99727cf2d1bSPablo de Lara return retval; 99827cf2d1bSPablo de Lara } 999387259bdSDeclan Doherty 1000387259bdSDeclan Doherty else if (strcmp(lgopts[option_index].name, "auth_op") == 0) 100172169087SPablo de Lara return parse_auth_op(&options->auth_xform.auth.op, 1002387259bdSDeclan Doherty optarg); 1003387259bdSDeclan Doherty 1004a7f4562bSFiona Trahe else if (strcmp(lgopts[option_index].name, "auth_key") == 0) { 10051df9c010SPablo de Lara options->akey_param = 1; 10061df9c010SPablo de Lara return parse_key(options->auth_xform.auth.key.data, optarg); 10071df9c010SPablo de Lara } 1008387259bdSDeclan Doherty 1009617a7949SPablo de Lara else if (strcmp(lgopts[option_index].name, "aad") == 0) { 1010617a7949SPablo de Lara options->aad_param = 1; 1011617a7949SPablo de Lara return parse_key(options->aad.data, optarg); 1012617a7949SPablo de Lara } 1013617a7949SPablo de Lara 10141df9c010SPablo de Lara else if (strcmp(lgopts[option_index].name, "sessionless") == 0) { 1015387259bdSDeclan Doherty options->sessionless = 1; 1016387259bdSDeclan Doherty return 0; 1017387259bdSDeclan Doherty } 1018387259bdSDeclan Doherty 1019387259bdSDeclan Doherty return -1; 1020387259bdSDeclan Doherty } 1021387259bdSDeclan Doherty 1022387259bdSDeclan Doherty /** Parse port mask */ 1023387259bdSDeclan Doherty static int 1024387259bdSDeclan Doherty l2fwd_crypto_parse_portmask(struct l2fwd_crypto_options *options, 1025387259bdSDeclan Doherty const char *q_arg) 1026387259bdSDeclan Doherty { 1027387259bdSDeclan Doherty char *end = NULL; 1028387259bdSDeclan Doherty unsigned long pm; 1029387259bdSDeclan Doherty 1030387259bdSDeclan Doherty /* parse hexadecimal string */ 1031387259bdSDeclan Doherty pm = strtoul(q_arg, &end, 16); 1032387259bdSDeclan Doherty if ((pm == '\0') || (end == NULL) || (*end != '\0')) 1033387259bdSDeclan Doherty pm = 0; 1034387259bdSDeclan Doherty 1035387259bdSDeclan Doherty options->portmask = pm; 1036387259bdSDeclan Doherty if (options->portmask == 0) { 1037387259bdSDeclan Doherty printf("invalid portmask specified\n"); 1038387259bdSDeclan Doherty return -1; 1039387259bdSDeclan Doherty } 1040387259bdSDeclan Doherty 1041387259bdSDeclan Doherty return pm; 1042387259bdSDeclan Doherty } 1043387259bdSDeclan Doherty 1044387259bdSDeclan Doherty /** Parse number of queues */ 1045387259bdSDeclan Doherty static int 1046387259bdSDeclan Doherty l2fwd_crypto_parse_nqueue(struct l2fwd_crypto_options *options, 1047387259bdSDeclan Doherty const char *q_arg) 1048387259bdSDeclan Doherty { 1049387259bdSDeclan Doherty char *end = NULL; 1050387259bdSDeclan Doherty unsigned long n; 1051387259bdSDeclan Doherty 1052387259bdSDeclan Doherty /* parse hexadecimal string */ 1053387259bdSDeclan Doherty n = strtoul(q_arg, &end, 10); 1054387259bdSDeclan Doherty if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1055387259bdSDeclan Doherty n = 0; 1056387259bdSDeclan Doherty else if (n >= MAX_RX_QUEUE_PER_LCORE) 1057387259bdSDeclan Doherty n = 0; 1058387259bdSDeclan Doherty 1059387259bdSDeclan Doherty options->nb_ports_per_lcore = n; 1060387259bdSDeclan Doherty if (options->nb_ports_per_lcore == 0) { 1061387259bdSDeclan Doherty printf("invalid number of ports selected\n"); 1062387259bdSDeclan Doherty return -1; 1063387259bdSDeclan Doherty } 1064387259bdSDeclan Doherty 1065387259bdSDeclan Doherty return 0; 1066387259bdSDeclan Doherty } 1067387259bdSDeclan Doherty 1068387259bdSDeclan Doherty /** Parse timer period */ 1069387259bdSDeclan Doherty static int 1070387259bdSDeclan Doherty l2fwd_crypto_parse_timer_period(struct l2fwd_crypto_options *options, 1071387259bdSDeclan Doherty const char *q_arg) 1072387259bdSDeclan Doherty { 1073387259bdSDeclan Doherty char *end = NULL; 10743c96262cSPablo de Lara unsigned long n; 1075387259bdSDeclan Doherty 1076387259bdSDeclan Doherty /* parse number string */ 10773c96262cSPablo de Lara n = (unsigned)strtol(q_arg, &end, 10); 1078387259bdSDeclan Doherty if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) 1079387259bdSDeclan Doherty n = 0; 1080387259bdSDeclan Doherty 1081ad509b4aSDeclan Doherty if (n >= MAX_TIMER_PERIOD) { 10823c96262cSPablo de Lara printf("Warning refresh period specified %lu is greater than " 10833c96262cSPablo de Lara "max value %lu! using max value", 1084ad509b4aSDeclan Doherty n, MAX_TIMER_PERIOD); 1085ad509b4aSDeclan Doherty n = MAX_TIMER_PERIOD; 1086ad509b4aSDeclan Doherty } 1087387259bdSDeclan Doherty 1088387259bdSDeclan Doherty options->refresh_period = n * 1000 * TIMER_MILLISECOND; 1089387259bdSDeclan Doherty 1090387259bdSDeclan Doherty return 0; 1091387259bdSDeclan Doherty } 1092387259bdSDeclan Doherty 1093387259bdSDeclan Doherty /** Generate default options for application */ 1094387259bdSDeclan Doherty static void 1095387259bdSDeclan Doherty l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) 1096387259bdSDeclan Doherty { 1097387259bdSDeclan Doherty srand(time(NULL)); 1098387259bdSDeclan Doherty 1099387259bdSDeclan Doherty options->portmask = 0xffffffff; 1100387259bdSDeclan Doherty options->nb_ports_per_lcore = 1; 1101387259bdSDeclan Doherty options->refresh_period = 10000; 1102387259bdSDeclan Doherty options->single_lcore = 0; 11033c96262cSPablo de Lara options->sessionless = 0; 1104387259bdSDeclan Doherty 1105387259bdSDeclan Doherty options->xform_chain = L2FWD_CRYPTO_CIPHER_HASH; 1106387259bdSDeclan Doherty 1107387259bdSDeclan Doherty /* Cipher Data */ 11081bd407faSFiona Trahe options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1109387259bdSDeclan Doherty options->cipher_xform.next = NULL; 11101df9c010SPablo de Lara options->ckey_param = 0; 11111df9c010SPablo de Lara options->iv_param = 0; 1112387259bdSDeclan Doherty 1113387259bdSDeclan Doherty options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; 1114387259bdSDeclan Doherty options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; 1115387259bdSDeclan Doherty 1116387259bdSDeclan Doherty /* Authentication Data */ 11171bd407faSFiona Trahe options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1118387259bdSDeclan Doherty options->auth_xform.next = NULL; 11191df9c010SPablo de Lara options->akey_param = 0; 1120617a7949SPablo de Lara options->aad_param = 0; 1121387259bdSDeclan Doherty 1122387259bdSDeclan Doherty options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; 112327cf2d1bSPablo de Lara options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; 1124387259bdSDeclan Doherty 112527cf2d1bSPablo de Lara options->type = CDEV_TYPE_ANY; 1126387259bdSDeclan Doherty } 1127387259bdSDeclan Doherty 1128387259bdSDeclan Doherty static void 1129387259bdSDeclan Doherty l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) 1130387259bdSDeclan Doherty { 1131387259bdSDeclan Doherty printf("Options:-\nn"); 1132387259bdSDeclan Doherty printf("portmask: %x\n", options->portmask); 1133387259bdSDeclan Doherty printf("ports per lcore: %u\n", options->nb_ports_per_lcore); 1134387259bdSDeclan Doherty printf("refresh period : %u\n", options->refresh_period); 1135387259bdSDeclan Doherty printf("single lcore mode: %s\n", 1136387259bdSDeclan Doherty options->single_lcore ? "enabled" : "disabled"); 1137387259bdSDeclan Doherty printf("stats_printing: %s\n", 1138ad509b4aSDeclan Doherty options->refresh_period == 0 ? "disabled" : "enabled"); 1139387259bdSDeclan Doherty 1140387259bdSDeclan Doherty printf("sessionless crypto: %s\n", 1141387259bdSDeclan Doherty options->sessionless ? "enabled" : "disabled"); 1142387259bdSDeclan Doherty } 1143387259bdSDeclan Doherty 1144387259bdSDeclan Doherty /* Parse the argument given in the command line of the application */ 1145387259bdSDeclan Doherty static int 1146387259bdSDeclan Doherty l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options, 1147387259bdSDeclan Doherty int argc, char **argv) 1148387259bdSDeclan Doherty { 1149387259bdSDeclan Doherty int opt, retval, option_index; 1150387259bdSDeclan Doherty char **argvopt = argv, *prgname = argv[0]; 1151387259bdSDeclan Doherty 1152387259bdSDeclan Doherty static struct option lgopts[] = { 1153387259bdSDeclan Doherty { "sessionless", no_argument, 0, 0 }, 1154387259bdSDeclan Doherty 1155387259bdSDeclan Doherty { "cdev_type", required_argument, 0, 0 }, 1156387259bdSDeclan Doherty { "chain", required_argument, 0, 0 }, 1157387259bdSDeclan Doherty 1158387259bdSDeclan Doherty { "cipher_algo", required_argument, 0, 0 }, 1159387259bdSDeclan Doherty { "cipher_op", required_argument, 0, 0 }, 1160387259bdSDeclan Doherty { "cipher_key", required_argument, 0, 0 }, 1161387259bdSDeclan Doherty 1162387259bdSDeclan Doherty { "auth_algo", required_argument, 0, 0 }, 1163387259bdSDeclan Doherty { "auth_op", required_argument, 0, 0 }, 1164387259bdSDeclan Doherty { "auth_key", required_argument, 0, 0 }, 1165387259bdSDeclan Doherty 1166387259bdSDeclan Doherty { "iv", required_argument, 0, 0 }, 1167617a7949SPablo de Lara { "aad", required_argument, 0, 0 }, 1168387259bdSDeclan Doherty 1169387259bdSDeclan Doherty { "sessionless", no_argument, 0, 0 }, 11703c96262cSPablo de Lara 1171387259bdSDeclan Doherty { NULL, 0, 0, 0 } 1172387259bdSDeclan Doherty }; 1173387259bdSDeclan Doherty 1174387259bdSDeclan Doherty l2fwd_crypto_default_options(options); 1175387259bdSDeclan Doherty 1176387259bdSDeclan Doherty while ((opt = getopt_long(argc, argvopt, "p:q:st:", lgopts, 1177387259bdSDeclan Doherty &option_index)) != EOF) { 1178387259bdSDeclan Doherty switch (opt) { 1179387259bdSDeclan Doherty /* long options */ 1180387259bdSDeclan Doherty case 0: 1181387259bdSDeclan Doherty retval = l2fwd_crypto_parse_args_long_options(options, 1182387259bdSDeclan Doherty lgopts, option_index); 1183387259bdSDeclan Doherty if (retval < 0) { 1184387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1185387259bdSDeclan Doherty return -1; 1186387259bdSDeclan Doherty } 1187387259bdSDeclan Doherty break; 1188387259bdSDeclan Doherty 1189387259bdSDeclan Doherty /* portmask */ 1190387259bdSDeclan Doherty case 'p': 1191387259bdSDeclan Doherty retval = l2fwd_crypto_parse_portmask(options, optarg); 1192387259bdSDeclan Doherty if (retval < 0) { 1193387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1194387259bdSDeclan Doherty return -1; 1195387259bdSDeclan Doherty } 1196387259bdSDeclan Doherty break; 1197387259bdSDeclan Doherty 1198387259bdSDeclan Doherty /* nqueue */ 1199387259bdSDeclan Doherty case 'q': 1200387259bdSDeclan Doherty retval = l2fwd_crypto_parse_nqueue(options, optarg); 1201387259bdSDeclan Doherty if (retval < 0) { 1202387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1203387259bdSDeclan Doherty return -1; 1204387259bdSDeclan Doherty } 1205387259bdSDeclan Doherty break; 1206387259bdSDeclan Doherty 1207387259bdSDeclan Doherty /* single */ 1208387259bdSDeclan Doherty case 's': 1209387259bdSDeclan Doherty options->single_lcore = 1; 1210387259bdSDeclan Doherty 1211387259bdSDeclan Doherty break; 1212387259bdSDeclan Doherty 1213387259bdSDeclan Doherty /* timer period */ 1214387259bdSDeclan Doherty case 't': 1215387259bdSDeclan Doherty retval = l2fwd_crypto_parse_timer_period(options, 1216387259bdSDeclan Doherty optarg); 1217387259bdSDeclan Doherty if (retval < 0) { 1218387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1219387259bdSDeclan Doherty return -1; 1220387259bdSDeclan Doherty } 1221387259bdSDeclan Doherty break; 1222387259bdSDeclan Doherty 1223387259bdSDeclan Doherty default: 1224387259bdSDeclan Doherty l2fwd_crypto_usage(prgname); 1225387259bdSDeclan Doherty return -1; 1226387259bdSDeclan Doherty } 1227387259bdSDeclan Doherty } 1228387259bdSDeclan Doherty 1229387259bdSDeclan Doherty 1230387259bdSDeclan Doherty if (optind >= 0) 1231387259bdSDeclan Doherty argv[optind-1] = prgname; 1232387259bdSDeclan Doherty 1233387259bdSDeclan Doherty retval = optind-1; 1234387259bdSDeclan Doherty optind = 0; /* reset getopt lib */ 1235387259bdSDeclan Doherty 1236387259bdSDeclan Doherty return retval; 1237387259bdSDeclan Doherty } 1238387259bdSDeclan Doherty 1239387259bdSDeclan Doherty /* Check the link status of all ports in up to 9s, and print them finally */ 1240387259bdSDeclan Doherty static void 1241387259bdSDeclan Doherty check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) 1242387259bdSDeclan Doherty { 1243387259bdSDeclan Doherty #define CHECK_INTERVAL 100 /* 100ms */ 1244387259bdSDeclan Doherty #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1245387259bdSDeclan Doherty uint8_t portid, count, all_ports_up, print_flag = 0; 1246387259bdSDeclan Doherty struct rte_eth_link link; 1247387259bdSDeclan Doherty 1248387259bdSDeclan Doherty printf("\nChecking link status"); 1249387259bdSDeclan Doherty fflush(stdout); 1250387259bdSDeclan Doherty for (count = 0; count <= MAX_CHECK_TIME; count++) { 1251387259bdSDeclan Doherty all_ports_up = 1; 1252387259bdSDeclan Doherty for (portid = 0; portid < port_num; portid++) { 1253387259bdSDeclan Doherty if ((port_mask & (1 << portid)) == 0) 1254387259bdSDeclan Doherty continue; 1255387259bdSDeclan Doherty memset(&link, 0, sizeof(link)); 1256387259bdSDeclan Doherty rte_eth_link_get_nowait(portid, &link); 1257387259bdSDeclan Doherty /* print link status if flag set */ 1258387259bdSDeclan Doherty if (print_flag == 1) { 1259387259bdSDeclan Doherty if (link.link_status) 1260387259bdSDeclan Doherty printf("Port %d Link Up - speed %u " 1261387259bdSDeclan Doherty "Mbps - %s\n", (uint8_t)portid, 1262387259bdSDeclan Doherty (unsigned)link.link_speed, 1263387259bdSDeclan Doherty (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1264387259bdSDeclan Doherty ("full-duplex") : ("half-duplex\n")); 1265387259bdSDeclan Doherty else 1266387259bdSDeclan Doherty printf("Port %d Link Down\n", 1267387259bdSDeclan Doherty (uint8_t)portid); 1268387259bdSDeclan Doherty continue; 1269387259bdSDeclan Doherty } 1270387259bdSDeclan Doherty /* clear all_ports_up flag if any link down */ 1271387259bdSDeclan Doherty if (link.link_status == 0) { 1272387259bdSDeclan Doherty all_ports_up = 0; 1273387259bdSDeclan Doherty break; 1274387259bdSDeclan Doherty } 1275387259bdSDeclan Doherty } 1276387259bdSDeclan Doherty /* after finally printing all link status, get out */ 1277387259bdSDeclan Doherty if (print_flag == 1) 1278387259bdSDeclan Doherty break; 1279387259bdSDeclan Doherty 1280387259bdSDeclan Doherty if (all_ports_up == 0) { 1281387259bdSDeclan Doherty printf("."); 1282387259bdSDeclan Doherty fflush(stdout); 1283387259bdSDeclan Doherty rte_delay_ms(CHECK_INTERVAL); 1284387259bdSDeclan Doherty } 1285387259bdSDeclan Doherty 1286387259bdSDeclan Doherty /* set the print_flag if all ports up or timeout */ 1287387259bdSDeclan Doherty if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1288387259bdSDeclan Doherty print_flag = 1; 1289387259bdSDeclan Doherty printf("done\n"); 1290387259bdSDeclan Doherty } 1291387259bdSDeclan Doherty } 1292387259bdSDeclan Doherty } 1293387259bdSDeclan Doherty 129427cf2d1bSPablo de Lara /* Check if device has to be HW/SW or any */ 1295387259bdSDeclan Doherty static int 129627cf2d1bSPablo de Lara check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_info) 129727cf2d1bSPablo de Lara { 129827cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_HW && 129927cf2d1bSPablo de Lara (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 130027cf2d1bSPablo de Lara return 0; 130127cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_SW && 130227cf2d1bSPablo de Lara !(dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) 130327cf2d1bSPablo de Lara return 0; 130427cf2d1bSPablo de Lara if (options->type == CDEV_TYPE_ANY) 130527cf2d1bSPablo de Lara return 0; 130627cf2d1bSPablo de Lara 130727cf2d1bSPablo de Lara return -1; 130827cf2d1bSPablo de Lara } 130927cf2d1bSPablo de Lara 131027cf2d1bSPablo de Lara static int 131127cf2d1bSPablo de Lara initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, 131227cf2d1bSPablo de Lara uint8_t *enabled_cdevs) 1313387259bdSDeclan Doherty { 1314387259bdSDeclan Doherty unsigned i, cdev_id, cdev_count, enabled_cdev_count = 0; 131527cf2d1bSPablo de Lara const struct rte_cryptodev_capabilities *cap; 131627cf2d1bSPablo de Lara enum rte_crypto_auth_algorithm cap_auth_algo; 131727cf2d1bSPablo de Lara enum rte_crypto_auth_algorithm opt_auth_algo; 131827cf2d1bSPablo de Lara enum rte_crypto_cipher_algorithm cap_cipher_algo; 131927cf2d1bSPablo de Lara enum rte_crypto_cipher_algorithm opt_cipher_algo; 1320387259bdSDeclan Doherty int retval; 1321387259bdSDeclan Doherty 132227cf2d1bSPablo de Lara cdev_count = rte_cryptodev_count(); 132327cf2d1bSPablo de Lara if (cdev_count == 0) { 132427cf2d1bSPablo de Lara printf("No crypto devices available\n"); 1325387259bdSDeclan Doherty return -1; 1326387259bdSDeclan Doherty } 1327387259bdSDeclan Doherty 132827cf2d1bSPablo de Lara for (cdev_id = 0; cdev_id < cdev_count && enabled_cdev_count < nb_ports; 1329387259bdSDeclan Doherty cdev_id++) { 1330387259bdSDeclan Doherty struct rte_cryptodev_qp_conf qp_conf; 1331387259bdSDeclan Doherty struct rte_cryptodev_info dev_info; 1332387259bdSDeclan Doherty 1333387259bdSDeclan Doherty struct rte_cryptodev_config conf = { 1334387259bdSDeclan Doherty .nb_queue_pairs = 1, 1335387259bdSDeclan Doherty .socket_id = SOCKET_ID_ANY, 1336387259bdSDeclan Doherty .session_mp = { 1337387259bdSDeclan Doherty .nb_objs = 2048, 1338387259bdSDeclan Doherty .cache_size = 64 1339387259bdSDeclan Doherty } 1340387259bdSDeclan Doherty }; 1341387259bdSDeclan Doherty 1342387259bdSDeclan Doherty rte_cryptodev_info_get(cdev_id, &dev_info); 1343387259bdSDeclan Doherty 134427cf2d1bSPablo de Lara /* Set cipher parameters */ 134527cf2d1bSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 134627cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 134727cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { 134827cf2d1bSPablo de Lara /* Check if device supports cipher algo */ 134927cf2d1bSPablo de Lara i = 0; 135027cf2d1bSPablo de Lara opt_cipher_algo = options->cipher_xform.cipher.algo; 135127cf2d1bSPablo de Lara cap = &dev_info.capabilities[i]; 135227cf2d1bSPablo de Lara while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 135327cf2d1bSPablo de Lara cap_cipher_algo = cap->sym.cipher.algo; 135427cf2d1bSPablo de Lara if (cap->sym.xform_type == 135527cf2d1bSPablo de Lara RTE_CRYPTO_SYM_XFORM_CIPHER) { 135627cf2d1bSPablo de Lara if (cap_cipher_algo == opt_cipher_algo) { 135727cf2d1bSPablo de Lara if (check_type(options, &dev_info) == 0) 135827cf2d1bSPablo de Lara break; 135927cf2d1bSPablo de Lara } 136027cf2d1bSPablo de Lara } 136127cf2d1bSPablo de Lara cap = &dev_info.capabilities[++i]; 136227cf2d1bSPablo de Lara } 1363387259bdSDeclan Doherty 136427cf2d1bSPablo de Lara if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 136527cf2d1bSPablo de Lara printf("Algorithm %s not supported by cryptodev %u" 136627cf2d1bSPablo de Lara " or device not of preferred type (%s)\n", 136727cf2d1bSPablo de Lara options->string_cipher_algo, cdev_id, 136827cf2d1bSPablo de Lara options->string_type); 136927cf2d1bSPablo de Lara continue; 137027cf2d1bSPablo de Lara } 137127cf2d1bSPablo de Lara 137227cf2d1bSPablo de Lara options->block_size = cap->sym.cipher.block_size; 137327cf2d1bSPablo de Lara options->iv.length = cap->sym.cipher.iv_size.min; 137427cf2d1bSPablo de Lara options->cipher_xform.cipher.key.length = 137527cf2d1bSPablo de Lara cap->sym.cipher.key_size.min; 137627cf2d1bSPablo de Lara if (!options->ckey_param) 137727cf2d1bSPablo de Lara generate_random_key( 137827cf2d1bSPablo de Lara options->cipher_xform.cipher.key.data, 137927cf2d1bSPablo de Lara options->cipher_xform.cipher.key.length); 138027cf2d1bSPablo de Lara 138127cf2d1bSPablo de Lara } 138227cf2d1bSPablo de Lara 138327cf2d1bSPablo de Lara /* Set auth parameters */ 138427cf2d1bSPablo de Lara if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || 138527cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || 138627cf2d1bSPablo de Lara options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { 138727cf2d1bSPablo de Lara /* Check if device supports auth algo */ 138827cf2d1bSPablo de Lara i = 0; 138927cf2d1bSPablo de Lara opt_auth_algo = options->auth_xform.auth.algo; 139027cf2d1bSPablo de Lara cap = &dev_info.capabilities[i]; 139127cf2d1bSPablo de Lara while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { 139227cf2d1bSPablo de Lara cap_auth_algo = cap->sym.auth.algo; 139327cf2d1bSPablo de Lara if ((cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) && 139427cf2d1bSPablo de Lara (cap_auth_algo == opt_auth_algo) && 139527cf2d1bSPablo de Lara (check_type(options, &dev_info) == 0)) { 139627cf2d1bSPablo de Lara break; 139727cf2d1bSPablo de Lara } 139827cf2d1bSPablo de Lara cap = &dev_info.capabilities[++i]; 139927cf2d1bSPablo de Lara } 140027cf2d1bSPablo de Lara 140127cf2d1bSPablo de Lara if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { 140227cf2d1bSPablo de Lara printf("Algorithm %s not supported by cryptodev %u" 140327cf2d1bSPablo de Lara " or device not of preferred type (%s)\n", 140427cf2d1bSPablo de Lara options->string_auth_algo, cdev_id, 140527cf2d1bSPablo de Lara options->string_type); 140627cf2d1bSPablo de Lara continue; 140727cf2d1bSPablo de Lara } 140827cf2d1bSPablo de Lara 140927cf2d1bSPablo de Lara options->block_size = cap->sym.auth.block_size; 141027cf2d1bSPablo de Lara options->auth_xform.auth.add_auth_data_length = 141127cf2d1bSPablo de Lara cap->sym.auth.aad_size.min; 141227cf2d1bSPablo de Lara options->auth_xform.auth.digest_length = 141327cf2d1bSPablo de Lara cap->sym.auth.digest_size.min; 141427cf2d1bSPablo de Lara options->auth_xform.auth.key.length = 141527cf2d1bSPablo de Lara cap->sym.auth.key_size.min; 141627cf2d1bSPablo de Lara 141727cf2d1bSPablo de Lara if (!options->akey_param) 141827cf2d1bSPablo de Lara generate_random_key( 141927cf2d1bSPablo de Lara options->auth_xform.auth.key.data, 142027cf2d1bSPablo de Lara options->auth_xform.auth.key.length); 142127cf2d1bSPablo de Lara } 1422387259bdSDeclan Doherty 1423387259bdSDeclan Doherty retval = rte_cryptodev_configure(cdev_id, &conf); 1424387259bdSDeclan Doherty if (retval < 0) { 1425387259bdSDeclan Doherty printf("Failed to configure cryptodev %u", cdev_id); 1426387259bdSDeclan Doherty return -1; 1427387259bdSDeclan Doherty } 1428387259bdSDeclan Doherty 1429387259bdSDeclan Doherty qp_conf.nb_descriptors = 2048; 1430387259bdSDeclan Doherty 1431387259bdSDeclan Doherty retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, 1432387259bdSDeclan Doherty SOCKET_ID_ANY); 1433387259bdSDeclan Doherty if (retval < 0) { 1434387259bdSDeclan Doherty printf("Failed to setup queue pair %u on cryptodev %u", 1435387259bdSDeclan Doherty 0, cdev_id); 1436387259bdSDeclan Doherty return -1; 1437387259bdSDeclan Doherty } 1438387259bdSDeclan Doherty 1439387259bdSDeclan Doherty l2fwd_enabled_crypto_mask |= (1 << cdev_id); 1440387259bdSDeclan Doherty 144127cf2d1bSPablo de Lara enabled_cdevs[cdev_id] = 1; 1442387259bdSDeclan Doherty enabled_cdev_count++; 1443387259bdSDeclan Doherty } 1444387259bdSDeclan Doherty 1445387259bdSDeclan Doherty return enabled_cdev_count; 1446387259bdSDeclan Doherty } 1447387259bdSDeclan Doherty 1448387259bdSDeclan Doherty static int 1449387259bdSDeclan Doherty initialize_ports(struct l2fwd_crypto_options *options) 1450387259bdSDeclan Doherty { 1451387259bdSDeclan Doherty uint8_t last_portid, portid; 1452387259bdSDeclan Doherty unsigned enabled_portcount = 0; 1453387259bdSDeclan Doherty unsigned nb_ports = rte_eth_dev_count(); 1454387259bdSDeclan Doherty 1455387259bdSDeclan Doherty if (nb_ports == 0) { 1456387259bdSDeclan Doherty printf("No Ethernet ports - bye\n"); 1457387259bdSDeclan Doherty return -1; 1458387259bdSDeclan Doherty } 1459387259bdSDeclan Doherty 1460387259bdSDeclan Doherty if (nb_ports > RTE_MAX_ETHPORTS) 1461387259bdSDeclan Doherty nb_ports = RTE_MAX_ETHPORTS; 1462387259bdSDeclan Doherty 1463387259bdSDeclan Doherty /* Reset l2fwd_dst_ports */ 1464387259bdSDeclan Doherty for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) 1465387259bdSDeclan Doherty l2fwd_dst_ports[portid] = 0; 1466387259bdSDeclan Doherty 1467387259bdSDeclan Doherty for (last_portid = 0, portid = 0; portid < nb_ports; portid++) { 1468387259bdSDeclan Doherty int retval; 1469387259bdSDeclan Doherty 1470387259bdSDeclan Doherty /* Skip ports that are not enabled */ 1471387259bdSDeclan Doherty if ((options->portmask & (1 << portid)) == 0) 1472387259bdSDeclan Doherty continue; 1473387259bdSDeclan Doherty 1474387259bdSDeclan Doherty /* init port */ 1475387259bdSDeclan Doherty printf("Initializing port %u... ", (unsigned) portid); 1476387259bdSDeclan Doherty fflush(stdout); 1477387259bdSDeclan Doherty retval = rte_eth_dev_configure(portid, 1, 1, &port_conf); 1478387259bdSDeclan Doherty if (retval < 0) { 1479387259bdSDeclan Doherty printf("Cannot configure device: err=%d, port=%u\n", 1480387259bdSDeclan Doherty retval, (unsigned) portid); 1481387259bdSDeclan Doherty return -1; 1482387259bdSDeclan Doherty } 1483387259bdSDeclan Doherty 1484387259bdSDeclan Doherty /* init one RX queue */ 1485387259bdSDeclan Doherty fflush(stdout); 1486387259bdSDeclan Doherty retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, 1487387259bdSDeclan Doherty rte_eth_dev_socket_id(portid), 1488387259bdSDeclan Doherty NULL, l2fwd_pktmbuf_pool); 1489387259bdSDeclan Doherty if (retval < 0) { 1490387259bdSDeclan Doherty printf("rte_eth_rx_queue_setup:err=%d, port=%u\n", 1491387259bdSDeclan Doherty retval, (unsigned) portid); 1492387259bdSDeclan Doherty return -1; 1493387259bdSDeclan Doherty } 1494387259bdSDeclan Doherty 1495387259bdSDeclan Doherty /* init one TX queue on each port */ 1496387259bdSDeclan Doherty fflush(stdout); 1497387259bdSDeclan Doherty retval = rte_eth_tx_queue_setup(portid, 0, nb_txd, 1498387259bdSDeclan Doherty rte_eth_dev_socket_id(portid), 1499387259bdSDeclan Doherty NULL); 1500387259bdSDeclan Doherty if (retval < 0) { 1501387259bdSDeclan Doherty printf("rte_eth_tx_queue_setup:err=%d, port=%u\n", 1502387259bdSDeclan Doherty retval, (unsigned) portid); 1503387259bdSDeclan Doherty 1504387259bdSDeclan Doherty return -1; 1505387259bdSDeclan Doherty } 1506387259bdSDeclan Doherty 1507387259bdSDeclan Doherty /* Start device */ 1508387259bdSDeclan Doherty retval = rte_eth_dev_start(portid); 1509387259bdSDeclan Doherty if (retval < 0) { 1510387259bdSDeclan Doherty printf("rte_eth_dev_start:err=%d, port=%u\n", 1511387259bdSDeclan Doherty retval, (unsigned) portid); 1512387259bdSDeclan Doherty return -1; 1513387259bdSDeclan Doherty } 1514387259bdSDeclan Doherty 1515387259bdSDeclan Doherty rte_eth_promiscuous_enable(portid); 1516387259bdSDeclan Doherty 1517387259bdSDeclan Doherty rte_eth_macaddr_get(portid, &l2fwd_ports_eth_addr[portid]); 1518387259bdSDeclan Doherty 1519387259bdSDeclan Doherty printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", 1520387259bdSDeclan Doherty (unsigned) portid, 1521387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[0], 1522387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[1], 1523387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[2], 1524387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[3], 1525387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[4], 1526387259bdSDeclan Doherty l2fwd_ports_eth_addr[portid].addr_bytes[5]); 1527387259bdSDeclan Doherty 1528387259bdSDeclan Doherty /* initialize port stats */ 1529387259bdSDeclan Doherty memset(&port_statistics, 0, sizeof(port_statistics)); 1530387259bdSDeclan Doherty 1531387259bdSDeclan Doherty /* Setup port forwarding table */ 1532387259bdSDeclan Doherty if (enabled_portcount % 2) { 1533387259bdSDeclan Doherty l2fwd_dst_ports[portid] = last_portid; 1534387259bdSDeclan Doherty l2fwd_dst_ports[last_portid] = portid; 1535387259bdSDeclan Doherty } else { 1536387259bdSDeclan Doherty last_portid = portid; 1537387259bdSDeclan Doherty } 1538387259bdSDeclan Doherty 1539387259bdSDeclan Doherty l2fwd_enabled_port_mask |= (1 << portid); 1540387259bdSDeclan Doherty enabled_portcount++; 1541387259bdSDeclan Doherty } 1542387259bdSDeclan Doherty 1543387259bdSDeclan Doherty if (enabled_portcount == 1) { 1544387259bdSDeclan Doherty l2fwd_dst_ports[last_portid] = last_portid; 1545387259bdSDeclan Doherty } else if (enabled_portcount % 2) { 1546387259bdSDeclan Doherty printf("odd number of ports in portmask- bye\n"); 1547387259bdSDeclan Doherty return -1; 1548387259bdSDeclan Doherty } 1549387259bdSDeclan Doherty 1550387259bdSDeclan Doherty check_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask); 1551387259bdSDeclan Doherty 1552387259bdSDeclan Doherty return enabled_portcount; 1553387259bdSDeclan Doherty } 1554387259bdSDeclan Doherty 15551df9c010SPablo de Lara static void 15561df9c010SPablo de Lara reserve_key_memory(struct l2fwd_crypto_options *options) 15571df9c010SPablo de Lara { 15581df9c010SPablo de Lara options->cipher_xform.cipher.key.data = rte_malloc("crypto key", 15591df9c010SPablo de Lara MAX_KEY_SIZE, 0); 15601df9c010SPablo de Lara if (options->cipher_xform.cipher.key.data == NULL) 15611df9c010SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key"); 15621df9c010SPablo de Lara 15631df9c010SPablo de Lara 15641df9c010SPablo de Lara options->auth_xform.auth.key.data = rte_malloc("auth key", 15651df9c010SPablo de Lara MAX_KEY_SIZE, 0); 15661df9c010SPablo de Lara if (options->auth_xform.auth.key.data == NULL) 15671df9c010SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key"); 15681df9c010SPablo de Lara 15691df9c010SPablo de Lara options->iv.data = rte_malloc("iv", MAX_KEY_SIZE, 0); 15701df9c010SPablo de Lara if (options->iv.data == NULL) 15711df9c010SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for IV"); 15721df9c010SPablo de Lara options->iv.phys_addr = rte_malloc_virt2phy(options->iv.data); 1573617a7949SPablo de Lara 1574617a7949SPablo de Lara options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); 1575617a7949SPablo de Lara if (options->aad.data == NULL) 1576617a7949SPablo de Lara rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD"); 1577617a7949SPablo de Lara options->aad.phys_addr = rte_malloc_virt2phy(options->aad.data); 15781df9c010SPablo de Lara } 15791df9c010SPablo de Lara 1580387259bdSDeclan Doherty int 1581387259bdSDeclan Doherty main(int argc, char **argv) 1582387259bdSDeclan Doherty { 1583387259bdSDeclan Doherty struct lcore_queue_conf *qconf; 1584387259bdSDeclan Doherty struct l2fwd_crypto_options options; 1585387259bdSDeclan Doherty 1586387259bdSDeclan Doherty uint8_t nb_ports, nb_cryptodevs, portid, cdev_id; 1587387259bdSDeclan Doherty unsigned lcore_id, rx_lcore_id; 1588387259bdSDeclan Doherty int ret, enabled_cdevcount, enabled_portcount; 158927cf2d1bSPablo de Lara uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS] = {0}; 1590387259bdSDeclan Doherty 1591387259bdSDeclan Doherty /* init EAL */ 1592387259bdSDeclan Doherty ret = rte_eal_init(argc, argv); 1593387259bdSDeclan Doherty if (ret < 0) 1594387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); 1595387259bdSDeclan Doherty argc -= ret; 1596387259bdSDeclan Doherty argv += ret; 1597387259bdSDeclan Doherty 15981df9c010SPablo de Lara /* reserve memory for Cipher/Auth key and IV */ 15991df9c010SPablo de Lara reserve_key_memory(&options); 16001df9c010SPablo de Lara 1601387259bdSDeclan Doherty /* parse application arguments (after the EAL ones) */ 1602387259bdSDeclan Doherty ret = l2fwd_crypto_parse_args(&options, argc, argv); 1603387259bdSDeclan Doherty if (ret < 0) 1604387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Invalid L2FWD-CRYPTO arguments\n"); 1605387259bdSDeclan Doherty 1606387259bdSDeclan Doherty /* create the mbuf pool */ 1607c0f87eb5SDeclan Doherty l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 512, 1608c0f87eb5SDeclan Doherty sizeof(struct rte_crypto_op), 1609c0f87eb5SDeclan Doherty RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 1610387259bdSDeclan Doherty if (l2fwd_pktmbuf_pool == NULL) 1611387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); 1612387259bdSDeclan Doherty 1613387259bdSDeclan Doherty /* create crypto op pool */ 1614c0f87eb5SDeclan Doherty l2fwd_crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool", 1615c0f87eb5SDeclan Doherty RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, 0, 1616c0f87eb5SDeclan Doherty rte_socket_id()); 1617c0f87eb5SDeclan Doherty if (l2fwd_crypto_op_pool == NULL) 1618387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n"); 1619387259bdSDeclan Doherty 1620387259bdSDeclan Doherty /* Enable Ethernet ports */ 1621387259bdSDeclan Doherty enabled_portcount = initialize_ports(&options); 1622387259bdSDeclan Doherty if (enabled_portcount < 1) 1623387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, "Failed to initial Ethernet ports\n"); 1624387259bdSDeclan Doherty 1625387259bdSDeclan Doherty nb_ports = rte_eth_dev_count(); 1626387259bdSDeclan Doherty /* Initialize the port/queue configuration of each logical core */ 1627387259bdSDeclan Doherty for (rx_lcore_id = 0, qconf = NULL, portid = 0; 1628387259bdSDeclan Doherty portid < nb_ports; portid++) { 1629387259bdSDeclan Doherty 1630387259bdSDeclan Doherty /* skip ports that are not enabled */ 1631387259bdSDeclan Doherty if ((options.portmask & (1 << portid)) == 0) 1632387259bdSDeclan Doherty continue; 1633387259bdSDeclan Doherty 1634387259bdSDeclan Doherty if (options.single_lcore && qconf == NULL) { 1635387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 1636387259bdSDeclan Doherty rx_lcore_id++; 1637387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 1638387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 1639387259bdSDeclan Doherty "Not enough cores\n"); 1640387259bdSDeclan Doherty } 1641387259bdSDeclan Doherty } else if (!options.single_lcore) { 1642387259bdSDeclan Doherty /* get the lcore_id for this port */ 1643387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 1644387259bdSDeclan Doherty lcore_queue_conf[rx_lcore_id].nb_rx_ports == 1645387259bdSDeclan Doherty options.nb_ports_per_lcore) { 1646387259bdSDeclan Doherty rx_lcore_id++; 1647387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 1648387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 1649387259bdSDeclan Doherty "Not enough cores\n"); 1650387259bdSDeclan Doherty } 1651387259bdSDeclan Doherty } 1652387259bdSDeclan Doherty 1653387259bdSDeclan Doherty /* Assigned a new logical core in the loop above. */ 1654387259bdSDeclan Doherty if (qconf != &lcore_queue_conf[rx_lcore_id]) 1655387259bdSDeclan Doherty qconf = &lcore_queue_conf[rx_lcore_id]; 1656387259bdSDeclan Doherty 1657387259bdSDeclan Doherty qconf->rx_port_list[qconf->nb_rx_ports] = portid; 1658387259bdSDeclan Doherty qconf->nb_rx_ports++; 1659387259bdSDeclan Doherty 1660387259bdSDeclan Doherty printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned)portid); 1661387259bdSDeclan Doherty } 1662387259bdSDeclan Doherty 1663387259bdSDeclan Doherty /* Enable Crypto devices */ 166427cf2d1bSPablo de Lara enabled_cdevcount = initialize_cryptodevs(&options, enabled_portcount, 166527cf2d1bSPablo de Lara enabled_cdevs); 166627cf2d1bSPablo de Lara if (enabled_cdevcount < 0) 166727cf2d1bSPablo de Lara rte_exit(EXIT_FAILURE, "Failed to initialize crypto devices\n"); 166827cf2d1bSPablo de Lara 166927cf2d1bSPablo de Lara if (enabled_cdevcount < enabled_portcount) 167027cf2d1bSPablo de Lara rte_exit(EXIT_FAILURE, "Number of capable crypto devices (%d) " 167127cf2d1bSPablo de Lara "has to be more or equal to number of ports (%d)\n", 167227cf2d1bSPablo de Lara enabled_cdevcount, enabled_portcount); 1673387259bdSDeclan Doherty 1674387259bdSDeclan Doherty nb_cryptodevs = rte_cryptodev_count(); 167527cf2d1bSPablo de Lara 167627cf2d1bSPablo de Lara /* Initialize the port/cryptodev configuration of each logical core */ 1677387259bdSDeclan Doherty for (rx_lcore_id = 0, qconf = NULL, cdev_id = 0; 1678387259bdSDeclan Doherty cdev_id < nb_cryptodevs && enabled_cdevcount; 1679387259bdSDeclan Doherty cdev_id++) { 168027cf2d1bSPablo de Lara /* Crypto op not supported by crypto device */ 168127cf2d1bSPablo de Lara if (!enabled_cdevs[cdev_id]) 1682387259bdSDeclan Doherty continue; 1683387259bdSDeclan Doherty 1684387259bdSDeclan Doherty if (options.single_lcore && qconf == NULL) { 1685387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0) { 1686387259bdSDeclan Doherty rx_lcore_id++; 1687387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 1688387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 1689387259bdSDeclan Doherty "Not enough cores\n"); 1690387259bdSDeclan Doherty } 1691387259bdSDeclan Doherty } else if (!options.single_lcore) { 1692387259bdSDeclan Doherty /* get the lcore_id for this port */ 1693387259bdSDeclan Doherty while (rte_lcore_is_enabled(rx_lcore_id) == 0 || 1694387259bdSDeclan Doherty lcore_queue_conf[rx_lcore_id].nb_crypto_devs == 1695387259bdSDeclan Doherty options.nb_ports_per_lcore) { 1696387259bdSDeclan Doherty rx_lcore_id++; 1697387259bdSDeclan Doherty if (rx_lcore_id >= RTE_MAX_LCORE) 1698387259bdSDeclan Doherty rte_exit(EXIT_FAILURE, 1699387259bdSDeclan Doherty "Not enough cores\n"); 1700387259bdSDeclan Doherty } 1701387259bdSDeclan Doherty } 1702387259bdSDeclan Doherty 1703387259bdSDeclan Doherty /* Assigned a new logical core in the loop above. */ 1704387259bdSDeclan Doherty if (qconf != &lcore_queue_conf[rx_lcore_id]) 1705387259bdSDeclan Doherty qconf = &lcore_queue_conf[rx_lcore_id]; 1706387259bdSDeclan Doherty 1707387259bdSDeclan Doherty qconf->cryptodev_list[qconf->nb_crypto_devs] = cdev_id; 1708387259bdSDeclan Doherty qconf->nb_crypto_devs++; 1709387259bdSDeclan Doherty 1710387259bdSDeclan Doherty enabled_cdevcount--; 1711387259bdSDeclan Doherty 1712387259bdSDeclan Doherty printf("Lcore %u: cryptodev %u\n", rx_lcore_id, 1713387259bdSDeclan Doherty (unsigned)cdev_id); 1714387259bdSDeclan Doherty } 1715387259bdSDeclan Doherty 1716387259bdSDeclan Doherty /* launch per-lcore init on every lcore */ 1717387259bdSDeclan Doherty rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, (void *)&options, 1718387259bdSDeclan Doherty CALL_MASTER); 1719387259bdSDeclan Doherty RTE_LCORE_FOREACH_SLAVE(lcore_id) { 1720387259bdSDeclan Doherty if (rte_eal_wait_lcore(lcore_id) < 0) 1721387259bdSDeclan Doherty return -1; 1722387259bdSDeclan Doherty } 1723387259bdSDeclan Doherty 1724387259bdSDeclan Doherty return 0; 1725387259bdSDeclan Doherty } 1726