diff options
Diffstat (limited to 'app')
91 files changed, 8396 insertions, 2862 deletions
diff --git a/app/Makefile b/app/Makefile index 1151e094..30ec292a 100644 --- a/app/Makefile +++ b/app/Makefile @@ -37,5 +37,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_test DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info +DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/app/pdump/Makefile b/app/pdump/Makefile new file mode 100644 index 00000000..d85bb08e --- /dev/null +++ b/app/pdump/Makefile @@ -0,0 +1,49 @@ +# BSD LICENSE +# +# Copyright(c) 2016 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(RTE_SDK)/mk/rte.vars.mk + +ifeq ($(CONFIG_RTE_LIBRTE_PDUMP),y) + +APP = dpdk_pdump + +CFLAGS += $(WERROR_FLAGS) + +# all source are stored in SRCS-y + +SRCS-y := main.c + +# this application needs libraries first +DEPDIRS-y += lib + +include $(RTE_SDK)/mk/rte.app.mk + +endif diff --git a/app/pdump/main.c b/app/pdump/main.c new file mode 100644 index 00000000..2087c159 --- /dev/null +++ b/app/pdump/main.c @@ -0,0 +1,844 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <inttypes.h> +#include <stdlib.h> +#include <getopt.h> +#include <signal.h> +#include <stdbool.h> +#include <net/if.h> + +#include <rte_eal.h> +#include <rte_common.h> +#include <rte_debug.h> +#include <rte_ethdev.h> +#include <rte_memory.h> +#include <rte_lcore.h> +#include <rte_branch_prediction.h> +#include <rte_errno.h> +#include <rte_dev.h> +#include <rte_kvargs.h> +#include <rte_mempool.h> +#include <rte_ring.h> +#include <rte_pdump.h> + +#define PDUMP_PORT_ARG "port" +#define PDUMP_PCI_ARG "device_id" +#define PDUMP_QUEUE_ARG "queue" +#define PDUMP_DIR_ARG "dir" +#define PDUMP_RX_DEV_ARG "rx-dev" +#define PDUMP_TX_DEV_ARG "tx-dev" +#define PDUMP_RING_SIZE_ARG "ring-size" +#define PDUMP_MSIZE_ARG "mbuf-size" +#define PDUMP_NUM_MBUFS_ARG "total-num-mbufs" + +#define VDEV_PCAP "eth_pcap_%s_%d,tx_pcap=%s" +#define VDEV_IFACE "eth_pcap_%s_%d,tx_iface=%s" +#define TX_STREAM_SIZE 64 + +#define MP_NAME "pdump_pool_%d" + +#define RX_RING "rx_ring_%d" +#define TX_RING "tx_ring_%d" + +#define RX_STR "rx" +#define TX_STR "tx" + +/* Maximum long option length for option parsing. */ +#define APP_ARG_TCPDUMP_MAX_TUPLES 54 +#define MBUF_POOL_CACHE_SIZE 250 +#define TX_DESC_PER_QUEUE 512 +#define RX_DESC_PER_QUEUE 128 +#define MBUFS_PER_POOL 65535 +#define MAX_LONG_OPT_SZ 64 +#define RING_SIZE 16384 +#define SIZE 256 +#define BURST_SIZE 32 +#define NUM_VDEVS 2 + +#define RTE_RING_SZ_MASK (unsigned)(0x0fffffff) /**< Ring size mask */ +/* true if x is a power of 2 */ +#define POWEROF2(x) ((((x)-1) & (x)) == 0) + +enum pdump_en_dis { + DISABLE = 1, + ENABLE = 2 +}; + +enum pcap_stream { + IFACE = 1, + PCAP = 2 +}; + +enum pdump_by { + PORT_ID = 1, + DEVICE_ID = 2 +}; + +const char *valid_pdump_arguments[] = { + PDUMP_PORT_ARG, + PDUMP_PCI_ARG, + PDUMP_QUEUE_ARG, + PDUMP_DIR_ARG, + PDUMP_RX_DEV_ARG, + PDUMP_TX_DEV_ARG, + PDUMP_RING_SIZE_ARG, + PDUMP_MSIZE_ARG, + PDUMP_NUM_MBUFS_ARG, + NULL +}; + +struct pdump_stats { + uint64_t dequeue_pkts; + uint64_t tx_pkts; + uint64_t freed_pkts; +}; + +struct pdump_tuples { + /* cli params */ + uint8_t port; + char *device_id; + uint16_t queue; + char rx_dev[TX_STREAM_SIZE]; + char tx_dev[TX_STREAM_SIZE]; + uint32_t ring_size; + uint16_t mbuf_data_size; + uint32_t total_num_mbufs; + + /* params for library API call */ + uint32_t dir; + struct rte_mempool *mp; + struct rte_ring *rx_ring; + struct rte_ring *tx_ring; + + /* params for packet dumping */ + enum pdump_by dump_by_type; + int rx_vdev_id; + int tx_vdev_id; + enum pcap_stream rx_vdev_stream_type; + enum pcap_stream tx_vdev_stream_type; + bool single_pdump_dev; + + /* stats */ + struct pdump_stats stats; +} __rte_cache_aligned; +static struct pdump_tuples pdump_t[APP_ARG_TCPDUMP_MAX_TUPLES]; + +struct parse_val { + uint64_t min; + uint64_t max; + uint64_t val; +}; + +int num_tuples; +static struct rte_eth_conf port_conf_default; +volatile uint8_t quit_signal; + +/**< display usage */ +static void +pdump_usage(const char *prgname) +{ + printf("usage: %s [EAL options] -- --pdump " + "'(port=<port id> | device_id=<pci id or vdev name>)," + "(queue=<queue_id>)," + "(rx-dev=<iface or pcap file> |" + " tx-dev=<iface or pcap file>," + "[ring-size=<ring size>default:16384]," + "[mbuf-size=<mbuf data size>default:2176]," + "[total-num-mbufs=<number of mbufs>default:65535]" + "'\n", + prgname); +} + +static int +parse_device_id(const char *key __rte_unused, const char *value, + void *extra_args) +{ + struct pdump_tuples *pt = extra_args; + + pt->device_id = strdup(value); + pt->dump_by_type = DEVICE_ID; + + return 0; +} + +static int +parse_queue(const char *key __rte_unused, const char *value, void *extra_args) +{ + unsigned long n; + struct pdump_tuples *pt = extra_args; + + if (!strcmp(value, "*")) + pt->queue = RTE_PDUMP_ALL_QUEUES; + else { + n = strtoul(value, NULL, 10); + pt->queue = (uint16_t) n; + } + return 0; +} + +static int +parse_rxtxdev(const char *key, const char *value, void *extra_args) +{ + + struct pdump_tuples *pt = extra_args; + + if (!strcmp(key, PDUMP_RX_DEV_ARG)) { + snprintf(pt->rx_dev, sizeof(pt->rx_dev), "%s", value); + /* identify the tx stream type for pcap vdev */ + if (if_nametoindex(pt->rx_dev)) + pt->rx_vdev_stream_type = IFACE; + } else if (!strcmp(key, PDUMP_TX_DEV_ARG)) { + snprintf(pt->tx_dev, sizeof(pt->tx_dev), "%s", value); + /* identify the tx stream type for pcap vdev */ + if (if_nametoindex(pt->tx_dev)) + pt->tx_vdev_stream_type = IFACE; + } else { + printf("invalid dev type %s, must be rx or tx\n", value); + return -1; + } + + return 0; +} + +static int +parse_uint_value(const char *key, const char *value, void *extra_args) +{ + struct parse_val *v; + unsigned long t; + char *end; + int ret = 0; + + errno = 0; + v = extra_args; + t = strtoul(value, &end, 10); + + if (errno != 0 || end[0] != 0 || t < v->min || t > v->max) { + printf("invalid value:\"%s\" for key:\"%s\", " + "value must be >= %"PRIu64" and <= %"PRIu64"\n", + value, key, v->min, v->max); + ret = -EINVAL; + } + if (!strcmp(key, PDUMP_RING_SIZE_ARG) && !POWEROF2(t)) { + printf("invalid value:\"%s\" for key:\"%s\", " + "value must be power of 2\n", value, key); + ret = -EINVAL; + } + + if (ret != 0) + return ret; + + v->val = t; + return 0; +} + +static int +parse_pdump(const char *optarg) +{ + struct rte_kvargs *kvlist; + int ret = 0, cnt1, cnt2; + struct pdump_tuples *pt; + struct parse_val v = {0}; + + pt = &pdump_t[num_tuples]; + + /* initial check for invalid arguments */ + kvlist = rte_kvargs_parse(optarg, valid_pdump_arguments); + if (kvlist == NULL) { + printf("--pdump=\"%s\": invalid argument passed\n", optarg); + return -1; + } + + /* port/device_id parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_PORT_ARG); + cnt2 = rte_kvargs_count(kvlist, PDUMP_PCI_ARG); + if (!((cnt1 == 1 && cnt2 == 0) || (cnt1 == 0 && cnt2 == 1))) { + printf("--pdump=\"%s\": must have either port or " + "device_id argument\n", optarg); + ret = -1; + goto free_kvlist; + } else if (cnt1 == 1) { + v.min = 0; + v.max = RTE_MAX_ETHPORTS-1; + ret = rte_kvargs_process(kvlist, PDUMP_PORT_ARG, + &parse_uint_value, &v); + if (ret < 0) + goto free_kvlist; + pt->port = (uint8_t) v.val; + pt->dump_by_type = PORT_ID; + } else if (cnt2 == 1) { + ret = rte_kvargs_process(kvlist, PDUMP_PCI_ARG, + &parse_device_id, pt); + if (ret < 0) + goto free_kvlist; + } + + /* queue parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_QUEUE_ARG); + if (cnt1 != 1) { + printf("--pdump=\"%s\": must have queue argument\n", optarg); + ret = -1; + goto free_kvlist; + } + ret = rte_kvargs_process(kvlist, PDUMP_QUEUE_ARG, &parse_queue, pt); + if (ret < 0) + goto free_kvlist; + + /* rx-dev and tx-dev parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_RX_DEV_ARG); + cnt2 = rte_kvargs_count(kvlist, PDUMP_TX_DEV_ARG); + if (cnt1 == 0 && cnt2 == 0) { + printf("--pdump=\"%s\": must have either rx-dev or " + "tx-dev argument\n", optarg); + ret = -1; + goto free_kvlist; + } else if (cnt1 == 1 && cnt2 == 1) { + ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, + &parse_rxtxdev, pt); + if (ret < 0) + goto free_kvlist; + ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, + &parse_rxtxdev, pt); + if (ret < 0) + goto free_kvlist; + /* if captured packets has to send to the same vdev */ + if (!strcmp(pt->rx_dev, pt->tx_dev)) + pt->single_pdump_dev = true; + pt->dir = RTE_PDUMP_FLAG_RXTX; + } else if (cnt1 == 1) { + ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, + &parse_rxtxdev, pt); + if (ret < 0) + goto free_kvlist; + pt->dir = RTE_PDUMP_FLAG_RX; + } else if (cnt2 == 1) { + ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, + &parse_rxtxdev, pt); + if (ret < 0) + goto free_kvlist; + pt->dir = RTE_PDUMP_FLAG_TX; + } + + /* optional */ + /* ring_size parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_RING_SIZE_ARG); + if (cnt1 == 1) { + v.min = 2; + v.max = RTE_RING_SZ_MASK-1; + ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG, + &parse_uint_value, &v); + if (ret < 0) + goto free_kvlist; + pt->ring_size = (uint32_t) v.val; + } else + pt->ring_size = RING_SIZE; + + /* mbuf_data_size parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_MSIZE_ARG); + if (cnt1 == 1) { + v.min = 1; + v.max = UINT16_MAX; + ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG, + &parse_uint_value, &v); + if (ret < 0) + goto free_kvlist; + pt->mbuf_data_size = (uint16_t) v.val; + } else + pt->mbuf_data_size = RTE_MBUF_DEFAULT_BUF_SIZE; + + /* total_num_mbufs parsing and validation */ + cnt1 = rte_kvargs_count(kvlist, PDUMP_NUM_MBUFS_ARG); + if (cnt1 == 1) { + v.min = 1025; + v.max = UINT16_MAX; + ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG, + &parse_uint_value, &v); + if (ret < 0) + goto free_kvlist; + pt->total_num_mbufs = (uint16_t) v.val; + } else + pt->total_num_mbufs = MBUFS_PER_POOL; + + num_tuples++; + +free_kvlist: + rte_kvargs_free(kvlist); + return ret; +} + +/* Parse the argument given in the command line of the application */ +static int +launch_args_parse(int argc, char **argv, char *prgname) +{ + int opt, ret; + int option_index; + static struct option long_option[] = { + {"pdump", 1, 0, 0}, + {NULL, 0, 0, 0} + }; + + if (argc == 1) + pdump_usage(prgname); + + /* Parse command line */ + while ((opt = getopt_long(argc, argv, " ", + long_option, &option_index)) != EOF) { + switch (opt) { + case 0: + if (!strncmp(long_option[option_index].name, "pdump", + MAX_LONG_OPT_SZ)) { + ret = parse_pdump(optarg); + if (ret) { + pdump_usage(prgname); + return -1; + } + } + break; + default: + pdump_usage(prgname); + return -1; + } + } + + return 0; +} + +static void +print_pdump_stats(void) +{ + int i; + struct pdump_tuples *pt; + + for (i = 0; i < num_tuples; i++) { + printf("##### PDUMP DEBUG STATS #####\n"); + pt = &pdump_t[i]; + printf(" -packets dequeued: %"PRIu64"\n", + pt->stats.dequeue_pkts); + printf(" -packets transmitted to vdev: %"PRIu64"\n", + pt->stats.tx_pkts); + printf(" -packets freed: %"PRIu64"\n", + pt->stats.freed_pkts); + } +} + +static inline void +disable_pdump(struct pdump_tuples *pt) +{ + if (pt->dump_by_type == DEVICE_ID) + rte_pdump_disable_by_deviceid(pt->device_id, pt->queue, + pt->dir); + else if (pt->dump_by_type == PORT_ID) + rte_pdump_disable(pt->port, pt->queue, pt->dir); +} + +static inline void +pdump_rxtx(struct rte_ring *ring, uint8_t vdev_id, struct pdump_stats *stats) +{ + /* write input packets of port to vdev for pdump */ + struct rte_mbuf *rxtx_bufs[BURST_SIZE]; + + /* first dequeue packets from ring of primary process */ + const uint16_t nb_in_deq = rte_ring_dequeue_burst(ring, + (void *)rxtx_bufs, BURST_SIZE); + stats->dequeue_pkts += nb_in_deq; + + if (nb_in_deq) { + /* then sent on vdev */ + uint16_t nb_in_txd = rte_eth_tx_burst( + vdev_id, + 0, rxtx_bufs, nb_in_deq); + stats->tx_pkts += nb_in_txd; + + if (unlikely(nb_in_txd < nb_in_deq)) { + do { + rte_pktmbuf_free(rxtx_bufs[nb_in_txd]); + stats->freed_pkts++; + } while (++nb_in_txd < nb_in_deq); + } + } +} + +static void +free_ring_data(struct rte_ring *ring, uint8_t vdev_id, + struct pdump_stats *stats) +{ + while (rte_ring_count(ring)) + pdump_rxtx(ring, vdev_id, stats); +} + +static void +cleanup_pdump_resources(void) +{ + int i; + struct pdump_tuples *pt; + + /* disable pdump and free the pdump_tuple resources */ + for (i = 0; i < num_tuples; i++) { + pt = &pdump_t[i]; + + /* remove callbacks */ + disable_pdump(pt); + + /* + * transmit rest of the enqueued packets of the rings on to + * the vdev, in order to release mbufs to the mepool. + **/ + if (pt->dir & RTE_PDUMP_FLAG_RX) + free_ring_data(pt->rx_ring, pt->rx_vdev_id, &pt->stats); + if (pt->dir & RTE_PDUMP_FLAG_TX) + free_ring_data(pt->tx_ring, pt->tx_vdev_id, &pt->stats); + + if (pt->device_id) + free(pt->device_id); + + /* free the rings */ + if (pt->rx_ring) + rte_ring_free(pt->rx_ring); + if (pt->tx_ring) + rte_ring_free(pt->tx_ring); + } +} + +static void +signal_handler(int sig_num) +{ + if (sig_num == SIGINT) { + printf("\n\nSignal %d received, preparing to exit...\n", + sig_num); + quit_signal = 1; + } +} + +static inline int +configure_vdev(uint8_t port_id) +{ + struct ether_addr addr; + const uint16_t rxRings = 0, txRings = 1; + const uint8_t nb_ports = rte_eth_dev_count(); + int ret; + uint16_t q; + + if (port_id > nb_ports) + return -1; + + ret = rte_eth_dev_configure(port_id, rxRings, txRings, + &port_conf_default); + if (ret != 0) + rte_exit(EXIT_FAILURE, "dev config failed\n"); + + for (q = 0; q < txRings; q++) { + ret = rte_eth_tx_queue_setup(port_id, q, TX_DESC_PER_QUEUE, + rte_eth_dev_socket_id(port_id), NULL); + if (ret < 0) + rte_exit(EXIT_FAILURE, "queue setup failed\n"); + } + + ret = rte_eth_dev_start(port_id); + if (ret < 0) + rte_exit(EXIT_FAILURE, "dev start failed\n"); + + rte_eth_macaddr_get(port_id, &addr); + printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 + " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", + (unsigned)port_id, + addr.addr_bytes[0], addr.addr_bytes[1], + addr.addr_bytes[2], addr.addr_bytes[3], + addr.addr_bytes[4], addr.addr_bytes[5]); + + rte_eth_promiscuous_enable(port_id); + + return 0; +} + +static void +create_mp_ring_vdev(void) +{ + int i; + uint8_t portid; + struct pdump_tuples *pt = NULL; + struct rte_mempool *mbuf_pool = NULL; + char vdev_args[SIZE]; + char ring_name[SIZE]; + char mempool_name[SIZE]; + + for (i = 0; i < num_tuples; i++) { + pt = &pdump_t[i]; + snprintf(mempool_name, SIZE, MP_NAME, i); + mbuf_pool = rte_mempool_lookup(mempool_name); + if (mbuf_pool == NULL) { + /* create mempool */ + mbuf_pool = rte_pktmbuf_pool_create(mempool_name, + pt->total_num_mbufs, + MBUF_POOL_CACHE_SIZE, 0, + pt->mbuf_data_size, + rte_socket_id()); + if (mbuf_pool == NULL) + rte_exit(EXIT_FAILURE, + "Mempool creation failed: %s\n", + rte_strerror(rte_errno)); + } + pt->mp = mbuf_pool; + + if (pt->dir == RTE_PDUMP_FLAG_RXTX) { + /* if captured packets has to send to the same vdev */ + /* create rx_ring */ + snprintf(ring_name, SIZE, RX_RING, i); + pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, + rte_socket_id(), 0); + if (pt->rx_ring == NULL) + rte_exit(EXIT_FAILURE, "%s:%s:%d\n", + rte_strerror(rte_errno), + __func__, __LINE__); + + /* create tx_ring */ + snprintf(ring_name, SIZE, TX_RING, i); + pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, + rte_socket_id(), 0); + if (pt->tx_ring == NULL) + rte_exit(EXIT_FAILURE, "%s:%s:%d\n", + rte_strerror(rte_errno), + __func__, __LINE__); + + /* create vdevs */ + (pt->rx_vdev_stream_type == IFACE) ? + snprintf(vdev_args, SIZE, VDEV_IFACE, RX_STR, i, + pt->rx_dev) : + snprintf(vdev_args, SIZE, VDEV_PCAP, RX_STR, i, + pt->rx_dev); + if (rte_eth_dev_attach(vdev_args, &portid) < 0) + rte_exit(EXIT_FAILURE, + "vdev creation failed:%s:%d\n", + __func__, __LINE__); + pt->rx_vdev_id = portid; + + /* configure vdev */ + configure_vdev(pt->rx_vdev_id); + + if (pt->single_pdump_dev) + pt->tx_vdev_id = portid; + else { + (pt->tx_vdev_stream_type == IFACE) ? + snprintf(vdev_args, SIZE, VDEV_IFACE, TX_STR, i, + pt->tx_dev) : + snprintf(vdev_args, SIZE, VDEV_PCAP, TX_STR, i, + pt->tx_dev); + if (rte_eth_dev_attach(vdev_args, &portid) < 0) + rte_exit(EXIT_FAILURE, + "vdev creation failed:" + "%s:%d\n", __func__, __LINE__); + pt->tx_vdev_id = portid; + + /* configure vdev */ + configure_vdev(pt->tx_vdev_id); + } + } else if (pt->dir == RTE_PDUMP_FLAG_RX) { + + /* create rx_ring */ + snprintf(ring_name, SIZE, RX_RING, i); + pt->rx_ring = rte_ring_create(ring_name, pt->ring_size, + rte_socket_id(), 0); + if (pt->rx_ring == NULL) + rte_exit(EXIT_FAILURE, "%s\n", + rte_strerror(rte_errno)); + + (pt->rx_vdev_stream_type == IFACE) ? + snprintf(vdev_args, SIZE, VDEV_IFACE, RX_STR, i, + pt->rx_dev) : + snprintf(vdev_args, SIZE, VDEV_PCAP, RX_STR, i, + pt->rx_dev); + if (rte_eth_dev_attach(vdev_args, &portid) < 0) + rte_exit(EXIT_FAILURE, + "vdev creation failed:%s:%d\n", + __func__, __LINE__); + pt->rx_vdev_id = portid; + /* configure vdev */ + configure_vdev(pt->rx_vdev_id); + } else if (pt->dir == RTE_PDUMP_FLAG_TX) { + + /* create tx_ring */ + snprintf(ring_name, SIZE, TX_RING, i); + pt->tx_ring = rte_ring_create(ring_name, pt->ring_size, + rte_socket_id(), 0); + if (pt->tx_ring == NULL) + rte_exit(EXIT_FAILURE, "%s\n", + rte_strerror(rte_errno)); + + (pt->tx_vdev_stream_type == IFACE) ? + snprintf(vdev_args, SIZE, VDEV_IFACE, TX_STR, i, + pt->tx_dev) : + snprintf(vdev_args, SIZE, VDEV_PCAP, TX_STR, i, + pt->tx_dev); + if (rte_eth_dev_attach(vdev_args, &portid) < 0) + rte_exit(EXIT_FAILURE, + "vdev creation failed\n"); + pt->tx_vdev_id = portid; + + /* configure vdev */ + configure_vdev(pt->tx_vdev_id); + } + } +} + +static void +enable_pdump(void) +{ + int i; + struct pdump_tuples *pt; + int ret = 0, ret1 = 0; + + for (i = 0; i < num_tuples; i++) { + pt = &pdump_t[i]; + if (pt->dir == RTE_PDUMP_FLAG_RXTX) { + if (pt->dump_by_type == DEVICE_ID) { + ret = rte_pdump_enable_by_deviceid( + pt->device_id, + pt->queue, + RTE_PDUMP_FLAG_RX, + pt->rx_ring, + pt->mp, NULL); + ret = rte_pdump_enable_by_deviceid( + pt->device_id, + pt->queue, + RTE_PDUMP_FLAG_TX, + pt->tx_ring, + pt->mp, NULL); + } else if (pt->dump_by_type == PORT_ID) { + ret = rte_pdump_enable(pt->port, pt->queue, + RTE_PDUMP_FLAG_RX, + pt->rx_ring, pt->mp, NULL); + ret1 = rte_pdump_enable(pt->port, pt->queue, + RTE_PDUMP_FLAG_TX, + pt->tx_ring, pt->mp, NULL); + } + } else if (pt->dir == RTE_PDUMP_FLAG_RX) { + if (pt->dump_by_type == DEVICE_ID) + ret = rte_pdump_enable_by_deviceid( + pt->device_id, + pt->queue, + pt->dir, pt->rx_ring, + pt->mp, NULL); + else if (pt->dump_by_type == PORT_ID) + ret = rte_pdump_enable(pt->port, pt->queue, + pt->dir, + pt->rx_ring, pt->mp, NULL); + } else if (pt->dir == RTE_PDUMP_FLAG_TX) { + if (pt->dump_by_type == DEVICE_ID) + ret = rte_pdump_enable_by_deviceid( + pt->device_id, + pt->queue, + pt->dir, + pt->tx_ring, pt->mp, NULL); + else if (pt->dump_by_type == PORT_ID) + ret = rte_pdump_enable(pt->port, pt->queue, + pt->dir, + pt->tx_ring, pt->mp, NULL); + } + if (ret < 0 || ret1 < 0) { + cleanup_pdump_resources(); + rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); + } + } +} + +static inline void +dump_packets(void) +{ + int i; + struct pdump_tuples *pt; + + while (!quit_signal) { + for (i = 0; i < num_tuples; i++) { + pt = &pdump_t[i]; + if (pt->dir & RTE_PDUMP_FLAG_RX) + pdump_rxtx(pt->rx_ring, pt->rx_vdev_id, + &pt->stats); + if (pt->dir & RTE_PDUMP_FLAG_TX) + pdump_rxtx(pt->tx_ring, pt->tx_vdev_id, + &pt->stats); + } + } +} + +int +main(int argc, char **argv) +{ + int diag; + int ret; + int i; + + char c_flag[] = "-c1"; + char n_flag[] = "-n4"; + char mp_flag[] = "--proc-type=secondary"; + char *argp[argc + 3]; + + /* catch ctrl-c so we can print on exit */ + signal(SIGINT, signal_handler); + + argp[0] = argv[0]; + argp[1] = c_flag; + argp[2] = n_flag; + argp[3] = mp_flag; + + for (i = 1; i < argc; i++) + argp[i + 3] = argv[i]; + + argc += 3; + + diag = rte_eal_init(argc, argp); + if (diag < 0) + rte_panic("Cannot init EAL\n"); + + argc -= diag; + argv += (diag - 3); + + /* parse app arguments */ + if (argc > 1) { + ret = launch_args_parse(argc, argv, argp[0]); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid argument\n"); + } + + /* create mempool, ring and vdevs info */ + create_mp_ring_vdev(); + enable_pdump(); + dump_packets(); + + cleanup_pdump_resources(); + /* dump debug stats */ + print_pdump_stats(); + + return 0; +} diff --git a/app/proc_info/main.c b/app/proc_info/main.c index 341176db..6dc0bbb8 100644 --- a/app/proc_info/main.c +++ b/app/proc_info/main.c @@ -1,7 +1,7 @@ /* * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -243,11 +243,12 @@ nic_stats_clear(uint8_t port_id) static void nic_xstats_display(uint8_t port_id) { - struct rte_eth_xstats *xstats; + struct rte_eth_xstat_name *xstats_names; + struct rte_eth_xstat *xstats; int len, ret, i; static const char *nic_stats_border = "########################"; - len = rte_eth_xstats_get(port_id, NULL, 0); + len = rte_eth_xstats_get_names(port_id, NULL, 0); if (len < 0) { printf("Cannot get xstats count\n"); return; @@ -258,6 +259,18 @@ nic_xstats_display(uint8_t port_id) return; } + xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len); + if (xstats_names == NULL) { + printf("Cannot allocate memory for xstat names\n"); + free(xstats); + return; + } + if (len != rte_eth_xstats_get_names( + port_id, xstats_names, len)) { + printf("Cannot get xstat names\n"); + return; + } + printf("###### NIC extended statistics for port %-2d #########\n", port_id); printf("%s############################\n", @@ -270,11 +283,14 @@ nic_xstats_display(uint8_t port_id) } for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + printf("%s: %"PRIu64"\n", + xstats_names[i].name, + xstats[i].value); printf("%s############################\n", nic_stats_border); free(xstats); + free(xstats_names); } static void @@ -327,10 +343,6 @@ main(int argc, char **argv) if (nb_ports == 0) rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); - - if (nb_ports > RTE_MAX_ETHPORTS) - nb_ports = RTE_MAX_ETHPORTS; - /* If no port mask was specified*/ if (enabled_port_mask == 0) enabled_port_mask = 0xffff; diff --git a/app/test-acl/main.c b/app/test-acl/main.c index 0b0c093c..d3669814 100644 --- a/app/test-acl/main.c +++ b/app/test-acl/main.c @@ -901,7 +901,7 @@ search_ip5tuples(__attribute__((unused)) void *arg) "%s @lcore %u: %" PRIu32 " iterations, %" PRIu64 " pkts, %" PRIu32 " categories, %" PRIu64 " cycles, %#Lf cycles/pkt\n", __func__, lcore, i, pkt, config.run_categories, - tm, (long double)tm / pkt); + tm, (pkt == 0) ? 0 : (long double)tm / pkt); return 0; } diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index 72426f31..2a0b5a5d 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -50,7 +50,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline.c SRCS-y += config.c SRCS-y += iofwd.c SRCS-y += macfwd.c -SRCS-y += macfwd-retry.c SRCS-y += macswap.c SRCS-y += flowgen.c SRCS-y += rxonly.c @@ -58,11 +57,7 @@ SRCS-y += txonly.c SRCS-y += csumonly.c SRCS-y += icmpecho.c SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c -SRCS-y += mempool_anon.c -ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) -CFLAGS_mempool_anon.o := -D_GNU_SOURCE -endif CFLAGS_cmdline.o := -D_GNU_SOURCE # this application needs libraries first diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index c5b94797..b6b61ad3 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -246,8 +246,8 @@ static void cmd_help_long_parsed(void *parsed_result, " Set number of packets per burst.\n\n" "set burst tx delay (microseconds) retry (num)\n" - " Set the transmit delay time and number of retries" - " in mac_retry forwarding mode.\n\n" + " Set the transmit delay time and number of retries," + " effective when retry is enabled.\n\n" "set txpkts (x[,y]*)\n" " Set the length of each segment of TXONLY" @@ -559,13 +559,13 @@ static void cmd_help_long_parsed(void *parsed_result, "port config all max-pkt-len (value)\n" " Set the max packet length.\n\n" - "port config all (crc-strip|rx-cksum|hw-vlan|hw-vlan-filter|" + "port config all (crc-strip|scatter|rx-cksum|hw-vlan|hw-vlan-filter|" "hw-vlan-strip|hw-vlan-extend|drop-en)" " (on|off)\n" - " Set crc-strip/rx-checksum/hardware-vlan/drop_en" + " Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en" " for ports.\n\n" - "port config all rss (all|ip|tcp|udp|sctp|ether|none)\n" + "port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n" " Set the RSS mode.\n\n" "port config port-id rss reta (hash,queue)[,(hash,queue)]\n" @@ -1223,6 +1223,8 @@ cmd_config_rx_tx_parsed(void *parsed_result, return; } + fwd_config_setup(); + init_port_config(); cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); @@ -1410,6 +1412,15 @@ cmd_config_rx_mode_flag_parsed(void *parsed_result, printf("Unknown parameter\n"); return; } + } else if (!strcmp(res->name, "scatter")) { + if (!strcmp(res->value, "on")) + rx_mode.enable_scatter = 1; + else if (!strcmp(res->value, "off")) + rx_mode.enable_scatter = 0; + else { + printf("Unknown parameter\n"); + return; + } } else if (!strcmp(res->name, "rx-cksum")) { if (!strcmp(res->value, "on")) rx_mode.hw_ip_checksum = 1; @@ -1487,7 +1498,7 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_all = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all"); cmdline_parse_token_string_t cmd_config_rx_mode_flag_name = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name, - "crc-strip#rx-cksum#hw-vlan#" + "crc-strip#scatter#rx-cksum#hw-vlan#" "hw-vlan-filter#hw-vlan-strip#hw-vlan-extend"); cmdline_parse_token_string_t cmd_config_rx_mode_flag_value = TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value, @@ -1496,7 +1507,7 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_value = cmdline_parse_inst_t cmd_config_rx_mode_flag = { .f = cmd_config_rx_mode_flag_parsed, .data = NULL, - .help_str = "port config all crc-strip|rx-cksum|hw-vlan|" + .help_str = "port config all crc-strip|scatter|rx-cksum|hw-vlan|" "hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off", .tokens = { (void *)&cmd_config_rx_mode_flag_port, @@ -1524,6 +1535,7 @@ cmd_config_rss_parsed(void *parsed_result, { struct cmd_config_rss *res = parsed_result; struct rte_eth_rss_conf rss_conf; + int diag; uint8_t i; if (!strcmp(res->value, "all")) @@ -1540,6 +1552,14 @@ cmd_config_rss_parsed(void *parsed_result, rss_conf.rss_hf = ETH_RSS_SCTP; else if (!strcmp(res->value, "ether")) rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD; + else if (!strcmp(res->value, "port")) + rss_conf.rss_hf = ETH_RSS_PORT; + else if (!strcmp(res->value, "vxlan")) + rss_conf.rss_hf = ETH_RSS_VXLAN; + else if (!strcmp(res->value, "geneve")) + rss_conf.rss_hf = ETH_RSS_GENEVE; + else if (!strcmp(res->value, "nvgre")) + rss_conf.rss_hf = ETH_RSS_NVGRE; else if (!strcmp(res->value, "none")) rss_conf.rss_hf = 0; else { @@ -1547,8 +1567,13 @@ cmd_config_rss_parsed(void *parsed_result, return; } rss_conf.rss_key = NULL; - for (i = 0; i < rte_eth_dev_count(); i++) - rte_eth_dev_rss_hash_update(i, &rss_conf); + for (i = 0; i < rte_eth_dev_count(); i++) { + diag = rte_eth_dev_rss_hash_update(i, &rss_conf); + if (diag < 0) + printf("Configuration of RSS hash at ethernet port %d " + "failed with error (%d): %s.\n", + i, -diag, strerror(-diag)); + } } cmdline_parse_token_string_t cmd_config_rss_port = @@ -1561,12 +1586,12 @@ cmdline_parse_token_string_t cmd_config_rss_name = TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss"); cmdline_parse_token_string_t cmd_config_rss_value = TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, - "all#ip#tcp#udp#sctp#ether#none"); + "all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none"); cmdline_parse_inst_t cmd_config_rss = { .f = cmd_config_rss_parsed, .data = NULL, - .help_str = "port config all rss all|ip|tcp|udp|sctp|ether|none", + .help_str = "port config all rss all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none", .tokens = { (void *)&cmd_config_rss_port, (void *)&cmd_config_rss_keyword, @@ -2511,16 +2536,20 @@ static void cmd_set_list_parsed(void *parsed_result, nb_item = parse_item_list(res->list_of_items, "core", RTE_MAX_LCORE, parsed_items.lcorelist, 1); - if (nb_item > 0) + if (nb_item > 0) { set_fwd_lcores_list(parsed_items.lcorelist, nb_item); + fwd_config_setup(); + } return; } if (!strcmp(res->list_name, "portlist")) { nb_item = parse_item_list(res->list_of_items, "port", RTE_MAX_ETHPORTS, parsed_items.portlist, 1); - if (nb_item > 0) + if (nb_item > 0) { set_fwd_ports_list(parsed_items.portlist, nb_item); + fwd_config_setup(); + } } } @@ -2564,10 +2593,13 @@ static void cmd_set_mask_parsed(void *parsed_result, printf("Please stop forwarding first\n"); return; } - if (!strcmp(res->mask, "coremask")) + if (!strcmp(res->mask, "coremask")) { set_fwd_lcores_mask(res->hexavalue); - else if (!strcmp(res->mask, "portmask")) + fwd_config_setup(); + } else if (!strcmp(res->mask, "portmask")) { set_fwd_ports_mask(res->hexavalue); + fwd_config_setup(); + } } cmdline_parse_token_string_t cmd_setmask_set = @@ -2604,11 +2636,13 @@ static void cmd_set_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_set_result *res = parsed_result; - if (!strcmp(res->what, "nbport")) + if (!strcmp(res->what, "nbport")) { set_fwd_ports_number(res->value); - else if (!strcmp(res->what, "nbcore")) + fwd_config_setup(); + } else if (!strcmp(res->what, "nbcore")) { set_fwd_lcores_number(res->value); - else if (!strcmp(res->what, "burst")) + fwd_config_setup(); + } else if (!strcmp(res->what, "burst")) set_nb_pkt_per_burst(res->value); else if (!strcmp(res->what, "verbose")) set_verbose_level(res->value); @@ -2721,6 +2755,74 @@ cmdline_parse_inst_t cmd_set_txsplit = { }, }; +/* *** CONFIG TX QUEUE FLAGS *** */ + +struct cmd_config_txqflags_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + cmdline_fixed_string_t all; + cmdline_fixed_string_t what; + int32_t hexvalue; +}; + +static void cmd_config_txqflags_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_txqflags_result *res = parsed_result; + + if (!all_ports_stopped()) { + printf("Please stop all ports first\n"); + return; + } + + if (strcmp(res->what, "txqflags")) { + printf("Unknown parameter\n"); + return; + } + + if (res->hexvalue >= 0) { + txq_flags = res->hexvalue; + } else { + printf("txqflags must be >= 0\n"); + return; + } + + init_port_config(); + + cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); +} + +cmdline_parse_token_string_t cmd_config_txqflags_port = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, port, + "port"); +cmdline_parse_token_string_t cmd_config_txqflags_config = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, config, + "config"); +cmdline_parse_token_string_t cmd_config_txqflags_all = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, all, + "all"); +cmdline_parse_token_string_t cmd_config_txqflags_what = + TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, what, + "txqflags"); +cmdline_parse_token_num_t cmd_config_txqflags_value = + TOKEN_NUM_INITIALIZER(struct cmd_config_txqflags_result, + hexvalue, INT32); + +cmdline_parse_inst_t cmd_config_txqflags = { + .f = cmd_config_txqflags_parsed, + .data = NULL, + .help_str = "port config all txqflags value", + .tokens = { + (void *)&cmd_config_txqflags_port, + (void *)&cmd_config_txqflags_config, + (void *)&cmd_config_txqflags_all, + (void *)&cmd_config_txqflags_what, + (void *)&cmd_config_txqflags_value, + NULL, + }, +}; + /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */ struct cmd_rx_vlan_filter_all_result { cmdline_fixed_string_t rx_vlan; @@ -4480,6 +4582,7 @@ static void cmd_set_fwd_mode_parsed(void *parsed_result, { struct cmd_set_fwd_mode_result *res = parsed_result; + retry_enabled = 0; set_pkt_forwarding_mode(res->mode); } @@ -4525,6 +4628,74 @@ static void cmd_set_fwd_mode_init(void) token_struct->string_data.str = token; } +/* *** SET RETRY FORWARDING MODE *** */ +struct cmd_set_fwd_retry_mode_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t fwd; + cmdline_fixed_string_t mode; + cmdline_fixed_string_t retry; +}; + +static void cmd_set_fwd_retry_mode_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_fwd_retry_mode_result *res = parsed_result; + + retry_enabled = 1; + set_pkt_forwarding_mode(res->mode); +} + +cmdline_parse_token_string_t cmd_setfwd_retry_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + set, "set"); +cmdline_parse_token_string_t cmd_setfwd_retry_fwd = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + fwd, "fwd"); +cmdline_parse_token_string_t cmd_setfwd_retry_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + mode, + "" /* defined at init */); +cmdline_parse_token_string_t cmd_setfwd_retry_retry = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + retry, "retry"); + +cmdline_parse_inst_t cmd_set_fwd_retry_mode = { + .f = cmd_set_fwd_retry_mode_parsed, + .data = NULL, + .help_str = NULL, /* defined at init */ + .tokens = { + (void *)&cmd_setfwd_retry_set, + (void *)&cmd_setfwd_retry_fwd, + (void *)&cmd_setfwd_retry_mode, + (void *)&cmd_setfwd_retry_retry, + NULL, + }, +}; + +static void cmd_set_fwd_retry_mode_init(void) +{ + char *modes, *c; + static char token[128]; + static char help[256]; + cmdline_parse_token_string_t *token_struct; + + modes = list_pkt_forwarding_retry_modes(); + snprintf(help, sizeof(help), "set fwd %s retry - " + "set packet forwarding mode with retry", modes); + cmd_set_fwd_retry_mode.help_str = help; + + /* string token separator is # */ + for (c = token; *modes != '\0'; modes++) + if (*modes == '|') + *c++ = '#'; + else + *c++ = *modes; + token_struct = (cmdline_parse_token_string_t *) + cmd_set_fwd_retry_mode.tokens[2]; + token_struct->string_data.str = token; +} + /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */ struct cmd_set_burst_tx_retry_result { cmdline_fixed_string_t set; @@ -5240,6 +5411,46 @@ cmdline_parse_inst_t cmd_start_tx_first = { }, }; +/* *** START FORWARDING WITH N TX BURST FIRST *** */ +struct cmd_start_tx_first_n_result { + cmdline_fixed_string_t start; + cmdline_fixed_string_t tx_first; + uint32_t tx_num; +}; + +static void +cmd_start_tx_first_n_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_start_tx_first_n_result *res = parsed_result; + + start_packet_forwarding(res->tx_num); +} + +cmdline_parse_token_string_t cmd_start_tx_first_n_start = + TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result, + start, "start"); +cmdline_parse_token_string_t cmd_start_tx_first_n_tx_first = + TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result, + tx_first, "tx_first"); +cmdline_parse_token_num_t cmd_start_tx_first_n_tx_num = + TOKEN_NUM_INITIALIZER(struct cmd_start_tx_first_n_result, + tx_num, UINT32); + +cmdline_parse_inst_t cmd_start_tx_first_n = { + .f = cmd_start_tx_first_n_parsed, + .data = NULL, + .help_str = "start packet forwarding, after sending <num> " + "bursts of packets", + .tokens = { + (void *)&cmd_start_tx_first_n_start, + (void *)&cmd_start_tx_first_n_tx_first, + (void *)&cmd_start_tx_first_n_tx_num, + NULL, + }, +}; + /* *** SET LINK UP *** */ struct cmd_set_link_up_result { cmdline_fixed_string_t set; @@ -5336,7 +5547,7 @@ static void cmd_showcfg_parsed(void *parsed_result, else if (!strcmp(res->what, "cores")) fwd_lcores_config_display(); else if (!strcmp(res->what, "fwd")) - fwd_config_display(); + pkt_fwd_config_display(&cur_fwd_config); else if (!strcmp(res->what, "txpkts")) show_tx_pkt_segments(); } @@ -7191,8 +7402,6 @@ static void cmd_dump_parsed(void *parsed_result, rte_dump_physmem_layout(stdout); else if (!strcmp(res->dump, "dump_memzone")) rte_memzone_dump(stdout); - else if (!strcmp(res->dump, "dump_log_history")) - rte_log_dump_history(stdout); else if (!strcmp(res->dump, "dump_struct_sizes")) dump_struct_sizes(); else if (!strcmp(res->dump, "dump_ring")) @@ -7207,7 +7416,6 @@ cmdline_parse_token_string_t cmd_dump_dump = TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, "dump_physmem#" "dump_memzone#" - "dump_log_history#" "dump_struct_sizes#" "dump_ring#" "dump_mempool#" @@ -9299,6 +9507,10 @@ flowtype_to_str(uint16_t ftype) {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP}, {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER}, {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD}, + {"port", RTE_ETH_FLOW_PORT}, + {"vxlan", RTE_ETH_FLOW_VXLAN}, + {"geneve", RTE_ETH_FLOW_GENEVE}, + {"nvgre", RTE_ETH_FLOW_NVGRE}, }; for (i = 0; i < RTE_DIM(ftype_table); i++) { @@ -10399,6 +10611,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_showcfg, (cmdline_parse_inst_t *)&cmd_start, (cmdline_parse_inst_t *)&cmd_start_tx_first, + (cmdline_parse_inst_t *)&cmd_start_tx_first_n, (cmdline_parse_inst_t *)&cmd_set_link_up, (cmdline_parse_inst_t *)&cmd_set_link_down, (cmdline_parse_inst_t *)&cmd_reset, @@ -10408,6 +10621,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_set_fwd_list, (cmdline_parse_inst_t *)&cmd_set_fwd_mask, (cmdline_parse_inst_t *)&cmd_set_fwd_mode, + (cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode, (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all, @@ -10478,6 +10692,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_config_rx_mode_flag, (cmdline_parse_inst_t *)&cmd_config_rss, (cmdline_parse_inst_t *)&cmd_config_rxtx_queue, + (cmdline_parse_inst_t *)&cmd_config_txqflags, (cmdline_parse_inst_t *)&cmd_config_rss_reta, (cmdline_parse_inst_t *)&cmd_showport_reta, (cmdline_parse_inst_t *)&cmd_config_burst, @@ -10546,6 +10761,7 @@ prompt(void) { /* initialize non-constant commands */ cmd_set_fwd_mode_init(); + cmd_set_fwd_retry_mode_init(); testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); if (testpmd_cl == NULL) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index b1bbec6d..c5865f95 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -92,6 +92,7 @@ #include <rte_ether.h> #include <rte_ethdev.h> #include <rte_string_fns.h> +#include <rte_cycles.h> #include "testpmd.h" @@ -137,6 +138,11 @@ static const struct rss_type_info rss_type_table[] = { { "ipv6-ex", ETH_RSS_IPV6_EX }, { "ipv6-tcp-ex", ETH_RSS_IPV6_TCP_EX }, { "ipv6-udp-ex", ETH_RSS_IPV6_UDP_EX }, + { "port", ETH_RSS_PORT }, + { "vxlan", ETH_RSS_VXLAN }, + { "geneve", ETH_RSS_GENEVE }, + { "nvgre", ETH_RSS_NVGRE }, + }; static void @@ -150,6 +156,11 @@ print_ethaddr(const char *name, struct ether_addr *eth_addr) void nic_stats_display(portid_t port_id) { + static uint64_t prev_pkts_rx[RTE_MAX_ETHPORTS]; + static uint64_t prev_pkts_tx[RTE_MAX_ETHPORTS]; + static uint64_t prev_cycles[RTE_MAX_ETHPORTS]; + uint64_t diff_pkts_rx, diff_pkts_tx, diff_cycles; + uint64_t mpps_rx, mpps_tx; struct rte_eth_stats stats; struct rte_port *port = &ports[port_id]; uint8_t i; @@ -209,6 +220,23 @@ nic_stats_display(portid_t port_id) } } + diff_cycles = prev_cycles[port_id]; + prev_cycles[port_id] = rte_rdtsc(); + if (diff_cycles > 0) + diff_cycles = prev_cycles[port_id] - diff_cycles; + + diff_pkts_rx = stats.ipackets - prev_pkts_rx[port_id]; + diff_pkts_tx = stats.opackets - prev_pkts_tx[port_id]; + prev_pkts_rx[port_id] = stats.ipackets; + prev_pkts_tx[port_id] = stats.opackets; + mpps_rx = diff_cycles > 0 ? + diff_pkts_rx * rte_get_tsc_hz() / diff_cycles : 0; + mpps_tx = diff_cycles > 0 ? + diff_pkts_tx * rte_get_tsc_hz() / diff_cycles : 0; + printf("\n Throughput (since last show)\n"); + printf(" Rx-pps: %12"PRIu64"\n Tx-pps: %12"PRIu64"\n", + mpps_rx, mpps_tx); + printf(" %s############################%s\n", nic_stats_border, nic_stats_border); } @@ -232,29 +260,56 @@ nic_stats_clear(portid_t port_id) void nic_xstats_display(portid_t port_id) { - struct rte_eth_xstats *xstats; - int len, ret, i; + struct rte_eth_xstat *xstats; + int cnt_xstats, idx_xstat; + struct rte_eth_xstat_name *xstats_names; printf("###### NIC extended statistics for port %-2d\n", port_id); + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("Error: Invalid port number %i\n", port_id); + return; + } - len = rte_eth_xstats_get(port_id, NULL, 0); - if (len < 0) { - printf("Cannot get xstats count\n"); + /* Get count */ + cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0); + if (cnt_xstats < 0) { + printf("Error: Cannot get count of xstats\n"); return; } - xstats = malloc(sizeof(xstats[0]) * len); + + /* Get id-name lookup table */ + xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats); + if (xstats_names == NULL) { + printf("Cannot allocate memory for xstats lookup\n"); + return; + } + if (cnt_xstats != rte_eth_xstats_get_names( + port_id, xstats_names, cnt_xstats)) { + printf("Error: Cannot get xstats lookup\n"); + free(xstats_names); + return; + } + + /* Get stats themselves */ + xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats); if (xstats == NULL) { printf("Cannot allocate memory for xstats\n"); + free(xstats_names); return; } - ret = rte_eth_xstats_get(port_id, xstats, len); - if (ret < 0 || ret > len) { - printf("Cannot get xstats\n"); + if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) { + printf("Error: Unable to get xstats\n"); + free(xstats_names); free(xstats); return; } - for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + + /* Display xstats */ + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) + printf("%s: %"PRIu64"\n", + xstats_names[idx_xstat].name, + xstats[idx_xstat].value); + free(xstats_names); free(xstats); } @@ -893,8 +948,9 @@ fwd_lcores_config_display(void) void rxtx_config_display(void) { - printf(" %s packet forwarding - CRC stripping %s - " + printf(" %s packet forwarding%s - CRC stripping %s - " "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name, + retry_enabled == 0 ? "" : " with retry", rx_mode.hw_strip_crc ? "enabled" : "disabled", nb_pkt_per_burst); @@ -1131,6 +1187,7 @@ simple_fwd_config_setup(void) fwd_streams[i]->tx_port = fwd_ports_ids[j]; fwd_streams[i]->tx_queue = 0; fwd_streams[i]->peer_addr = j; + fwd_streams[i]->retry_enabled = retry_enabled; if (port_topology == PORT_TOPOLOGY_PAIRED) { fwd_streams[j]->rx_port = fwd_ports_ids[j]; @@ -1138,6 +1195,7 @@ simple_fwd_config_setup(void) fwd_streams[j]->tx_port = fwd_ports_ids[i]; fwd_streams[j]->tx_queue = 0; fwd_streams[j]->peer_addr = i; + fwd_streams[j]->retry_enabled = retry_enabled; } } } @@ -1173,10 +1231,8 @@ rss_fwd_config_setup(void) cur_fwd_config.nb_fwd_ports = nb_fwd_ports; cur_fwd_config.nb_fwd_streams = (streamid_t) (nb_q * cur_fwd_config.nb_fwd_ports); - if (cur_fwd_config.nb_fwd_streams > cur_fwd_config.nb_fwd_lcores) - cur_fwd_config.nb_fwd_streams = - (streamid_t)cur_fwd_config.nb_fwd_lcores; - else + + if (cur_fwd_config.nb_fwd_streams < cur_fwd_config.nb_fwd_lcores) cur_fwd_config.nb_fwd_lcores = (lcoreid_t)cur_fwd_config.nb_fwd_streams; @@ -1185,7 +1241,7 @@ rss_fwd_config_setup(void) setup_fwd_config_of_each_lcore(&cur_fwd_config); rxp = 0; rxq = 0; - for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) { + for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_streams; lc_id++) { struct fwd_stream *fs; fs = fwd_streams[lc_id]; @@ -1206,6 +1262,7 @@ rss_fwd_config_setup(void) fs->tx_port = fwd_ports_ids[txp]; fs->tx_queue = rxq; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; rxq = (queueid_t) (rxq + 1); if (rxq < nb_q) continue; @@ -1280,6 +1337,7 @@ dcb_fwd_config_setup(void) fs->tx_port = fwd_ports_ids[txp]; fs->tx_queue = txq + j % nb_tx_queue; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; } fwd_lcores[lc_id]->stream_nb += rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue; @@ -1350,6 +1408,7 @@ icmp_echo_config_setup(void) fs->tx_port = fs->rx_port; fs->tx_queue = rxq; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; if (verbose_level > 0) printf(" stream=%d port=%d rxq=%d txq=%d\n", sm_id, fs->rx_port, fs->rx_queue, @@ -1381,21 +1440,22 @@ fwd_config_setup(void) simple_fwd_config_setup(); } -static void +void pkt_fwd_config_display(struct fwd_config *cfg) { struct fwd_stream *fs; lcoreid_t lc_id; streamid_t sm_id; - printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - " + printf("%s packet forwarding%s - ports=%d - cores=%d - streams=%d - " "NUMA support %s, MP over anonymous pages %s\n", cfg->fwd_eng->fwd_mode_name, + retry_enabled == 0 ? "" : " with retry", cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams, numa_support == 1 ? "enabled" : "disabled", mp_anon != 0 ? "enabled" : "disabled"); - if (strcmp(cfg->fwd_eng->fwd_mode_name, "mac_retry") == 0) + if (retry_enabled) printf("TX retry num: %u, delay between TX retries: %uus\n", burst_tx_retry_num, burst_tx_delay_time); for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) { @@ -1420,14 +1480,6 @@ pkt_fwd_config_display(struct fwd_config *cfg) printf("\n"); } - -void -fwd_config_display(void) -{ - fwd_config_setup(); - pkt_fwd_config_display(&cur_fwd_config); -} - int set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc) { @@ -1565,6 +1617,22 @@ set_fwd_ports_number(uint16_t nb_pt) (unsigned int) nb_fwd_ports); } +int +port_is_forwarding(portid_t port_id) +{ + unsigned int i; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return -1; + + for (i = 0; i < nb_fwd_ports; i++) { + if (fwd_ports_ids[i] == port_id) + return 1; + } + + return 0; +} + void set_nb_pkt_per_burst(uint16_t nb) { @@ -1673,8 +1741,35 @@ list_pkt_forwarding_modes(void) if (strlen (fwd_modes) == 0) { while ((fwd_eng = fwd_engines[i++]) != NULL) { - strcat(fwd_modes, fwd_eng->fwd_mode_name); - strcat(fwd_modes, separator); + strncat(fwd_modes, fwd_eng->fwd_mode_name, + sizeof(fwd_modes) - strlen(fwd_modes) - 1); + strncat(fwd_modes, separator, + sizeof(fwd_modes) - strlen(fwd_modes) - 1); + } + fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0'; + } + + return fwd_modes; +} + +char* +list_pkt_forwarding_retry_modes(void) +{ + static char fwd_modes[128] = ""; + const char *separator = "|"; + struct fwd_engine *fwd_eng; + unsigned i = 0; + + if (strlen(fwd_modes) == 0) { + while ((fwd_eng = fwd_engines[i++]) != NULL) { + if (fwd_eng == &rx_only_engine) + continue; + strncat(fwd_modes, fwd_eng->fwd_mode_name, + sizeof(fwd_modes) - + strlen(fwd_modes) - 1); + strncat(fwd_modes, separator, + sizeof(fwd_modes) - + strlen(fwd_modes) - 1); } fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0'; } @@ -1691,8 +1786,9 @@ set_pkt_forwarding_mode(const char *fwd_mode_name) i = 0; while ((fwd_eng = fwd_engines[i]) != NULL) { if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) { - printf("Set %s packet forwarding mode\n", - fwd_mode_name); + printf("Set %s packet forwarding mode%s\n", + fwd_mode_name, + retry_enabled == 0 ? "" : " with retry"); cur_fwd_eng = fwd_eng; return; } @@ -2028,6 +2124,10 @@ flowtype_to_str(uint16_t flow_type) {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP}, {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER}, {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD}, + {"port", RTE_ETH_FLOW_PORT}, + {"vxlan", RTE_ETH_FLOW_VXLAN}, + {"geneve", RTE_ETH_FLOW_GENEVE}, + {"nvgre", RTE_ETH_FLOW_NVGRE}, }; for (i = 0; i < RTE_DIM(flowtype_str_table); i++) { diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 7e4f6620..ac4bd8f4 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -643,6 +643,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint16_t i; uint64_t ol_flags; uint16_t testpmd_ol_flags; + uint32_t retry; uint32_t rx_bad_ip_csum; uint32_t rx_bad_l4_csum; struct testpmd_offload_info info; @@ -676,6 +677,9 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) info.tso_segsz = txp->tso_segsz; for (i = 0; i < nb_rx; i++) { + if (likely(i < nb_rx - 1)) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], + void *)); ol_flags = 0; info.is_tunnel = 0; @@ -845,6 +849,17 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) } } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; fs->rx_bad_ip_csum += rx_bad_ip_csum; fs->rx_bad_l4_csum += rx_bad_l4_csum; diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c index 0f307e85..a6abe91e 100644 --- a/app/test-pmd/flowgen.c +++ b/app/test-pmd/flowgen.c @@ -89,17 +89,6 @@ static struct ether_addr cfg_ether_dst = #define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */ #define IP_VHL_DEF (IP_VERSION | IP_HDRLEN) -static inline struct rte_mbuf * -tx_mbuf_alloc(struct rte_mempool *mp) -{ - struct rte_mbuf *m; - - m = __rte_mbuf_raw_alloc(mp); - __rte_mbuf_sanity_check_raw(m, 0); - return m; -} - - static inline uint16_t ip_sum(const unaligned_uint16_t *hdr, int hdr_len) { @@ -142,6 +131,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs) uint16_t nb_tx; uint16_t nb_pkt; uint16_t i; + uint32_t retry; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; uint64_t end_tsc; @@ -167,7 +157,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs) ol_flags = ports[fs->tx_port].tx_ol_flags; for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { - pkt = tx_mbuf_alloc(mbp); + pkt = rte_mbuf_raw_alloc(mbp); if (!pkt) break; @@ -218,6 +208,17 @@ pkt_burst_flow_gen(struct fwd_stream *fs) } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c index e510f9bf..be308c9f 100644 --- a/app/test-pmd/icmpecho.c +++ b/app/test-pmd/icmpecho.c @@ -311,6 +311,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) struct ipv4_hdr *ip_h; struct icmp_hdr *icmp_h; struct ether_addr eth_addr; + uint32_t retry; uint32_t ip_addr; uint16_t nb_rx; uint16_t nb_tx; @@ -346,6 +347,9 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) fs->rx_packets += nb_rx; nb_replies = 0; for (i = 0; i < nb_rx; i++) { + if (likely(i < nb_rx - 1)) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], + void *)); pkt = pkts_burst[i]; eth_h = rte_pktmbuf_mtod(pkt, struct ether_hdr *); eth_type = RTE_BE_TO_CPU_16(eth_h->ether_type); @@ -515,6 +519,20 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) if (nb_replies > 0) { nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_replies); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_replies) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_replies && + retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, + fs->tx_queue, + &pkts_burst[nb_tx], + nb_replies - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c index 8840d868..7b6033a5 100644 --- a/app/test-pmd/iofwd.c +++ b/app/test-pmd/iofwd.c @@ -80,6 +80,8 @@ pkt_burst_io_forward(struct fwd_stream *fs) struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; uint16_t nb_rx; uint16_t nb_tx; + uint32_t retry; + #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; uint64_t end_tsc; @@ -93,16 +95,28 @@ pkt_burst_io_forward(struct fwd_stream *fs) /* * Receive a burst of packets and forward them. */ - nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, - nb_pkt_per_burst); + nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, + pkts_burst, nb_pkt_per_burst); if (unlikely(nb_rx == 0)) return; + fs->rx_packets += nb_rx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->rx_burst_stats.pkt_burst_spread[nb_rx]++; #endif - fs->rx_packets += nb_rx; - nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/macfwd-retry.c b/app/test-pmd/macfwd-retry.c deleted file mode 100644 index 3a96b3df..00000000 --- a/app/test-pmd/macfwd-retry.c +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdarg.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <stdint.h> -#include <unistd.h> -#include <inttypes.h> - -#include <sys/queue.h> -#include <sys/stat.h> - -#include <rte_common.h> -#include <rte_byteorder.h> -#include <rte_log.h> -#include <rte_debug.h> -#include <rte_cycles.h> -#include <rte_memory.h> -#include <rte_memcpy.h> -#include <rte_memzone.h> -#include <rte_launch.h> -#include <rte_eal.h> -#include <rte_per_lcore.h> -#include <rte_lcore.h> -#include <rte_atomic.h> -#include <rte_branch_prediction.h> -#include <rte_ring.h> -#include <rte_memory.h> -#include <rte_mempool.h> -#include <rte_mbuf.h> -#include <rte_interrupts.h> -#include <rte_pci.h> -#include <rte_ether.h> -#include <rte_ethdev.h> -#include <rte_ip.h> -#include <rte_string_fns.h> - -#include "testpmd.h" - -#define BURST_TX_WAIT_US 10 -#define BURST_TX_RETRIES 5 - -/* - * Global variables that control number of retires and - * timeout (in us) between retires. - */ -uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; -uint32_t burst_tx_retry_num = BURST_TX_RETRIES; - -/* - * Forwarding of packets in MAC mode with a wait and retry on TX to reduce packet loss. - * Change the source and the destination Ethernet addressed of packets - * before forwarding them. - */ -static void -pkt_burst_mac_retry_forward(struct fwd_stream *fs) -{ - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_mbuf *mb; - struct ether_hdr *eth_hdr; - uint32_t retry; - uint16_t nb_rx; - uint16_t nb_tx; - uint16_t i; -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - uint64_t start_tsc; - uint64_t end_tsc; - uint64_t core_cycles; -#endif - -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - start_tsc = rte_rdtsc(); -#endif - - /* - * Receive a burst of packets and forward them. - */ - nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, - nb_pkt_per_burst); - if (unlikely(nb_rx == 0)) - return; - -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->rx_burst_stats.pkt_burst_spread[nb_rx]++; -#endif - fs->rx_packets += nb_rx; - for (i = 0; i < nb_rx; i++) { - mb = pkts_burst[i]; - eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *); - ether_addr_copy(&peer_eth_addrs[fs->peer_addr], - ð_hdr->d_addr); - ether_addr_copy(&ports[fs->tx_port].eth_addr, - ð_hdr->s_addr); - } - nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); - - /* - * If not all packets have been TX'd then wait and retry. - */ - if (unlikely(nb_tx < nb_rx)) { - for (retry = 0; retry < burst_tx_retry_num; retry++) { - rte_delay_us(burst_tx_delay_time); - nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, - &pkts_burst[nb_tx], nb_rx - nb_tx); - if (nb_tx == nb_rx) - break; - } - } - - fs->tx_packets += nb_tx; -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; -#endif - if (unlikely(nb_tx < nb_rx)) { - fs->fwd_dropped += (nb_rx - nb_tx); - do { - rte_pktmbuf_free(pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); - } -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - end_tsc = rte_rdtsc(); - core_cycles = (end_tsc - start_tsc); - fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles); -#endif -} - -struct fwd_engine mac_retry_fwd_engine = { - .fwd_mode_name = "mac_retry", - .port_fwd_begin = NULL, - .port_fwd_end = NULL, - .packet_fwd = pkt_burst_mac_retry_forward, -}; diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c index 3b7fffb7..5d1c1617 100644 --- a/app/test-pmd/macfwd.c +++ b/app/test-pmd/macfwd.c @@ -81,6 +81,7 @@ pkt_burst_mac_forward(struct fwd_stream *fs) struct rte_port *txp; struct rte_mbuf *mb; struct ether_hdr *eth_hdr; + uint32_t retry; uint16_t nb_rx; uint16_t nb_tx; uint16_t i; @@ -113,6 +114,9 @@ pkt_burst_mac_forward(struct fwd_stream *fs) if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ) ol_flags |= PKT_TX_QINQ_PKT; for (i = 0; i < nb_rx; i++) { + if (likely(i < nb_rx - 1)) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], + void *)); mb = pkts_burst[i]; eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *); ether_addr_copy(&peer_eth_addrs[fs->peer_addr], @@ -126,6 +130,18 @@ pkt_burst_mac_forward(struct fwd_stream *fs) mb->vlan_tci_outer = txp->tx_vlan_id_outer; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } + fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/macswap.c b/app/test-pmd/macswap.c index 154889d1..4b0dbeb5 100644 --- a/app/test-pmd/macswap.c +++ b/app/test-pmd/macswap.c @@ -84,6 +84,7 @@ pkt_burst_mac_swap(struct fwd_stream *fs) uint16_t nb_rx; uint16_t nb_tx; uint16_t i; + uint32_t retry; uint64_t ol_flags = 0; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; @@ -113,6 +114,9 @@ pkt_burst_mac_swap(struct fwd_stream *fs) if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ) ol_flags |= PKT_TX_QINQ_PKT; for (i = 0; i < nb_rx; i++) { + if (likely(i < nb_rx - 1)) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], + void *)); mb = pkts_burst[i]; eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *); @@ -128,6 +132,17 @@ pkt_burst_mac_swap(struct fwd_stream *fs) mb->vlan_tci_outer = txp->tx_vlan_id_outer; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/mempool_anon.c b/app/test-pmd/mempool_anon.c deleted file mode 100644 index 47304329..00000000 --- a/app/test-pmd/mempool_anon.c +++ /dev/null @@ -1,201 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include "mempool_osdep.h" -#include <rte_errno.h> - -#ifdef RTE_EXEC_ENV_LINUXAPP - -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> - - -#define PAGEMAP_FNAME "/proc/self/pagemap" - -/* - * the pfn (page frame number) are bits 0-54 (see pagemap.txt in linux - * Documentation). - */ -#define PAGEMAP_PFN_BITS 54 -#define PAGEMAP_PFN_MASK RTE_LEN2MASK(PAGEMAP_PFN_BITS, phys_addr_t) - - -static int -get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz) -{ - int32_t fd, rc; - uint32_t i, nb; - off_t ofs; - - ofs = (uintptr_t)va / pg_sz * sizeof(*pa); - nb = pg_num * sizeof(*pa); - - if ((fd = open(PAGEMAP_FNAME, O_RDONLY)) < 0) - return ENOENT; - - if ((rc = pread(fd, pa, nb, ofs)) < 0 || (rc -= nb) != 0) { - - RTE_LOG(ERR, USER1, "failed read of %u bytes from \'%s\' " - "at offset %zu, error code: %d\n", - nb, PAGEMAP_FNAME, (size_t)ofs, errno); - rc = ENOENT; - } - - close(fd); - - for (i = 0; i != pg_num; i++) - pa[i] = (pa[i] & PAGEMAP_PFN_MASK) * pg_sz; - - return rc; -} - -struct rte_mempool * -mempool_anon_create(const char *name, unsigned elt_num, unsigned elt_size, - unsigned cache_size, unsigned private_data_size, - rte_mempool_ctor_t *mp_init, void *mp_init_arg, - rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg, - int socket_id, unsigned flags) -{ - struct rte_mempool *mp; - phys_addr_t *pa; - char *va, *uv; - uint32_t n, pg_num, pg_shift, pg_sz, total_size; - size_t sz; - ssize_t usz; - int32_t rc; - - rc = ENOMEM; - mp = NULL; - - pg_sz = getpagesize(); - if (rte_is_power_of_2(pg_sz) == 0) { - rte_errno = EINVAL; - return mp; - } - - pg_shift = rte_bsf32(pg_sz); - - total_size = rte_mempool_calc_obj_size(elt_size, flags, NULL); - - /* calc max memory size and max number of pages needed. */ - sz = rte_mempool_xmem_size(elt_num, total_size, pg_shift); - pg_num = sz >> pg_shift; - - /* get chunk of virtually continuos memory.*/ - if ((va = mmap(NULL, sz, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS | MAP_LOCKED, - -1, 0)) == MAP_FAILED) { - RTE_LOG(ERR, USER1, "%s(%s) failed mmap of %zu bytes, " - "error code: %d\n", - __func__, name, sz, errno); - rte_errno = rc; - return mp; - } - - /* extract physical mappings of the allocated memory. */ - if ((pa = calloc(pg_num, sizeof (*pa))) != NULL && - (rc = get_phys_map(va, pa, pg_num, pg_sz)) == 0) { - - /* - * Check that allocated size is big enough to hold elt_num - * objects and a calcualte how many bytes are actually required. - */ - - if ((usz = rte_mempool_xmem_usage(va, elt_num, total_size, pa, - pg_num, pg_shift)) < 0) { - - n = -usz; - rc = ENOENT; - RTE_LOG(ERR, USER1, "%s(%s) only %u objects from %u " - "requested can be created over " - "mmaped region %p of %zu bytes\n", - __func__, name, n, elt_num, va, sz); - } else { - - /* unmap unused pages if any */ - if ((size_t)usz < sz) { - - uv = va + usz; - usz = sz - usz; - - RTE_LOG(INFO, USER1, - "%s(%s): unmap unused %zu of %zu " - "mmaped bytes @%p\n", - __func__, name, (size_t)usz, sz, uv); - munmap(uv, usz); - sz -= usz; - pg_num = sz >> pg_shift; - } - - if ((mp = rte_mempool_xmem_create(name, elt_num, - elt_size, cache_size, private_data_size, - mp_init, mp_init_arg, - obj_init, obj_init_arg, - socket_id, flags, va, pa, pg_num, - pg_shift)) != NULL) - - RTE_VERIFY(elt_num == mp->size); - } - } - - if (mp == NULL) { - munmap(va, sz); - rte_errno = rc; - } - - free(pa); - return mp; -} - -#else /* RTE_EXEC_ENV_LINUXAPP */ - - -struct rte_mempool * -mempool_anon_create(__rte_unused const char *name, - __rte_unused unsigned elt_num, __rte_unused unsigned elt_size, - __rte_unused unsigned cache_size, - __rte_unused unsigned private_data_size, - __rte_unused rte_mempool_ctor_t *mp_init, - __rte_unused void *mp_init_arg, - __rte_unused rte_mempool_obj_ctor_t *obj_init, - __rte_unused void *obj_init_arg, - __rte_unused int socket_id, __rte_unused unsigned flags) -{ - rte_errno = ENOTSUP; - return NULL; -} - -#endif /* RTE_EXEC_ENV_LINUXAPP */ diff --git a/app/test-pmd/mempool_osdep.h b/app/test-pmd/mempool_osdep.h deleted file mode 100644 index 6b8df68a..00000000 --- a/app/test-pmd/mempool_osdep.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MEMPOOL_OSDEP_H_ -#define _MEMPOOL_OSDEP_H_ - -#include <rte_mempool.h> - -/** - * @file - * mempool OS specific header. - */ - -/* - * Create mempool over objects from mmap(..., MAP_ANONYMOUS, ...). - */ -struct rte_mempool * -mempool_anon_create(const char *name, unsigned n, unsigned elt_size, - unsigned cache_size, unsigned private_data_size, - rte_mempool_ctor_t *mp_init, void *mp_init_arg, - rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg, - int socket_id, unsigned flags); - -#endif /*_RTE_MEMPOOL_OSDEP_H_ */ diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index 55572ebe..8792c2c6 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -526,6 +526,7 @@ launch_args_parse(int argc, char** argv) { "pkt-filter-drop-queue", 1, 0, 0 }, { "crc-strip", 0, 0, 0 }, { "enable-rx-cksum", 0, 0, 0 }, + { "enable-scatter", 0, 0, 0 }, { "disable-hw-vlan", 0, 0, 0 }, { "disable-hw-vlan-filter", 0, 0, 0 }, { "disable-hw-vlan-strip", 0, 0, 0 }, @@ -764,6 +765,8 @@ launch_args_parse(int argc, char** argv) } if (!strcmp(lgopts[opt_idx].name, "crc-strip")) rx_mode.hw_strip_crc = 1; + if (!strcmp(lgopts[opt_idx].name, "enable-scatter")) + rx_mode.enable_scatter = 1; if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum")) rx_mode.hw_ip_checksum = 1; diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c index 14555abc..fbf287dc 100644 --- a/app/test-pmd/rxonly.c +++ b/app/test-pmd/rxonly.c @@ -156,9 +156,9 @@ pkt_burst_receive(struct fwd_stream *fs) printf("hash=0x%x ID=0x%x ", mb->hash.fdir.hash, mb->hash.fdir.id); } - if (ol_flags & PKT_RX_VLAN_PKT) + if (ol_flags & PKT_RX_VLAN_STRIPPED) printf(" - VLAN tci=0x%x", mb->vlan_tci); - if (ol_flags & PKT_RX_QINQ_PKT) + if (ol_flags & PKT_RX_QINQ_STRIPPED) printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x", mb->vlan_tci, mb->vlan_tci_outer); if (mb->packet_type) { @@ -179,6 +179,9 @@ pkt_burst_receive(struct fwd_stream *fs) case RTE_PTYPE_L2_ETHER_LLDP: printf(" - (outer) L2 type: ETHER_LLDP"); break; + case RTE_PTYPE_L2_ETHER_NSH: + printf(" - (outer) L2 type: ETHER_NSH"); + break; default: printf(" - (outer) L2 type: Unknown"); break; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 26a174c1..06885ceb 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -49,6 +49,7 @@ #include <inttypes.h> #include <rte_common.h> +#include <rte_errno.h> #include <rte_byteorder.h> #include <rte_log.h> #include <rte_debug.h> @@ -75,9 +76,11 @@ #ifdef RTE_LIBRTE_PMD_XENVIRT #include <rte_eth_xenvirt.h> #endif +#ifdef RTE_LIBRTE_PDUMP +#include <rte_pdump.h> +#endif #include "testpmd.h" -#include "mempool_osdep.h" uint16_t verbose_level = 0; /**< Silent by default. */ @@ -144,7 +147,6 @@ streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ struct fwd_engine * fwd_engines[] = { &io_fwd_engine, &mac_fwd_engine, - &mac_retry_fwd_engine, &mac_swap_engine, &flow_gen_engine, &rx_only_engine, @@ -159,6 +161,9 @@ struct fwd_engine * fwd_engines[] = { struct fwd_config cur_fwd_config; struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ +uint32_t retry_enabled; +uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; +uint32_t burst_tx_retry_num = BURST_TX_RETRIES; uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if @@ -416,6 +421,10 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); + RTE_LOG(INFO, USER1, + "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", + pool_name, nb_mbuf, mbuf_seg_size, socket_id); + #ifdef RTE_LIBRTE_PMD_XENVIRT rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size, (unsigned) mb_mempool_cache, @@ -427,22 +436,29 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, /* if the former XEN allocation failed fall back to normal allocation */ if (rte_mp == NULL) { - if (mp_anon != 0) - rte_mp = mempool_anon_create(pool_name, nb_mbuf, - mb_size, (unsigned) mb_mempool_cache, - sizeof(struct rte_pktmbuf_pool_private), - rte_pktmbuf_pool_init, NULL, - rte_pktmbuf_init, NULL, - socket_id, 0); - else + if (mp_anon != 0) { + rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, + mb_size, (unsigned) mb_mempool_cache, + sizeof(struct rte_pktmbuf_pool_private), + socket_id, 0); + + if (rte_mempool_populate_anon(rte_mp) == 0) { + rte_mempool_free(rte_mp); + rte_mp = NULL; + } + rte_pktmbuf_pool_init(rte_mp, NULL); + rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); + } else { /* wrapper to rte_mempool_create() */ rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, mb_mempool_cache, 0, mbuf_seg_size, socket_id); + } } if (rte_mp == NULL) { - rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u " - "failed\n", socket_id); + rte_exit(EXIT_FAILURE, + "Creation of mbuf pool for socket %u failed: %s\n", + socket_id, rte_strerror(rte_errno)); } else if (verbose_level > 0) { rte_mempool_dump(stdout, rte_mp); } @@ -580,6 +596,8 @@ init_config(void) /* Configuration of packet forwarding streams. */ if (init_fwd_streams() < 0) rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); + + fwd_config_setup(); } @@ -981,6 +999,12 @@ start_packet_forwarding(int with_tx_first) printf("Packet forwarding already started\n"); return; } + + if (init_fwd_streams() < 0) { + printf("Fail from init_fwd_streams()\n"); + return; + } + if(dcb_test) { for (i = 0; i < nb_fwd_ports; i++) { pt_id = fwd_ports_ids[i]; @@ -1003,6 +1027,7 @@ start_packet_forwarding(int with_tx_first) flush_fwd_rx_queues(); fwd_config_setup(); + pkt_fwd_config_display(&cur_fwd_config); rxtx_config_display(); for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { @@ -1036,8 +1061,11 @@ start_packet_forwarding(int with_tx_first) for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) (*port_fwd_begin)(fwd_ports_ids[i]); } - launch_packet_forwarding(run_one_txonly_burst_on_core); - rte_eal_mp_wait_lcore(); + while (with_tx_first--) { + launch_packet_forwarding( + run_one_txonly_burst_on_core); + rte_eal_mp_wait_lcore(); + } port_fwd_end = tx_only_engine.port_fwd_end; if (port_fwd_end != NULL) { for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) @@ -1070,10 +1098,6 @@ stop_packet_forwarding(void) #endif static const char *acc_stats_border = "+++++++++++++++"; - if (all_ports_started() == 0) { - printf("Not all ports were started\n"); - return; - } if (test_done) { printf("Packet forwarding not started\n"); return; @@ -1268,19 +1292,9 @@ start_port(portid_t pid) struct rte_port *port; struct ether_addr mac_addr; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return -1; - } - if (port_id_is_invalid(pid, ENABLED_WARN)) return 0; - if (init_fwd_streams() < 0) { - printf("Fail from init_fwd_streams()\n"); - return -1; - } - if(dcb_config) dcb_test = 1; FOREACH_PORT(pi, ports) { @@ -1351,7 +1365,7 @@ start_port(portid_t pid) if (mp == NULL) { printf("Failed to setup RX queue:" "No mempool allocation" - "on the socket %d\n", + " on the socket %d\n", rxring_numa[pi]); return -1; } @@ -1359,17 +1373,23 @@ start_port(portid_t pid) diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd,rxring_numa[pi], &(port->rx_conf),mp); - } - else + } else { + struct rte_mempool *mp = + mbuf_pool_find(port->socket_id); + if (mp == NULL) { + printf("Failed to setup RX queue:" + "No mempool allocation" + " on the socket %d\n", + port->socket_id); + return -1; + } diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd,port->socket_id, - &(port->rx_conf), - mbuf_pool_find(port->socket_id)); - + &(port->rx_conf), mp); + } if (diag == 0) continue; - /* Fail to setup rx queue, return */ if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_HANDLING, @@ -1424,10 +1444,6 @@ stop_port(portid_t pid) struct rte_port *port; int need_check_link_status = 0; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } if (dcb_test) { dcb_test = 0; dcb_config = 0; @@ -1442,6 +1458,16 @@ stop_port(portid_t pid) if (pid != pi && pid != (portid_t)RTE_PORT_ALL) continue; + if (port_is_forwarding(pi) != 0 && test_done == 0) { + printf("Please remove port %d from forwarding configuration.\n", pi); + continue; + } + + if (port_is_bonding_slave(pi)) { + printf("Please remove port %d from bonded device.\n", pi); + continue; + } + port = &ports[pi]; if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, RTE_PORT_HANDLING) == 0) @@ -1466,11 +1492,6 @@ close_port(portid_t pid) portid_t pi; struct rte_port *port; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } - if (port_id_is_invalid(pid, ENABLED_WARN)) return; @@ -1480,6 +1501,16 @@ close_port(portid_t pid) if (pid != pi && pid != (portid_t)RTE_PORT_ALL) continue; + if (port_is_forwarding(pi) != 0 && test_done == 0) { + printf("Please remove port %d from forwarding configuration.\n", pi); + continue; + } + + if (port_is_bonding_slave(pi)) { + printf("Please remove port %d from bonded device.\n", pi); + continue; + } + port = &ports[pi]; if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { @@ -1497,7 +1528,7 @@ close_port(portid_t pid) if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) - printf("Port %d can not be set into stopped\n", pi); + printf("Port %d cannot be set to closed\n", pi); } printf("Done\n"); @@ -1506,7 +1537,8 @@ close_port(portid_t pid) void attach_port(char *identifier) { - portid_t i, j, pi = 0; + portid_t pi = 0; + unsigned int socket_id; printf("Attaching a new port...\n"); @@ -1515,30 +1547,19 @@ attach_port(char *identifier) return; } - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } - if (rte_eth_dev_attach(identifier, &pi)) return; ports[pi].enabled = 1; - reconfig(pi, rte_eth_dev_socket_id(pi)); + socket_id = (unsigned)rte_eth_dev_socket_id(pi); + /* if socket_id is invalid, set to 0 */ + if (check_socket_id(socket_id) < 0) + socket_id = 0; + reconfig(pi, socket_id); rte_eth_promiscuous_enable(pi); nb_ports = rte_eth_dev_count(); - /* set_default_fwd_ports_config(); */ - memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids)); - i = 0; - FOREACH_PORT(j, ports) { - fwd_ports_ids[i] = j; - i++; - } - nb_cfg_ports = nb_ports; - nb_fwd_ports++; - ports[pi].port_status = RTE_PORT_STOPPED; printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); @@ -1548,7 +1569,6 @@ attach_port(char *identifier) void detach_port(uint8_t port_id) { - portid_t i, pi = 0; char name[RTE_ETH_NAME_MAX_LEN]; printf("Detaching a port...\n"); @@ -1564,16 +1584,6 @@ detach_port(uint8_t port_id) ports[port_id].enabled = 0; nb_ports = rte_eth_dev_count(); - /* set_default_fwd_ports_config(); */ - memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids)); - i = 0; - FOREACH_PORT(pi, ports) { - fwd_ports_ids[i] = pi; - i++; - } - nb_cfg_ports = nb_ports; - nb_fwd_ports--; - printf("Port '%s' is detached. Now total ports is %d\n", name, nb_ports); printf("Done\n"); @@ -1843,6 +1853,14 @@ void clear_port_slave_flag(portid_t slave_pid) port->slave_flag = 0; } +uint8_t port_is_bonding_slave(portid_t slave_pid) +{ + struct rte_port *port; + + port = &ports[slave_pid]; + return port->slave_flag; +} + const uint16_t vlan_tags[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -2018,6 +2036,10 @@ signal_handler(int signum) if (signum == SIGINT || signum == SIGTERM) { printf("\nSignal %d received, preparing to exit...\n", signum); +#ifdef RTE_LIBRTE_PDUMP + /* uninitialize packet capture framework */ + rte_pdump_uninit(); +#endif force_quit(); /* exit with the expected status */ signal(signum, SIG_DFL); @@ -2038,6 +2060,11 @@ main(int argc, char** argv) if (diag < 0) rte_panic("Cannot init EAL\n"); +#ifdef RTE_LIBRTE_PDUMP + /* initialize packet capture framework */ + rte_pdump_init(NULL); +#endif + nb_ports = (portid_t) rte_eth_dev_count(); if (nb_ports == 0) RTE_LOG(WARNING, EAL, "No probed ethernet devices\n"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 0f72ca1f..2b281cc4 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -103,6 +103,8 @@ struct fwd_stream { queueid_t tx_queue; /**< TX queue to send forwarded packets */ streamid_t peer_addr; /**< index of peer ethernet address of packets */ + unsigned int retry_enabled; + /* "read-write" results */ unsigned int rx_packets; /**< received packets */ unsigned int tx_packets; /**< received packets transmitted */ @@ -220,9 +222,14 @@ struct fwd_engine { packet_fwd_t packet_fwd; /**< Mandatory. */ }; +#define BURST_TX_WAIT_US 1 +#define BURST_TX_RETRIES 64 + +extern uint32_t burst_tx_delay_time; +extern uint32_t burst_tx_retry_num; + extern struct fwd_engine io_fwd_engine; extern struct fwd_engine mac_fwd_engine; -extern struct fwd_engine mac_retry_fwd_engine; extern struct fwd_engine mac_swap_engine; extern struct fwd_engine flow_gen_engine; extern struct fwd_engine rx_only_engine; @@ -380,6 +387,7 @@ extern int8_t tx_wthresh; extern struct fwd_config cur_fwd_config; extern struct fwd_engine *cur_fwd_eng; +extern uint32_t retry_enabled; extern struct fwd_lcore **fwd_lcores; extern struct fwd_stream **fwd_streams; @@ -472,7 +480,7 @@ void port_infos_display(portid_t port_id); void rx_queue_infos_display(portid_t port_idi, uint16_t queue_id); void tx_queue_infos_display(portid_t port_idi, uint16_t queue_id); void fwd_lcores_config_display(void); -void fwd_config_display(void); +void pkt_fwd_config_display(struct fwd_config *cfg); void rxtx_config_display(void); void fwd_config_setup(void); void set_def_fwd_config(void); @@ -500,6 +508,7 @@ void set_fwd_lcores_number(uint16_t nb_lc); void set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt); void set_fwd_ports_mask(uint64_t portmask); void set_fwd_ports_number(uint16_t nb_pt); +int port_is_forwarding(portid_t port_id); void rx_vlan_strip_set(portid_t port_id, int on); void rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on); @@ -523,6 +532,7 @@ void show_tx_pkt_segments(void); void set_tx_pkt_split(const char *name); void set_nb_pkt_per_burst(uint16_t pkt_burst); char *list_pkt_forwarding_modes(void); +char *list_pkt_forwarding_retry_modes(void); void set_pkt_forwarding_mode(const char *fwd_mode); void start_packet_forwarding(int with_tx_first); void stop_packet_forwarding(void); @@ -531,6 +541,8 @@ void dev_set_link_down(portid_t pid); void init_port_config(void); void set_port_slave_flag(portid_t slave_pid); void clear_port_slave_flag(portid_t slave_pid); +uint8_t port_is_bonding_slave(portid_t slave_pid); + int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode, enum rte_eth_nb_tcs num_tcs, uint8_t pfc_en); diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c index b37cae57..11fd681d 100644 --- a/app/test-pmd/txonly.c +++ b/app/test-pmd/txonly.c @@ -86,16 +86,6 @@ static struct ipv4_hdr pkt_ip_hdr; /**< IP header of transmitted packets. */ static struct udp_hdr pkt_udp_hdr; /**< UDP header of transmitted packets. */ -static inline struct rte_mbuf * -tx_mbuf_alloc(struct rte_mempool *mp) -{ - struct rte_mbuf *m; - - m = __rte_mbuf_raw_alloc(mp); - __rte_mbuf_sanity_check_raw(m, 0); - return m; -} - static void copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset) @@ -203,6 +193,7 @@ pkt_burst_transmit(struct fwd_stream *fs) uint16_t nb_tx; uint16_t nb_pkt; uint16_t vlan_tci, vlan_tci_outer; + uint32_t retry; uint64_t ol_flags = 0; uint8_t i; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES @@ -225,7 +216,7 @@ pkt_burst_transmit(struct fwd_stream *fs) if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ) ol_flags |= PKT_TX_QINQ_PKT; for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { - pkt = tx_mbuf_alloc(mbp); + pkt = rte_mbuf_raw_alloc(mbp); if (pkt == NULL) { nomore_mbuf: if (nb_pkt == 0) @@ -240,7 +231,7 @@ pkt_burst_transmit(struct fwd_stream *fs) nb_segs = tx_pkt_nb_segs; pkt_len = pkt->data_len; for (i = 1; i < nb_segs; i++) { - pkt_seg->next = tx_mbuf_alloc(mbp); + pkt_seg->next = rte_mbuf_raw_alloc(mbp); if (pkt_seg->next == NULL) { pkt->nb_segs = i; rte_pktmbuf_free(pkt); @@ -283,6 +274,17 @@ pkt_burst_transmit(struct fwd_stream *fs) pkts_burst[nb_pkt] = pkt; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_pkt) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_pkt && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_pkt - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS diff --git a/app/test/Makefile b/app/test/Makefile index a4907d59..2de8c7a6 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -33,6 +33,37 @@ include $(RTE_SDK)/mk/rte.vars.mk ifeq ($(CONFIG_RTE_APP_TEST),y) +# Define an externally linked resource. A linked resource is an arbitrary +# file that is linked into the test binary. The application refers to this +# resource by name. The linked generates identifiers beg_<name> and end_<name> +# for referencing by the C code. +# +# Parameters: <unique name>, <file to be linked> +define linked_resource +SRCS-y += $(1).res.o +$(1).res.o: $(2) + @ echo ' MKRES $$@' + $Q [ "$$(<D)" = . ] || ln -fs $$< + $Q $(OBJCOPY) -I binary -B $(RTE_OBJCOPY_ARCH) -O $(RTE_OBJCOPY_TARGET) \ + --rename-section \ + .data=.rodata,alloc,load,data,contents,readonly \ + --redefine-sym _binary_$$(subst .,_,$$(<F))_start=beg_$(1) \ + --redefine-sym _binary_$$(subst .,_,$$(<F))_end=end_$(1) \ + --redefine-sym _binary_$$(subst .,_,$$(<F))_size=siz_$(1) \ + $$(<F) $$@ +endef + +ifeq ($(CONFIG_RTE_APP_TEST_RESOURCE_TAR),y) +define linked_tar_resource +$(1).tar: $(2) + @ echo ' TAR $$@' + $Q tar -C $$(dir $$<) -cf $$@ $$(notdir $$<) +$(call linked_resource,$(1),$(1).tar) +endef +else # ! CONFIG_RTE_APP_TEST_RESOURCE_TAR +linked_tar_resource = +endif # CONFIG_RTE_APP_TEST_RESOURCE_TAR + # # library name # @@ -43,7 +74,14 @@ APP = test # SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c SRCS-y += test.c -SRCS-y += test_pci.c +SRCS-y += resource.c +SRCS-y += test_resource.c +test_resource.res: test_resource.c + @ cp $< $@ +$(eval $(call linked_resource,test_resource_c,test_resource.res)) +$(eval $(call linked_tar_resource,test_resource_tar,test_resource.c)) +SRCS-$(CONFIG_RTE_APP_TEST_RESOURCE_TAR) += test_pci.c +$(eval $(call linked_tar_resource,test_pci_sysfs,test_pci_sysfs)) SRCS-y += test_prefetch.c SRCS-y += test_byteorder.c SRCS-y += test_per_lcore.c @@ -87,9 +125,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_thash.c SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_perf.c SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_functions.c SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_scaling.c +SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_multiwriter.c SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm.c +SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm_perf.c SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm6.c +SRCS-$(CONFIG_RTE_LIBRTE_LPM) += test_lpm6_perf.c SRCS-y += test_debug.c SRCS-y += test_errno.c @@ -151,6 +192,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c @@ -164,7 +206,7 @@ CFLAGS += -D_GNU_SOURCE LDLIBS += -lm # Disable VTA for memcpy test -ifeq ($(CC), gcc) +ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1) CFLAGS_test_memcpy.o += -fno-var-tracking-assignments CFLAGS_test_memcpy_perf.o += -fno-var-tracking-assignments @@ -185,6 +227,10 @@ endif endif endif +ifeq ($(CONFIG_RTE_APP_TEST_RESOURCE_TAR),y) +LDLIBS += -larchive +endif + include $(RTE_SDK)/mk/rte.app.mk endif diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index dde45111..1e6b422c 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -58,6 +58,12 @@ parallel_test_group_list = [ "Tests" : [ { + "Name" : "Cycles autotest", + "Command" : "cycles_autotest", + "Func" : default_autotest, + "Report" : None, + }, + { "Name" : "Timer autotest", "Command" : "timer_autotest", "Func" : timer_autotest, @@ -88,9 +94,9 @@ parallel_test_group_list = [ "Report" : None, }, { - "Name" : "Dump log history", - "Command" : "dump_log_history", - "Func" : dump_autotest, + "Name" : "Resource autotest", + "Command" : "resource_autotest", + "Func" : default_autotest, "Report" : None, }, { @@ -109,7 +115,7 @@ parallel_test_group_list = [ }, { "Prefix": "group_2", - "Memory" : "128", + "Memory" : "16", "Tests" : [ { @@ -164,7 +170,7 @@ parallel_test_group_list = [ }, { "Prefix": "group_3", - "Memory" : per_sockets(1024), + "Memory" : per_sockets(390), "Tests" : [ { @@ -174,6 +180,12 @@ parallel_test_group_list = [ "Report" : None, }, { + "Name" : "LPM6 autotest", + "Command" : "lpm6_autotest", + "Func" : default_autotest, + "Report" : None, + }, + { "Name" : "IVSHMEM autotest", "Command" : "ivshmem_autotest", "Func" : default_autotest, @@ -287,7 +299,7 @@ parallel_test_group_list = [ }, { "Prefix": "group_6", - "Memory" : per_sockets(620), + "Memory" : per_sockets(128), "Tests" : [ { @@ -324,7 +336,7 @@ parallel_test_group_list = [ }, { "Prefix" : "group_7", - "Memory" : "400", + "Memory" : "64", "Tests" : [ { @@ -371,12 +383,6 @@ non_parallel_test_group_list = [ "Tests" : [ { - "Name" : "Cycles autotest", - "Command" : "cycles_autotest", - "Func" : default_autotest, - "Report" : None, - }, - { "Name" : "Mempool performance autotest", "Command" : "mempool_perf_autotest", "Func" : default_autotest, @@ -412,7 +418,7 @@ non_parallel_test_group_list = [ }, { "Prefix" : "power", - "Memory" : per_sockets(512), + "Memory" : "16", "Tests" : [ { @@ -425,7 +431,7 @@ non_parallel_test_group_list = [ }, { "Prefix" : "power_acpi_cpufreq", - "Memory" : per_sockets(512), + "Memory" : "16", "Tests" : [ { @@ -438,7 +444,7 @@ non_parallel_test_group_list = [ }, { "Prefix" : "power_kvm_vm", - "Memory" : "512", + "Memory" : "16", "Tests" : [ { @@ -450,19 +456,6 @@ non_parallel_test_group_list = [ ] }, { - "Prefix" : "lpm6", - "Memory" : "512", - "Tests" : - [ - { - "Name" : "LPM6 autotest", - "Command" : "lpm6_autotest", - "Func" : default_autotest, - "Report" : None, - }, - ] -}, -{ "Prefix": "timer_perf", "Memory" : per_sockets(512), "Tests" : diff --git a/app/test/autotest_test_funcs.py b/app/test/autotest_test_funcs.py index 0f012f6b..14cffd01 100644 --- a/app/test/autotest_test_funcs.py +++ b/app/test/autotest_test_funcs.py @@ -83,7 +83,7 @@ def spinlock_autotest(child, test_name): "Test Failed", "Hello from core ([0-9]*) !", "Hello from within recursive locks from ([0-9]*) !", - pexpect.TIMEOUT], timeout = 20) + pexpect.TIMEOUT], timeout = 5) # ok if index == 0: break @@ -145,18 +145,10 @@ def logs_autotest(child, test_name): child.sendline(test_name) log_list = [ - "TESTAPP1: this is a debug level message", - "TESTAPP1: this is a info level message", - "TESTAPP1: this is a warning level message", - "TESTAPP2: this is a info level message", - "TESTAPP2: this is a warning level message", - "TESTAPP1: this is a debug level message", - "TESTAPP1: this is a debug level message", - "TESTAPP1: this is a info level message", - "TESTAPP1: this is a warning level message", - "TESTAPP2: this is a info level message", - "TESTAPP2: this is a warning level message", - "TESTAPP1: this is a debug level message", + "TESTAPP1: error message", + "TESTAPP1: critical message", + "TESTAPP2: critical message", + "TESTAPP1: error message", ] for log_msg in log_list: @@ -181,9 +173,9 @@ def timer_autotest(child, test_name): i = 0 child.sendline(test_name) - index = child.expect(["Start timer stress tests \(20 seconds\)", + index = child.expect(["Start timer stress tests", "Test Failed", - pexpect.TIMEOUT], timeout = 10) + pexpect.TIMEOUT], timeout = 5) if index == 1: return -1, "Fail" @@ -192,16 +184,16 @@ def timer_autotest(child, test_name): index = child.expect(["Start timer stress tests 2", "Test Failed", - pexpect.TIMEOUT], timeout = 40) + pexpect.TIMEOUT], timeout = 5) if index == 1: return -1, "Fail" elif index == 2: return -1, "Fail [Timeout]" - index = child.expect(["Start timer basic tests \(20 seconds\)", + index = child.expect(["Start timer basic tests", "Test Failed", - pexpect.TIMEOUT], timeout = 20) + pexpect.TIMEOUT], timeout = 5) if index == 1: return -1, "Fail" @@ -281,7 +273,7 @@ def timer_autotest(child, test_name): def ring_autotest(child, test_name): child.sendline(test_name) index = child.expect(["Test OK", "Test Failed", - pexpect.TIMEOUT], timeout = 15) + pexpect.TIMEOUT], timeout = 2) if index == 1: return -1, "Fail" elif index == 2: diff --git a/app/test/commands.c b/app/test/commands.c index 9cb9606e..2df46b05 100644 --- a/app/test/commands.c +++ b/app/test/commands.c @@ -150,8 +150,6 @@ static void cmd_dump_parsed(void *parsed_result, rte_dump_physmem_layout(stdout); else if (!strcmp(res->dump, "dump_memzone")) rte_memzone_dump(stdout); - else if (!strcmp(res->dump, "dump_log_history")) - rte_log_dump_history(stdout); else if (!strcmp(res->dump, "dump_struct_sizes")) dump_struct_sizes(); else if (!strcmp(res->dump, "dump_ring")) @@ -164,7 +162,7 @@ static void cmd_dump_parsed(void *parsed_result, cmdline_parse_token_string_t cmd_dump_dump = TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, - "dump_physmem#dump_memzone#dump_log_history#" + "dump_physmem#dump_memzone#" "dump_struct_sizes#dump_ring#dump_mempool#" "dump_devargs"); @@ -439,7 +437,7 @@ int commands_init(void) commands_len += strlen(t->command) + 1; } - commands = malloc(commands_len); + commands = malloc(commands_len + 1); if (!commands) return -1; diff --git a/app/test/resource.c b/app/test/resource.c new file mode 100644 index 00000000..0e2b62cd --- /dev/null +++ b/app/test/resource.c @@ -0,0 +1,305 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 RehiveTech. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of RehiveTech nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/queue.h> + +#include <rte_debug.h> + +#include "resource.h" + +struct resource_list resource_list = TAILQ_HEAD_INITIALIZER(resource_list); + +size_t resource_size(const struct resource *r) +{ + return r->end - r->begin; +} + +const struct resource *resource_find(const char *name) +{ + struct resource *r; + + TAILQ_FOREACH(r, &resource_list, next) { + RTE_VERIFY(r->name); + + if (!strcmp(r->name, name)) + return r; + } + + return NULL; +} + +int resource_fwrite(const struct resource *r, FILE *f) +{ + const size_t goal = resource_size(r); + size_t total = 0; + + while (total < goal) { + size_t wlen = fwrite(r->begin + total, 1, goal - total, f); + if (wlen == 0) { + perror(__func__); + return -1; + } + + total += wlen; + } + + return 0; +} + +int resource_fwrite_file(const struct resource *r, const char *fname) +{ + FILE *f; + int ret; + + f = fopen(fname, "w"); + if (f == NULL) { + perror(__func__); + return -1; + } + + ret = resource_fwrite(r, f); + fclose(f); + return ret; +} + +#ifdef RTE_APP_TEST_RESOURCE_TAR +#include <archive.h> +#include <archive_entry.h> + +static int do_copy(struct archive *r, struct archive *w) +{ + const void *buf; + size_t len; +#if ARCHIVE_VERSION_NUMBER >= 3000000 + int64_t off; +#else + off_t off; +#endif + int ret; + + while (1) { + ret = archive_read_data_block(r, &buf, &len, &off); + if (ret == ARCHIVE_RETRY) + continue; + + if (ret == ARCHIVE_EOF) + return 0; + + if (ret != ARCHIVE_OK) + return ret; + + do { + ret = archive_write_data_block(w, buf, len, off); + if (ret != ARCHIVE_OK && ret != ARCHIVE_RETRY) + return ret; + } while (ret != ARCHIVE_OK); + } +} + +int resource_untar(const struct resource *res) +{ + struct archive *r; + struct archive *w; + struct archive_entry *e; + void *p; + int flags = 0; + int ret; + + p = malloc(resource_size(res)); + if (p == NULL) + rte_panic("Failed to malloc %zu B\n", resource_size(res)); + + memcpy(p, res->begin, resource_size(res)); + + r = archive_read_new(); + if (r == NULL) { + free(p); + return -1; + } + + archive_read_support_format_all(r); + archive_read_support_filter_all(r); + + w = archive_write_disk_new(); + if (w == NULL) { + archive_read_free(r); + free(p); + return -1; + } + + flags |= ARCHIVE_EXTRACT_PERM; + flags |= ARCHIVE_EXTRACT_FFLAGS; + archive_write_disk_set_options(w, flags); + archive_write_disk_set_standard_lookup(w); + + ret = archive_read_open_memory(r, p, resource_size(res)); + if (ret != ARCHIVE_OK) + goto fail; + + while (1) { + ret = archive_read_next_header(r, &e); + if (ret == ARCHIVE_EOF) + break; + if (ret != ARCHIVE_OK) + goto fail; + + ret = archive_write_header(w, e); + if (ret == ARCHIVE_EOF) + break; + if (ret != ARCHIVE_OK) + goto fail; + + if (archive_entry_size(e) == 0) + continue; + + ret = do_copy(r, w); + if (ret != ARCHIVE_OK) + goto fail; + + ret = archive_write_finish_entry(w); + if (ret != ARCHIVE_OK) + goto fail; + } + + archive_write_free(w); + archive_read_free(r); + free(p); + return 0; + +fail: + archive_write_free(w); + archive_read_free(r); + free(p); + rte_panic("Failed: %s\n", archive_error_string(r)); + return -1; +} + +int resource_rm_by_tar(const struct resource *res) +{ + struct archive *r; + struct archive_entry *e; + void *p; + int try_again = 1; + int attempts = 0; + int ret; + + p = malloc(resource_size(res)); + if (p == NULL) + rte_panic("Failed to malloc %zu B\n", resource_size(res)); + + memcpy(p, res->begin, resource_size(res)); + + /* + * If somebody creates a file somewhere inside the extracted TAR + * hierarchy during a test the resource_rm_by_tar might loop + * infinitely. We prevent this by adding the attempts counter there. + * In normal case, max N iteration is done where N is the depth of + * the file-hierarchy. + */ + while (try_again && attempts < 10000) { + r = archive_read_new(); + if (r == NULL) { + free(p); + return -1; + } + + archive_read_support_format_all(r); + archive_read_support_filter_all(r); + + ret = archive_read_open_memory(r, p, resource_size(res)); + if (ret != ARCHIVE_OK) { + fprintf(stderr, "Failed: %s\n", + archive_error_string(r)); + goto fail; + } + + try_again = 0; + + while (1) { + ret = archive_read_next_header(r, &e); + if (ret == ARCHIVE_EOF) + break; + if (ret != ARCHIVE_OK) + goto fail; + + ret = remove(archive_entry_pathname(e)); + if (ret < 0) { + switch (errno) { + case ENOTEMPTY: + case EEXIST: + try_again = 1; + break; + + /* should not usually happen: */ + case ENOENT: + case ENOTDIR: + case EROFS: + attempts += 1; + continue; + default: + perror("Failed to remove file"); + goto fail; + } + } + } + + archive_read_free(r); + attempts += 1; + } + + if (attempts >= 10000) { + fprintf(stderr, "Failed to remove archive\n"); + free(p); + return -1; + } + + free(p); + return 0; + +fail: + archive_read_free(r); + free(p); + + rte_panic("Failed: %s\n", archive_error_string(r)); + return -1; +} + +#endif /* RTE_APP_TEST_RESOURCE_TAR */ + +void resource_register(struct resource *r) +{ + TAILQ_INSERT_TAIL(&resource_list, r, next); +} diff --git a/app/test/resource.h b/app/test/resource.h new file mode 100644 index 00000000..1e961221 --- /dev/null +++ b/app/test/resource.h @@ -0,0 +1,135 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 RehiveTech. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of RehiveTech nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RESOURCE_H_ +#define _RESOURCE_H_ + +/** + * @file + * + * Test Resource API + * + * Each test can require and use some external resources. Usually, an external + * resource is a file or a filesystem sub-hierarchy. A resource is included + * inside the test executable. + */ + +#include <sys/queue.h> +#include <stdio.h> +#include <stddef.h> + +#include <rte_eal.h> +#include <rte_common.h> + +TAILQ_HEAD(resource_list, resource); +extern struct resource_list resource_list; + +/** + * Representation of a resource. It points to the resource's binary data. + * The semantics of the binary data are defined by the target test. + */ +struct resource { + const char *name; /**< Unique name of the resource */ + const char *begin; /**< Start of resource data */ + const char *end; /**< End of resource data */ + TAILQ_ENTRY(resource) next; +}; + +/** + * @return size of the given resource + */ +size_t resource_size(const struct resource *r); + +/** + * Find a resource by name in the global list of resources. + */ +const struct resource *resource_find(const char *name); + +/** + * Write the raw data of the resource to the given file. + * @return 0 on success + */ +int resource_fwrite(const struct resource *r, FILE *f); + +/** + * Write the raw data of the resource to the given file given by name. + * The name is relative to the current working directory. + * @return 0 on success + */ +int resource_fwrite_file(const struct resource *r, const char *fname); + +/** + * Treat the given resource as a tar archive. Extract + * the archive to the current directory. + */ +int resource_untar(const struct resource *res); + +/** + * Treat the given resource as a tar archive. Remove + * all files (related to the current directory) listed + * in the tar archive. + */ +int resource_rm_by_tar(const struct resource *res); + +/** + * Register a resource in the global list of resources. + * Not intended for direct use, please check the REGISTER_RESOURCE + * macro. + */ +void resource_register(struct resource *r); + +/** + * Definition of a resource linked externally (by means of the used toolchain). + * Only the base name of the resource is expected. The name refers to the + * linked pointers beg_<name> and end_<name> provided externally. + */ +#define REGISTER_LINKED_RESOURCE(n) \ +extern const char beg_ ##n; \ +extern const char end_ ##n; \ +REGISTER_RESOURCE(n, &beg_ ##n, &end_ ##n) \ + +/** + * Definition of a resource described by its name, and pointers begin, end. + */ +#define REGISTER_RESOURCE(n, b, e) \ +static struct resource linkres_ ##n = { \ + .name = RTE_STR(n), \ + .begin = b, \ + .end = e, \ +}; \ +static void __attribute__((constructor, used)) resinitfn_ ##n(void) \ +{ \ + resource_register(&linkres_ ##n); \ +} + +#endif diff --git a/app/test/test.h b/app/test/test.h index a2fba607..81828bee 100644 --- a/app/test/test.h +++ b/app/test/test.h @@ -35,6 +35,7 @@ #define _TEST_H_ #include <stddef.h> #include <sys/queue.h> +#include "rte_log.h" #define TEST_SUCCESS (0) #define TEST_FAILED (-1) @@ -64,7 +65,7 @@ } \ } while (0) - +/* Compare two buffers (length in bytes) */ #define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...) do { \ if (memcmp(a, b, len)) { \ printf("TestCase %s() line %d failed: " \ @@ -74,6 +75,61 @@ } \ } while (0) +/* Compare two buffers with offset (length and offset in bytes) */ +#define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...) do { \ + const uint8_t *_a_with_off = (const uint8_t *)a + off; \ + const uint8_t *_b_with_off = (const uint8_t *)b + off; \ + TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len, msg); \ +} while (0) + +/* Compare two buffers (length in bits) */ +#define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...) do { \ + uint8_t _last_byte_a, _last_byte_b; \ + uint8_t _last_byte_mask, _last_byte_bits; \ + TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg); \ + if (len % 8) { \ + _last_byte_bits = len % 8; \ + _last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \ + _last_byte_a = ((const uint8_t *)a)[len >> 3]; \ + _last_byte_b = ((const uint8_t *)b)[len >> 3]; \ + _last_byte_a &= _last_byte_mask; \ + _last_byte_b &= _last_byte_mask; \ + if (_last_byte_a != _last_byte_b) { \ + printf("TestCase %s() line %d failed: " \ + msg "\n", __func__, __LINE__, ##__VA_ARGS__);\ + TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ + return TEST_FAILED; \ + } \ + } \ +} while (0) + +/* Compare two buffers with offset (length and offset in bits) */ +#define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...) do { \ + uint8_t _first_byte_a, _first_byte_b; \ + uint8_t _first_byte_mask, _first_byte_bits; \ + uint32_t _len_without_first_byte = (off % 8) ? \ + len - (8 - (off % 8)) : \ + len; \ + uint32_t _off_in_bytes = (off % 8) ? (off >> 3) + 1 : (off >> 3); \ + const uint8_t *_a_with_off = (const uint8_t *)a + _off_in_bytes; \ + const uint8_t *_b_with_off = (const uint8_t *)b + _off_in_bytes; \ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off, \ + _len_without_first_byte, msg); \ + if (off % 8) { \ + _first_byte_bits = 8 - (off % 8); \ + _first_byte_mask = (1 << _first_byte_bits) - 1; \ + _first_byte_a = *(_a_with_off - 1); \ + _first_byte_b = *(_b_with_off - 1); \ + _first_byte_a &= _first_byte_mask; \ + _first_byte_b &= _first_byte_mask; \ + if (_first_byte_a != _first_byte_b) { \ + printf("TestCase %s() line %d failed: " \ + msg "\n", __func__, __LINE__, ##__VA_ARGS__); \ + TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__); \ + return TEST_FAILED; \ + } \ + } \ +} while (0) #define TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do { \ if (!(a != b)) { \ @@ -150,6 +206,12 @@ struct unit_test_case { #define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0 } +#if RTE_LOG_LEVEL >= RTE_LOG_DEBUG +#define TEST_HEXDUMP(file, title, buf, len) rte_hexdump(file, title, buf, len) +#else +#define TEST_HEXDUMP(file, title, buf, len) do {} while (0) +#endif + struct unit_test_suite { const char *suite_name; int (*setup)(void); diff --git a/app/test/test_alarm.c b/app/test/test_alarm.c index 5d6f4a27..d83591c9 100644 --- a/app/test/test_alarm.c +++ b/app/test/test_alarm.c @@ -45,8 +45,8 @@ #define US_PER_MS 1000 -#define RTE_TEST_ALARM_TIMEOUT 3000 /* ms */ -#define RTE_TEST_CHECK_PERIOD 1000 /* ms */ +#define RTE_TEST_ALARM_TIMEOUT 10 /* ms */ +#define RTE_TEST_CHECK_PERIOD 3 /* ms */ static volatile int flag; @@ -100,17 +100,17 @@ test_multi_alarms(void) printf("Expect 6 callbacks in order...\n"); /* add two alarms in order */ - rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1); - rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2); + rte_eal_alarm_set(10 * US_PER_MS, test_multi_cb, (void *)1); + rte_eal_alarm_set(20 * US_PER_MS, test_multi_cb, (void *)2); /* now add in reverse order */ - rte_eal_alarm_set(6000 * US_PER_MS, test_multi_cb, (void *)6); - rte_eal_alarm_set(5000 * US_PER_MS, test_multi_cb, (void *)5); - rte_eal_alarm_set(4000 * US_PER_MS, test_multi_cb, (void *)4); - rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3); + rte_eal_alarm_set(60 * US_PER_MS, test_multi_cb, (void *)6); + rte_eal_alarm_set(50 * US_PER_MS, test_multi_cb, (void *)5); + rte_eal_alarm_set(40 * US_PER_MS, test_multi_cb, (void *)4); + rte_eal_alarm_set(30 * US_PER_MS, test_multi_cb, (void *)3); /* wait for expiry */ - rte_delay_ms(6500); + rte_delay_ms(65); if (cb_count.cnt != 6) { printf("Missing callbacks\n"); /* remove any callbacks that might remain */ @@ -121,12 +121,12 @@ test_multi_alarms(void) cb_count.cnt = 0; printf("Expect only callbacks with args 1 and 3...\n"); /* Add 3 flags, then delete one */ - rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3); - rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2); - rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1); + rte_eal_alarm_set(30 * US_PER_MS, test_multi_cb, (void *)3); + rte_eal_alarm_set(20 * US_PER_MS, test_multi_cb, (void *)2); + rte_eal_alarm_set(10 * US_PER_MS, test_multi_cb, (void *)1); rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *)2); - rte_delay_ms(3500); + rte_delay_ms(35); if (cb_count.cnt != 2 || rm_count != 1) { printf("Error: invalid flags count or alarm removal failure" " - flags value = %d, expected = %d\n", @@ -138,9 +138,9 @@ test_multi_alarms(void) printf("Testing adding and then removing multiple alarms\n"); /* finally test that no callbacks are called if we delete them all*/ - rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1); - rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)2); - rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)3); + rte_eal_alarm_set(10 * US_PER_MS, test_multi_cb, (void *)1); + rte_eal_alarm_set(10 * US_PER_MS, test_multi_cb, (void *)2); + rte_eal_alarm_set(10 * US_PER_MS, test_multi_cb, (void *)3); rm_count = rte_eal_alarm_cancel(test_alarm_callback, (void *)-1); if (rm_count != 0) { printf("Error removing non-existant alarm succeeded\n"); @@ -157,19 +157,19 @@ test_multi_alarms(void) * Also test that we can cancel head-of-line callbacks ok.*/ flag = 0; recursive_error = 0; - rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1); - rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback, (void *)2); + rte_eal_alarm_set(10 * US_PER_MS, test_remove_in_callback, (void *)1); + rte_eal_alarm_set(20 * US_PER_MS, test_remove_in_callback, (void *)2); rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)1); if (rm_count != 1) { printf("Error cancelling head-of-list callback\n"); return -1; } - rte_delay_ms(1500); + rte_delay_ms(15); if (flag != 0) { printf("Error, cancelling head-of-list leads to premature callback\n"); return -1; } - rte_delay_ms(1000); + rte_delay_ms(10); if (flag != 2) { printf("Error - expected callback not called\n"); rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1); @@ -181,10 +181,10 @@ test_multi_alarms(void) /* Check if it can cancel all for the same callback */ printf("Testing canceling all for the same callback\n"); flag_2 = 0; - rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1); - rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback_2, (void *)2); - rte_eal_alarm_set(3000 * US_PER_MS, test_remove_in_callback_2, (void *)3); - rte_eal_alarm_set(4000 * US_PER_MS, test_remove_in_callback, (void *)4); + rte_eal_alarm_set(10 * US_PER_MS, test_remove_in_callback, (void *)1); + rte_eal_alarm_set(20 * US_PER_MS, test_remove_in_callback_2, (void *)2); + rte_eal_alarm_set(30 * US_PER_MS, test_remove_in_callback_2, (void *)3); + rte_eal_alarm_set(40 * US_PER_MS, test_remove_in_callback, (void *)4); rm_count = rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1); if (rm_count != 2) { printf("Error, cannot cancel all for the same callback\n"); diff --git a/app/test/test_cmdline_string.c b/app/test/test_cmdline_string.c index 915a7d76..c5bb9c0c 100644 --- a/app/test/test_cmdline_string.c +++ b/app/test/test_cmdline_string.c @@ -35,6 +35,7 @@ #include <string.h> #include <inttypes.h> +#include <rte_common.h> #include <rte_string_fns.h> #include <cmdline_parse.h> @@ -65,9 +66,10 @@ struct string_elt_str string_elt_strs[] = { {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1}, }; -#if CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE +#if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \ +|| (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE) #undef CMDLINE_TEST_BUFSIZE -#define CMDLINE_TEST_BUFSIZE STR_TOKEN_SIZE +#define CMDLINE_TEST_BUFSIZE RTE_MAX(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE) #endif struct string_nb_str { @@ -97,6 +99,11 @@ struct string_parse_str string_parse_strs[] = { {"two with\rgarbage\tcharacters\n", "one#two with\rgarbage\tcharacters\n#three", "two with\rgarbage\tcharacters\n"}, + {"one two", "one", "one"}, /* fixed string */ + {"one two", TOKEN_STRING_MULTI, "one two"}, /* multi string */ + {"one two", NULL, "one"}, /* any string */ + {"one two #three", TOKEN_STRING_MULTI, "one two "}, + /* multi string with comment */ }; @@ -124,7 +131,6 @@ struct string_invalid_str string_invalid_strs[] = { "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!" "toolong!!!" }, - {"invalid", ""}, {"", "invalid"} }; @@ -350,8 +356,7 @@ test_parse_string_valid(void) string_parse_strs[i].str, help_str); return -1; } - if (strncmp(buf, string_parse_strs[i].result, - sizeof(string_parse_strs[i].result) - 1) != 0) { + if (strcmp(buf, string_parse_strs[i].result) != 0) { printf("Error: result mismatch!\n"); return -1; } diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 8e8da988..fbfe1d0d 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -42,6 +42,10 @@ #include "test.h" #include "test_cryptodev.h" + +#include "test_cryptodev_aes.h" +#include "test_cryptodev_kasumi_test_vectors.h" +#include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" #include "test_cryptodev_snow3g_hash_test_vectors.h" #include "test_cryptodev_gcm_test_vectors.h" @@ -109,35 +113,20 @@ setup_test_string(struct rte_mempool *mpool, return m; } -static int -setup_oop_test_mbufs(struct rte_mbuf **ibuf, struct rte_mbuf **obuf, - struct rte_mempool *mpool, const char *string, size_t len, - uint8_t blocksize) { - *ibuf = setup_test_string(mpool, string, len, blocksize); - if (*ibuf == NULL) - return -(EFAULT); - *obuf = setup_test_string(mpool, NULL, len, blocksize); - if (*obuf == NULL) - return -(EFAULT); - return 0; -} - -#if HEX_DUMP -static void -hexdump_mbuf_data(FILE *f, const char *title, struct rte_mbuf *m) +/* Get number of bytes in X bits (rounding up) */ +static uint32_t +ceil_byte_length(uint32_t num_bits) { - rte_hexdump(f, title, rte_pktmbuf_mtod(m, const void *), m->data_len); + if (num_bits % 8) + return ((num_bits >> 3) + 1); + else + return (num_bits >> 3); } -#endif static struct rte_crypto_op * process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) { -#if HEX_DUMP - hexdump_mbuf_data(stdout, "Enqueued Packet", ibuf); -#endif - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { printf("Error sending packet for encryption"); return NULL; @@ -148,11 +137,6 @@ process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) rte_pause(); -#if HEX_DUMP - if (obuf) - hexdump_mbuf_data(stdout, "Dequeued Packet", obuf); -#endif - return op; } @@ -241,6 +225,20 @@ testsuite_setup(void) } } + /* Create 2 KASUMI devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_KASUMI_PMD) { + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_KASUMI_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + TEST_ASSERT_SUCCESS(rte_eal_vdev_init( + CRYPTODEV_NAME_KASUMI_PMD, NULL), + "Failed to create instance %u of" + " pmd : %s", + i, CRYPTODEV_NAME_KASUMI_PMD); + } + } + } + /* Create 2 NULL devices if required */ if (gbl_cryptodev_type == RTE_CRYPTODEV_NULL_PMD) { nb_devs = rte_cryptodev_count_devtype( @@ -318,12 +316,12 @@ testsuite_teardown(void) if (ts_params->mbuf_pool != NULL) { RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", - rte_mempool_count(ts_params->mbuf_pool)); + rte_mempool_avail_count(ts_params->mbuf_pool)); } if (ts_params->op_mpool != NULL) { RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", - rte_mempool_count(ts_params->op_mpool)); + rte_mempool_avail_count(ts_params->op_mpool)); } } @@ -398,10 +396,13 @@ ut_teardown(void) /* * free mbuf - both obuf and ibuf are usually the same, - * but rte copes even if we call free twice + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. */ if (ut_params->obuf) { rte_pktmbuf_free(ut_params->obuf); + if (ut_params->ibuf == ut_params->obuf) + ut_params->ibuf = 0; ut_params->obuf = 0; } if (ut_params->ibuf) { @@ -411,7 +412,7 @@ ut_teardown(void) if (ts_params->mbuf_pool != NULL) RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", - rte_mempool_count(ts_params->mbuf_pool)); + rte_mempool_avail_count(ts_params->mbuf_pool)); rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); @@ -922,661 +923,6 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void) return TEST_SUCCESS; } - -static int -test_AES_CBC_HMAC_SHA1_encrypt_digest_oop(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - - TEST_ASSERT_EQUAL(setup_oop_test_mbufs(&ut_params->ibuf, - &ut_params->obuf, ts_params->mbuf_pool, catch_22_quote, - QUOTE_512_BYTES, 0), 0, - "Allocation of rte_mbuf failed"); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->obuf, - DIGEST_BYTE_LENGTH_SHA1); - - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = &ut_params->auth_xform; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->auth_xform.auth.key.data = hmac_sha1_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], - &ut_params->cipher_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - - - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - sym_op->m_dst = ut_params->obuf; - - sym_op->auth.digest.data = ut_params->digest; - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->obuf, QUOTE_512_BYTES); - - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA1; - sym_op->auth.data.length = QUOTE_512_BYTES; - - /* Set crypto operation cipher parameters */ - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, - "Failed to prepend place for iv input"); - - TEST_ASSERT_NOT_NULL(rte_pktmbuf_prepend(ut_params->obuf, - CIPHER_IV_LENGTH_AES_CBC), - "Failed to prepend place for iv output"); - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - /* Validate obuf */ - uint8_t *ciphertext; - - ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst, - uint8_t *, CIPHER_IV_LENGTH_AES_CBC); - - TEST_ASSERT_BUFFERS_ARE_EQUAL(ciphertext, - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, - "ciphertext data not as expected"); - - uint8_t *digest = ciphertext + QUOTE_512_BYTES; - - TEST_ASSERT_BUFFERS_ARE_EQUAL(digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest, - gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ? - TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 : - DIGEST_BYTE_LENGTH_SHA1, - "Generated digest data not as expected"); - - - return TEST_SUCCESS; -} - - -static int -test_AES_CBC_HMAC_SHA1_decrypt_digest_oop_ver(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and digest */ - - TEST_ASSERT_EQUAL(setup_oop_test_mbufs(&ut_params->ibuf, - &ut_params->obuf, ts_params->mbuf_pool, - (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, 0), 0, - "Allocation of rte_mbuf failed"); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA1); - - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest, - DIGEST_BYTE_LENGTH_SHA1); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = &ut_params->cipher_xform; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->auth_xform.auth.key.data = hmac_sha1_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - sym_op->m_dst = ut_params->obuf; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA1; - - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - - TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, - "Failed to prepend place for iv input"); - - TEST_ASSERT_NOT_NULL(rte_pktmbuf_prepend(ut_params->obuf, - CIPHER_IV_LENGTH_AES_CBC), - "Failed to prepend place for iv output"); - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "Digest verification failed"); - - ut_params->obuf = ut_params->op->sym->m_dst; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, - catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - - return TEST_SUCCESS; -} - - -static int -test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - catch_22_quote, QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA1); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(ut_params->op, 2), - "failed to allocate space for crypto transforms"); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - /* Set crypto operation data parameters */ - sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - - /* cipher parameters */ - sym_op->xform->cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - sym_op->xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - sym_op->xform->cipher.key.data = aes_cbc_key; - sym_op->xform->cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* hash parameters */ - sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; - - sym_op->xform->next->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->xform->next->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - sym_op->xform->next->auth.key.length = HMAC_KEY_LENGTH_SHA1; - sym_op->xform->next->auth.key.data = hmac_sha1_key; - sym_op->xform->next->auth.digest_length = - DIGEST_BYTE_LENGTH_SHA1; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA1; - - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest, - gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ? - TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 : - DIGEST_BYTE_LENGTH_SHA1, - "Generated digest data not as expected"); - - - return TEST_SUCCESS; -} - -static int -test_AES_CBC_HMAC_SHA1_decrypt_digest_verify(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA1); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest, - DIGEST_BYTE_LENGTH_SHA1); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = &ut_params->cipher_xform; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->auth_xform.auth.key.data = hmac_sha1_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA1; - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, - catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "Digest verification failed"); - - - return TEST_SUCCESS; -} - - -/* ***** AES-CBC / HMAC-SHA256 Hash Tests ***** */ - -#define HMAC_KEY_LENGTH_SHA256 (DIGEST_BYTE_LENGTH_SHA256) - -static uint8_t hmac_sha256_key[] = { - 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9a, 0x4f, 0x88, 0x1b, 0xb6, 0x8f, 0xd8, 0x60 }; - -static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA256_digest[] = { - 0xc8, 0x57, 0x57, 0x31, 0x03, 0xe0, 0x03, 0x55, - 0x07, 0xc8, 0x9e, 0x7f, 0x48, 0x9a, 0x61, 0x9a, - 0x68, 0xee, 0x03, 0x0e, 0x71, 0x75, 0xc7, 0xf4, - 0x2e, 0x45, 0x26, 0x32, 0x7c, 0x12, 0x15, 0x15 }; - -static int -test_AES_CBC_HMAC_SHA256_encrypt_digest(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - catch_22_quote, QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA256); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = &ut_params->auth_xform; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256; - ut_params->auth_xform.auth.key.data = hmac_sha256_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], - &ut_params->cipher_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA256; - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA256_digest, - gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ? - TRUNCATED_DIGEST_BYTE_LENGTH_SHA256 : - DIGEST_BYTE_LENGTH_SHA256, - "Generated digest data not as expected"); - - - return TEST_SUCCESS; -} - -static int -test_AES_CBC_HMAC_SHA256_decrypt_digest_verify(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA256); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA256_digest, - DIGEST_BYTE_LENGTH_SHA256); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = &ut_params->cipher_xform; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha256_key; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256; - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - - /* Set crypto operation data parameters */ - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA256; - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, catch_22_quote, - QUOTE_512_BYTES, - "Plaintext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "Digest verification failed"); - - return TEST_SUCCESS; -} - /* ***** AES-CBC / HMAC-SHA512 Hash Tests ***** */ #define HMAC_KEY_LENGTH_SHA512 (DIGEST_BYTE_LENGTH_SHA512) @@ -1601,106 +947,6 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A }; -static int -test_AES_CBC_HMAC_SHA512_encrypt_digest(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - catch_22_quote, QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA512); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = &ut_params->auth_xform; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->cipher_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA512; - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, - CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, - gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ? - TRUNCATED_DIGEST_BYTE_LENGTH_SHA512 : - DIGEST_BYTE_LENGTH_SHA512, - "Generated digest data not as expected"); - - return TEST_SUCCESS; -} static int @@ -1712,25 +958,6 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, struct crypto_testsuite_params *ts_params); -static int -test_AES_CBC_HMAC_SHA512_decrypt_digest_verify(void) -{ - struct crypto_unittest_params *ut_params = &unittest_params; - struct crypto_testsuite_params *ts_params = &testsuite_params; - - TEST_ASSERT(test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - ut_params) == TEST_SUCCESS, - "Failed to create session params"); - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - return test_AES_CBC_HMAC_SHA512_decrypt_perform(ut_params->sess, - ut_params, ts_params); -} static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( @@ -1835,241 +1062,58 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, return TEST_SUCCESS; } -/* ***** AES-CBC / HMAC-AES_XCBC Chain Tests ***** */ - -static uint8_t aes_cbc_hmac_aes_xcbc_key[] = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }; - -static const uint8_t catch_22_quote_2_512_bytes_HMAC_AES_XCBC_digest[] = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }; - static int -test_AES_CBC_HMAC_AES_XCBC_encrypt_digest(void) +test_AES_mb_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - catch_22_quote, QUOTE_512_BYTES, 0); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = &ut_params->auth_xform; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC; - ut_params->auth_xform.auth.key.length = AES_XCBC_MAC_KEY_SZ; - ut_params->auth_xform.auth.key.data = aes_cbc_hmac_aes_xcbc_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_AES_XCBC; - - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], - &ut_params->cipher_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); + int status; - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + status = test_AES_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_AESNI_MB_PMD); - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - - /* Set operation cipher parameters */ - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - sym_op->m_src, CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(sym_op->m_src); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Set operation authentication parameters */ - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - sym_op->m_src, DIGEST_BYTE_LENGTH_AES_XCBC); - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - sym_op->m_src, - CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_AES_XCBC; - - memset(sym_op->auth.digest.data, 0, DIGEST_BYTE_LENGTH_AES_XCBC); - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - - /* Process crypto operation */ - ut_params->op = process_crypto_request(ts_params->valid_devs[0], - ut_params->op); - TEST_ASSERT_NOT_NULL(ut_params->op, "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src, - uint8_t *, CIPHER_IV_LENGTH_AES_CBC), - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod_offset( - ut_params->op->sym->m_src, uint8_t *, - CIPHER_IV_LENGTH_AES_CBC + - QUOTE_512_BYTES), - catch_22_quote_2_512_bytes_HMAC_AES_XCBC_digest, - DIGEST_BYTE_LENGTH_AES_XCBC, - "Generated digest data not as expected"); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); return TEST_SUCCESS; } static int -test_AES_CBC_HMAC_AES_XCBC_decrypt_digest_verify(void) +test_AES_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - - /* Generate test mbuf data and space for digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - (const char *)catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, 0); - - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = NULL; - - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; - - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = &ut_params->cipher_xform; - - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC; - ut_params->auth_xform.auth.key.length = AES_XCBC_MAC_KEY_SZ; - ut_params->auth_xform.auth.key.data = aes_cbc_hmac_aes_xcbc_key; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_AES_XCBC; - - /* Create Crypto session*/ - ut_params->sess = - rte_cryptodev_sym_session_create(ts_params->valid_devs[0], - &ut_params->auth_xform); - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + int status; - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - /* Set crypto operation data parameters */ - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; + status = test_AES_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD); - - sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( - ut_params->ibuf, DIGEST_BYTE_LENGTH_AES_XCBC); - TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, - "no room to append digest"); - - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_AES_XCBC; - - rte_memcpy(sym_op->auth.digest.data, - catch_22_quote_2_512_bytes_HMAC_AES_XCBC_digest, - DIGEST_BYTE_LENGTH_AES_XCBC); - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0], - ut_params->op), "failed to process sym crypto op"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto op processing failed"); - - ut_params->obuf = ut_params->op->sym->m_src; - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + - CIPHER_IV_LENGTH_AES_CBC, catch_22_quote, - QUOTE_512_BYTES, - "Ciphertext data not as expected"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "Digest verification failed"); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); return TEST_SUCCESS; } /* ***** Snow3G Tests ***** */ static int -create_snow3g_hash_session(uint8_t dev_id, +create_snow3g_kasumi_hash_session(uint8_t dev_id, const uint8_t *key, const uint8_t key_len, const uint8_t aad_len, const uint8_t auth_len, - enum rte_crypto_auth_operation op) + enum rte_crypto_auth_operation op, + enum rte_crypto_auth_algorithm algo) { uint8_t hash_key[key_len]; struct crypto_unittest_params *ut_params = &unittest_params; memcpy(hash_key, key, key_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "key:", key, key_len); -#endif + + TEST_HEXDUMP(stdout, "key:", key, key_len); + /* Setup Authentication Parameters */ ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; ut_params->auth_xform.next = NULL; ut_params->auth_xform.auth.op = op; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2; + ut_params->auth_xform.auth.algo = algo; ut_params->auth_xform.auth.key.length = key_len; ut_params->auth_xform.auth.key.data = hash_key; ut_params->auth_xform.auth.digest_length = auth_len; @@ -2079,9 +1123,11 @@ create_snow3g_hash_session(uint8_t dev_id, TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); return 0; } + static int -create_snow3g_cipher_session(uint8_t dev_id, +create_snow3g_kasumi_cipher_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, + enum rte_crypto_cipher_algorithm algo, const uint8_t *key, const uint8_t key_len) { uint8_t cipher_key[key_len]; @@ -2094,14 +1140,13 @@ create_snow3g_cipher_session(uint8_t dev_id, ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; ut_params->cipher_xform.next = NULL; - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2; + ut_params->cipher_xform.cipher.algo = algo; ut_params->cipher_xform.cipher.op = op; ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = key_len; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "key:", key, key_len); -#endif + TEST_HEXDUMP(stdout, "key:", key, key_len); + /* Create Crypto session */ ut_params->sess = rte_cryptodev_sym_session_create(dev_id, &ut_params-> @@ -2111,9 +1156,10 @@ create_snow3g_cipher_session(uint8_t dev_id, } static int -create_snow3g_cipher_operation(const uint8_t *iv, const unsigned iv_len, +create_snow3g_kasumi_cipher_operation(const uint8_t *iv, const unsigned iv_len, const unsigned cipher_len, - const unsigned cipher_offset) + const unsigned cipher_offset, + enum rte_crypto_cipher_algorithm algo) { struct crypto_testsuite_params *ts_params = &testsuite_params; struct crypto_unittest_params *ut_params = &unittest_params; @@ -2134,7 +1180,11 @@ create_snow3g_cipher_operation(const uint8_t *iv, const unsigned iv_len, sym_op->m_src = ut_params->ibuf; /* iv */ - iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); + if (algo == RTE_CRYPTO_CIPHER_KASUMI_F8) + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 8); + else + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf , iv_pad_len); @@ -2151,9 +1201,10 @@ create_snow3g_cipher_operation(const uint8_t *iv, const unsigned iv_len, } static int -create_snow3g_cipher_operation_oop(const uint8_t *iv, const unsigned iv_len, +create_snow3g_kasumi_cipher_operation_oop(const uint8_t *iv, const uint8_t iv_len, const unsigned cipher_len, - const unsigned cipher_offset) + const unsigned cipher_offset, + enum rte_crypto_cipher_algorithm algo) { struct crypto_testsuite_params *ts_params = &testsuite_params; struct crypto_unittest_params *ut_params = &unittest_params; @@ -2175,9 +1226,12 @@ create_snow3g_cipher_operation_oop(const uint8_t *iv, const unsigned iv_len, sym_op->m_dst = ut_params->obuf; /* iv */ - iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf - , iv_pad_len); + if (algo == RTE_CRYPTO_CIPHER_KASUMI_F8) + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 8); + else + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, + iv_pad_len); TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); @@ -2192,11 +1246,14 @@ create_snow3g_cipher_operation_oop(const uint8_t *iv, const unsigned iv_len, } static int -create_snow3g_cipher_auth_session(uint8_t dev_id, +create_snow3g_kasumi_cipher_auth_session(uint8_t dev_id, enum rte_crypto_cipher_operation cipher_op, enum rte_crypto_auth_operation auth_op, + enum rte_crypto_auth_algorithm auth_algo, + enum rte_crypto_cipher_algorithm cipher_algo, const uint8_t *key, const uint8_t key_len, const uint8_t aad_len, const uint8_t auth_len) + { uint8_t cipher_auth_key[key_len]; @@ -2209,7 +1266,7 @@ create_snow3g_cipher_auth_session(uint8_t dev_id, ut_params->auth_xform.next = NULL; ut_params->auth_xform.auth.op = auth_op; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2; + ut_params->auth_xform.auth.algo = auth_algo; ut_params->auth_xform.auth.key.length = key_len; /* Hash key = cipher key */ ut_params->auth_xform.auth.key.data = cipher_auth_key; @@ -2220,14 +1277,13 @@ create_snow3g_cipher_auth_session(uint8_t dev_id, ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; ut_params->cipher_xform.next = &ut_params->auth_xform; - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2; + ut_params->cipher_xform.cipher.algo = cipher_algo; ut_params->cipher_xform.cipher.op = cipher_op; ut_params->cipher_xform.cipher.key.data = cipher_auth_key; ut_params->cipher_xform.cipher.key.length = key_len; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "key:", key, key_len); -#endif + TEST_HEXDUMP(stdout, "key:", key, key_len); + /* Create Crypto session*/ ut_params->sess = rte_cryptodev_sym_session_create(dev_id, &ut_params->cipher_xform); @@ -2237,12 +1293,14 @@ create_snow3g_cipher_auth_session(uint8_t dev_id, } static int -create_snow3g_auth_cipher_session(uint8_t dev_id, +create_snow3g_kasumi_auth_cipher_session(uint8_t dev_id, enum rte_crypto_cipher_operation cipher_op, enum rte_crypto_auth_operation auth_op, + enum rte_crypto_auth_algorithm auth_algo, + enum rte_crypto_cipher_algorithm cipher_algo, const uint8_t *key, const uint8_t key_len, const uint8_t aad_len, const uint8_t auth_len) - { +{ uint8_t auth_cipher_key[key_len]; struct crypto_unittest_params *ut_params = &unittest_params; @@ -2253,7 +1311,7 @@ create_snow3g_auth_cipher_session(uint8_t dev_id, ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; ut_params->auth_xform.auth.op = auth_op; ut_params->auth_xform.next = &ut_params->cipher_xform; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2; + ut_params->auth_xform.auth.algo = auth_algo; ut_params->auth_xform.auth.key.length = key_len; ut_params->auth_xform.auth.key.data = auth_cipher_key; ut_params->auth_xform.auth.digest_length = auth_len; @@ -2262,14 +1320,13 @@ create_snow3g_auth_cipher_session(uint8_t dev_id, /* Setup Cipher Parameters */ ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; ut_params->cipher_xform.next = NULL; - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2; + ut_params->cipher_xform.cipher.algo = cipher_algo; ut_params->cipher_xform.cipher.op = cipher_op; ut_params->cipher_xform.cipher.key.data = auth_cipher_key; ut_params->cipher_xform.cipher.key.length = key_len; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "key:", key, key_len); -#endif + TEST_HEXDUMP(stdout, "key:", key, key_len); + /* Create Crypto session*/ ut_params->sess = rte_cryptodev_sym_session_create(dev_id, &ut_params->auth_xform); @@ -2280,11 +1337,12 @@ create_snow3g_auth_cipher_session(uint8_t dev_id, } static int -create_snow3g_hash_operation(const uint8_t *auth_tag, +create_snow3g_kasumi_hash_operation(const uint8_t *auth_tag, const unsigned auth_tag_len, const uint8_t *aad, const unsigned aad_len, unsigned data_pad_len, enum rte_crypto_auth_operation op, + enum rte_crypto_auth_algorithm algo, const unsigned auth_len, const unsigned auth_offset) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -2313,9 +1371,12 @@ create_snow3g_hash_operation(const uint8_t *auth_tag, * The cryptodev API calls out - * - the array must be big enough to hold the AAD, plus any * space to round this up to the nearest multiple of the - * block size (16 bytes). + * block size (8 bytes for KASUMI and 16 bytes for SNOW3G). */ - aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); + if (algo == RTE_CRYPTO_AUTH_KASUMI_F9) + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 8); + else + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend( ut_params->ibuf, aad_buffer_len); TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, @@ -2327,10 +1388,8 @@ create_snow3g_hash_operation(const uint8_t *auth_tag, memset(sym_op->auth.aad.data, 0, aad_buffer_len); rte_memcpy(sym_op->auth.aad.data, aad, aad_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "aad:", + TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, aad_len); -#endif /* digest */ sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( @@ -2347,11 +1406,9 @@ create_snow3g_hash_operation(const uint8_t *auth_tag, else rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "digest:", + TEST_HEXDUMP(stdout, "digest:", sym_op->auth.digest.data, sym_op->auth.digest.length); -#endif sym_op->auth.data.length = auth_len; sym_op->auth.data.offset = auth_offset; @@ -2360,11 +1417,13 @@ create_snow3g_hash_operation(const uint8_t *auth_tag, } static int -create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, +create_snow3g_kasumi_cipher_hash_operation(const uint8_t *auth_tag, const unsigned auth_tag_len, const uint8_t *aad, const uint8_t aad_len, unsigned data_pad_len, enum rte_crypto_auth_operation op, + enum rte_crypto_auth_algorithm auth_algo, + enum rte_crypto_cipher_algorithm cipher_algo, const uint8_t *iv, const uint8_t iv_len, const unsigned cipher_len, const unsigned cipher_offset, const unsigned auth_len, const unsigned auth_offset) @@ -2390,7 +1449,10 @@ create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, /* iv */ - iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); + if (cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8) + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 8); + else + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( ut_params->ibuf, iv_pad_len); @@ -2411,9 +1473,12 @@ create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, * The cryptodev API calls out - * - the array must be big enough to hold the AAD, plus any * space to round this up to the nearest multiple of the - * block size (16 bytes). + * block size (8 bytes for KASUMI and 16 bytes for SNOW3G). */ - aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); + if (auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9) + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 8); + else + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *); @@ -2426,10 +1491,8 @@ create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, memset(sym_op->auth.aad.data, 0, aad_buffer_len); rte_memcpy(sym_op->auth.aad.data, aad, aad_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "aad:", + TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, aad_len); -#endif /* digest */ sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( @@ -2446,11 +1509,9 @@ create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, else rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); - #ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "digest:", + TEST_HEXDUMP(stdout, "digest:", sym_op->auth.digest.data, sym_op->auth.digest.length); - #endif sym_op->auth.data.length = auth_len; sym_op->auth.data.offset = auth_offset; @@ -2459,12 +1520,14 @@ create_snow3g_cipher_hash_operation(const uint8_t *auth_tag, } static int -create_snow3g_auth_cipher_operation(const unsigned auth_tag_len, +create_snow3g_kasumi_auth_cipher_operation(const unsigned auth_tag_len, const uint8_t *iv, const uint8_t iv_len, const uint8_t *aad, const uint8_t aad_len, unsigned data_pad_len, const unsigned cipher_len, const unsigned cipher_offset, - const unsigned auth_len, const unsigned auth_offset) + const unsigned auth_len, const unsigned auth_offset, + enum rte_crypto_auth_algorithm auth_algo, + enum rte_crypto_cipher_algorithm cipher_algo) { struct crypto_testsuite_params *ts_params = &testsuite_params; struct crypto_unittest_params *ut_params = &unittest_params; @@ -2499,13 +1562,15 @@ create_snow3g_auth_cipher_operation(const unsigned auth_tag_len, memset(sym_op->auth.digest.data, 0, auth_tag_len); - #ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "digest:", + TEST_HEXDUMP(stdout, "digest:", sym_op->auth.digest.data, sym_op->auth.digest.length); - #endif + /* iv */ - iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); + if (cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8) + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 8); + else + iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16); sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( ut_params->ibuf, iv_pad_len); @@ -2523,9 +1588,12 @@ create_snow3g_auth_cipher_operation(const unsigned auth_tag_len, * The cryptodev API calls out - * - the array must be big enough to hold the AAD, plus any * space to round this up to the nearest multiple of the - * block size (16 bytes). + * block size (8 bytes for KASUMI 16 bytes). */ - aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); + if (auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9) + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 8); + else + aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16); sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend( ut_params->ibuf, aad_buffer_len); @@ -2538,10 +1606,8 @@ create_snow3g_auth_cipher_operation(const unsigned auth_tag_len, memset(sym_op->auth.aad.data, 0, aad_buffer_len); rte_memcpy(sym_op->auth.aad.data, aad, aad_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "aad:", + TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data, aad_len); -#endif sym_op->cipher.data.length = cipher_len; sym_op->cipher.data.offset = auth_offset + cipher_offset; @@ -2560,13 +1626,15 @@ test_snow3g_authentication(const struct snow3g_hash_test_data *tdata) int retval; unsigned plaintext_pad_len; + unsigned plaintext_len; uint8_t *plaintext; /* Create SNOW3G session */ - retval = create_snow3g_hash_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_hash_session(ts_params->valid_devs[0], tdata->key.data, tdata->key.len, tdata->aad.len, tdata->digest.len, - RTE_CRYPTO_AUTH_OP_GENERATE); + RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_SNOW3G_UIA2); if (retval < 0) return retval; @@ -2576,17 +1644,19 @@ test_snow3g_authentication(const struct snow3g_hash_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); + plaintext_len = ceil_byte_length(tdata->plaintext.len); /* Append data which is padded to a multiple of */ /* the algorithms block size */ - plaintext_pad_len = tdata->plaintext.len >> 3; + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len >> 3); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); - /* Create SNOW3G opertaion */ - retval = create_snow3g_hash_operation(NULL, tdata->digest.len, + /* Create SNOW3G operation */ + retval = create_snow3g_kasumi_hash_operation(NULL, tdata->digest.len, tdata->aad.data, tdata->aad.len, plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, tdata->validAuthLenInBits.len, tdata->validAuthOffsetLenInBits.len); if (retval < 0) @@ -2617,13 +1687,15 @@ test_snow3g_authentication_verify(const struct snow3g_hash_test_data *tdata) int retval; unsigned plaintext_pad_len; + unsigned plaintext_len; uint8_t *plaintext; /* Create SNOW3G session */ - retval = create_snow3g_hash_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_hash_session(ts_params->valid_devs[0], tdata->key.data, tdata->key.len, tdata->aad.len, tdata->digest.len, - RTE_CRYPTO_AUTH_OP_VERIFY); + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_AUTH_SNOW3G_UIA2); if (retval < 0) return retval; /* alloc mbuf and set payload */ @@ -2632,19 +1704,21 @@ test_snow3g_authentication_verify(const struct snow3g_hash_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); - /* Append data which is padded to a multiple */ - /* of the algorithms block size */ - plaintext_pad_len = tdata->plaintext.len >> 3; + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len >> 3); + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); /* Create SNOW3G operation */ - retval = create_snow3g_hash_operation(tdata->digest.data, + retval = create_snow3g_kasumi_hash_operation(tdata->digest.data, tdata->digest.len, tdata->aad.data, tdata->aad.len, plaintext_pad_len, RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, tdata->validAuthLenInBits.len, tdata->validAuthOffsetLenInBits.len); if (retval < 0) @@ -2666,6 +1740,127 @@ test_snow3g_authentication_verify(const struct snow3g_hash_test_data *tdata) return 0; } +static int +test_kasumi_authentication(const struct kasumi_hash_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + unsigned plaintext_pad_len; + unsigned plaintext_len; + uint8_t *plaintext; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_hash_session(ts_params->valid_devs[0], + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->digest.len, + RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_KASUMI_F9); + if (retval < 0) + return retval; + + /* alloc mbuf and set payload */ + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_hash_operation(NULL, tdata->digest.len, + tdata->aad.data, tdata->aad.len, + plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_KASUMI_F9, + tdata->validAuthLenInBits.len, + tdata->validAuthOffsetLenInBits.len); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + ALIGN_POW2_ROUNDUP(tdata->aad.len, 8); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest.data, + DIGEST_BYTE_LENGTH_KASUMI_F9, + "KASUMI Generated auth tag not as expected"); + + return 0; +} + +static int +test_kasumi_authentication_verify(const struct kasumi_hash_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + unsigned plaintext_pad_len; + unsigned plaintext_len; + uint8_t *plaintext; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_hash_session(ts_params->valid_devs[0], + tdata->key.data, tdata->key.len, + tdata->aad.len, tdata->digest.len, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_AUTH_KASUMI_F9); + if (retval < 0) + return retval; + /* alloc mbuf and set payload */ + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_hash_operation(tdata->digest.data, + tdata->digest.len, + tdata->aad.data, tdata->aad.len, + plaintext_pad_len, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_AUTH_KASUMI_F9, + tdata->validAuthLenInBits.len, + tdata->validAuthOffsetLenInBits.len); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + ut_params->obuf = ut_params->op->sym->m_src; + ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + plaintext_pad_len + tdata->aad.len; + + /* Validate obuf */ + if (ut_params->op->status == RTE_CRYPTO_OP_STATUS_SUCCESS) + return 0; + else + return -1; + + return 0; +} static int test_snow3g_hash_generate_test_case_1(void) @@ -2686,6 +1881,24 @@ test_snow3g_hash_generate_test_case_3(void) } static int +test_snow3g_hash_generate_test_case_4(void) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_4); +} + +static int +test_snow3g_hash_generate_test_case_5(void) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_5); +} + +static int +test_snow3g_hash_generate_test_case_6(void) +{ + return test_snow3g_authentication(&snow3g_hash_test_case_6); +} + +static int test_snow3g_hash_verify_test_case_1(void) { return test_snow3g_authentication_verify(&snow3g_hash_test_case_1); @@ -2705,6 +1918,351 @@ test_snow3g_hash_verify_test_case_3(void) } static int +test_snow3g_hash_verify_test_case_4(void) +{ + return test_snow3g_authentication_verify(&snow3g_hash_test_case_4); +} + +static int +test_snow3g_hash_verify_test_case_5(void) +{ + return test_snow3g_authentication_verify(&snow3g_hash_test_case_5); +} + +static int +test_snow3g_hash_verify_test_case_6(void) +{ + return test_snow3g_authentication_verify(&snow3g_hash_test_case_6); +} + +static int +test_kasumi_hash_generate_test_case_1(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_1); +} + +static int +test_kasumi_hash_generate_test_case_2(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_2); +} + +static int +test_kasumi_hash_generate_test_case_3(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_3); +} + +static int +test_kasumi_hash_generate_test_case_4(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_4); +} + +static int +test_kasumi_hash_generate_test_case_5(void) +{ + return test_kasumi_authentication(&kasumi_hash_test_case_5); +} + +static int +test_kasumi_hash_verify_test_case_1(void) +{ + return test_kasumi_authentication_verify(&kasumi_hash_test_case_1); +} + +static int +test_kasumi_hash_verify_test_case_2(void) +{ + return test_kasumi_authentication_verify(&kasumi_hash_test_case_2); +} + +static int +test_kasumi_hash_verify_test_case_3(void) +{ + return test_kasumi_authentication_verify(&kasumi_hash_test_case_3); +} + +static int +test_kasumi_hash_verify_test_case_4(void) +{ + return test_kasumi_authentication_verify(&kasumi_hash_test_case_4); +} + +static int +test_kasumi_hash_verify_test_case_5(void) +{ + return test_kasumi_authentication_verify(&kasumi_hash_test_case_5); +} + +static int +test_kasumi_encryption(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext, *ciphertext; + unsigned plaintext_pad_len; + unsigned plaintext_len; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_cipher_operation(tdata->iv.data, tdata->iv.len, + tdata->plaintext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_KASUMI_F8); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + + ut_params->obuf = ut_params->op->sym->m_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len; + else + ciphertext = plaintext; + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validCipherLenInBits.len, + "KASUMI Ciphertext data not as expected"); + return 0; +} + +static int +test_kasumi_encryption_oop(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *plaintext, *ciphertext; + unsigned plaintext_pad_len; + unsigned plaintext_len; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 8); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, plaintext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_cipher_operation_oop(tdata->iv.data, + tdata->iv.len, + tdata->plaintext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_KASUMI_F8); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + + ut_params->obuf = ut_params->op->sym->m_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len; + else + ciphertext = plaintext; + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, plaintext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validCipherLenInBits.len, + "KASUMI Ciphertext data not as expected"); + return 0; +} + +static int +test_kasumi_decryption_oop(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *ciphertext, *plaintext; + unsigned ciphertext_pad_len; + unsigned ciphertext_len; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_DECRYPT, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext_len = ceil_byte_length(tdata->ciphertext.len); + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 8); + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_cipher_operation_oop(tdata->iv.data, + tdata->iv.len, + tdata->ciphertext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_KASUMI_F8); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + + ut_params->obuf = ut_params->op->sym->m_dst; + if (ut_params->obuf) + plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len; + else + plaintext = ciphertext; + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, ciphertext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + plaintext, + tdata->plaintext.data, + tdata->validCipherLenInBits.len, + "KASUMI Plaintext data not as expected"); + return 0; +} + +static int +test_kasumi_decryption(const struct kasumi_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + int retval; + uint8_t *ciphertext, *plaintext; + unsigned ciphertext_pad_len; + unsigned ciphertext_len; + + /* Create KASUMI session */ + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_DECRYPT, + RTE_CRYPTO_CIPHER_KASUMI_F8, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext_len = ceil_byte_length(tdata->ciphertext.len); + /* Append data which is padded to a multiple */ + /* of the algorithms block size */ + ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 8); + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, ciphertext_len); + + /* Create KASUMI operation */ + retval = create_snow3g_kasumi_cipher_operation(tdata->iv.data, + tdata->iv.len, + tdata->ciphertext.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_KASUMI_F8); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + + ut_params->obuf = ut_params->op->sym->m_dst; + if (ut_params->obuf) + plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len; + else + plaintext = ciphertext; + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, ciphertext_len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + plaintext, + tdata->plaintext.data, + tdata->validCipherLenInBits.len, + "KASUMI Plaintext data not as expected"); + return 0; +} + +static int test_snow3g_encryption(const struct snow3g_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -2712,13 +2270,13 @@ test_snow3g_encryption(const struct snow3g_test_data *tdata) int retval; uint8_t *plaintext, *ciphertext; - uint8_t plaintext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned plaintext_pad_len; + unsigned plaintext_len; /* Create SNOW3G session */ - retval = create_snow3g_cipher_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len); if (retval < 0) return retval; @@ -2729,24 +2287,21 @@ test_snow3g_encryption(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); - /* - * Append data which is padded to a - * multiple of the algorithms block size - */ - /*tdata->plaintext.len = tdata->plaintext.len >> 3;*/ - plaintext_pad_len = RTE_ALIGN_CEIL((tdata->plaintext.len >> 3), 16); + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); - plaintext = (uint8_t *) rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, (tdata->plaintext.len >> 3)); + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif /* Create SNOW3G operation */ - retval = create_snow3g_cipher_operation(tdata->iv.data, tdata->iv.len, + retval = create_snow3g_kasumi_cipher_operation(tdata->iv.data, tdata->iv.len, tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len); + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2); if (retval < 0) return retval; @@ -2761,20 +2316,13 @@ test_snow3g_encryption(const struct snow3g_test_data *tdata) else ciphertext = plaintext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8 - lastByteValidBits); - (*(ciphertext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ciphertext, tdata->ciphertext.data, - tdata->ciphertext.len >> 3, + tdata->validDataLenInBits.len, "Snow3G Ciphertext data not as expected"); return 0; } @@ -2788,13 +2336,107 @@ test_snow3g_encryption_oop(const struct snow3g_test_data *tdata) uint8_t *plaintext, *ciphertext; int retval; - uint8_t plaintext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned plaintext_pad_len; + unsigned plaintext_len; + + /* Create SNOW3G session */ + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], + RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, + tdata->key.data, tdata->key.len); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + TEST_ASSERT_NOT_NULL(ut_params->obuf, + "Failed to allocate output buffer in mempool"); + + /* Clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + plaintext_pad_len); + rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); + + /* Create SNOW3G operation */ + retval = create_snow3g_kasumi_cipher_operation_oop(tdata->iv.data, + tdata->iv.len, + tdata->validCipherLenInBits.len, + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2); + if (retval < 0) + return retval; + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + + ut_params->obuf = ut_params->op->sym->m_dst; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + tdata->iv.len; + else + ciphertext = plaintext; + + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( + ciphertext, + tdata->ciphertext.data, + tdata->validDataLenInBits.len, + "Snow3G Ciphertext data not as expected"); + return 0; +} + +/* Shift right a buffer by "offset" bits, "offset" < 8 */ +static void +buffer_shift_right(uint8_t *buffer, uint32_t length, uint8_t offset) +{ + uint8_t curr_byte, prev_byte; + uint32_t length_in_bytes = ceil_byte_length(length + offset); + uint8_t lower_byte_mask = (1 << offset) - 1; + unsigned i; + + prev_byte = buffer[0]; + buffer[0] >>= offset; + + for (i = 1; i < length_in_bytes; i++) { + curr_byte = buffer[i]; + buffer[i] = ((prev_byte & lower_byte_mask) << (8 - offset)) | + (curr_byte >> offset); + prev_byte = curr_byte; + } +} + +static int +test_snow3g_encryption_offset_oop(const struct snow3g_test_data *tdata) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + uint8_t *plaintext, *ciphertext; + int retval; + uint32_t plaintext_len; + uint32_t plaintext_pad_len; + uint8_t extra_offset = 4; + uint8_t *expected_ciphertext_shifted; /* Create SNOW3G session */ - retval = create_snow3g_cipher_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_ENCRYPT, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len); if (retval < 0) return retval; @@ -2811,29 +2453,31 @@ test_snow3g_encryption_oop(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); + plaintext_len = ceil_byte_length(tdata->plaintext.len + extra_offset); /* * Append data which is padded to a * multiple of the algorithms block size */ - /*tdata->plaintext.len = tdata->plaintext.len >> 3;*/ - plaintext_pad_len = RTE_ALIGN_CEIL((tdata->plaintext.len >> 3), 16); + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); plaintext = (uint8_t *) rte_pktmbuf_append(ut_params->ibuf, plaintext_pad_len); - rte_pktmbuf_append(ut_params->obuf, - plaintext_pad_len); + rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len); memcpy(plaintext, tdata->plaintext.data, (tdata->plaintext.len >> 3)); + buffer_shift_right(plaintext, tdata->plaintext.len, extra_offset); #ifdef RTE_APP_TEST_DEBUG rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); #endif /* Create SNOW3G operation */ - retval = create_snow3g_cipher_operation_oop(tdata->iv.data, + retval = create_snow3g_kasumi_cipher_operation_oop(tdata->iv.data, tdata->iv.len, tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len); + tdata->validCipherOffsetLenInBits.len + + extra_offset, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2); if (retval < 0) return retval; @@ -2848,25 +2492,30 @@ test_snow3g_encryption_oop(const struct snow3g_test_data *tdata) else ciphertext = plaintext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8 - lastByteValidBits); - (*(ciphertext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; - #ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + rte_hexdump(stdout, "ciphertext:", ciphertext, plaintext_len); #endif + + expected_ciphertext_shifted = rte_malloc(NULL, + ceil_byte_length(plaintext_len + extra_offset), 0); + + TEST_ASSERT_NOT_NULL(expected_ciphertext_shifted, + "failed to reserve memory for ciphertext shifted\n"); + + memcpy(expected_ciphertext_shifted, tdata->ciphertext.data, + ceil_byte_length(tdata->ciphertext.len)); + buffer_shift_right(expected_ciphertext_shifted, tdata->ciphertext.len, + extra_offset); /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET( ciphertext, - tdata->ciphertext.data, - tdata->ciphertext.len >> 3, + expected_ciphertext_shifted, + tdata->validDataLenInBits.len, + extra_offset, "Snow3G Ciphertext data not as expected"); return 0; } - static int test_snow3g_decryption(const struct snow3g_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -2875,13 +2524,13 @@ static int test_snow3g_decryption(const struct snow3g_test_data *tdata) int retval; uint8_t *plaintext, *ciphertext; - uint8_t ciphertext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned ciphertext_pad_len; + unsigned ciphertext_len; /* Create SNOW3G session */ - retval = create_snow3g_cipher_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_DECRYPT, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len); if (retval < 0) return retval; @@ -2892,48 +2541,40 @@ static int test_snow3g_decryption(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); - /* - * Append data which is padded to a - * multiple of the algorithms block size - */ - ciphertext_pad_len = RTE_ALIGN_CEIL((tdata->ciphertext.len >> 3), 16); + ciphertext_len = ceil_byte_length(tdata->ciphertext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 16); + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); - ciphertext = (uint8_t *) rte_pktmbuf_append(ut_params->ibuf, - ciphertext_pad_len); - memcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len >> 3); + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif /* Create SNOW3G operation */ - retval = create_snow3g_cipher_operation(tdata->iv.data, tdata->iv.len, + retval = create_snow3g_kasumi_cipher_operation(tdata->iv.data, tdata->iv.len, tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len); + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2); if (retval < 0) return retval; ut_params->op = process_crypto_request(ts_params->valid_devs[0], ut_params->op); TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); - ut_params->obuf = ut_params->op->sym->m_src; + ut_params->obuf = ut_params->op->sym->m_dst; if (ut_params->obuf) plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + tdata->iv.len; else plaintext = ciphertext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8 - lastByteValidBits); - (*(ciphertext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); + /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(plaintext, + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(plaintext, tdata->plaintext.data, - tdata->plaintext.len >> 3, + tdata->validDataLenInBits.len, "Snow3G Plaintext data not as expected"); return 0; } @@ -2946,13 +2587,13 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata) int retval; uint8_t *plaintext, *ciphertext; - uint8_t ciphertext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned ciphertext_pad_len; + unsigned ciphertext_len; /* Create SNOW3G session */ - retval = create_snow3g_cipher_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_cipher_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_DECRYPT, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len); if (retval < 0) return retval; @@ -2972,28 +2613,23 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->obuf)); - /* - * Append data which is padded to a - * multiple of the algorithms block size - */ - ciphertext_pad_len = RTE_ALIGN_CEIL((tdata->ciphertext.len >> 3), 16); - - ciphertext = (uint8_t *) rte_pktmbuf_append(ut_params->ibuf, - ciphertext_pad_len); - - rte_pktmbuf_append(ut_params->obuf, - ciphertext_pad_len); + ciphertext_len = ceil_byte_length(tdata->ciphertext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 16); + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); - memcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len >> 3); + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif /* Create SNOW3G operation */ - retval = create_snow3g_cipher_operation_oop(tdata->iv.data, + retval = create_snow3g_kasumi_cipher_operation_oop(tdata->iv.data, tdata->iv.len, tdata->validCipherLenInBits.len, - tdata->validCipherOffsetLenInBits.len); + tdata->validCipherOffsetLenInBits.len, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2); if (retval < 0) return retval; @@ -3006,19 +2642,13 @@ static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata) + tdata->iv.len; else plaintext = ciphertext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8 - lastByteValidBits); - (*(plaintext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); + /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL(plaintext, + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(plaintext, tdata->plaintext.data, - tdata->plaintext.len >> 3, + tdata->validDataLenInBits.len, "Snow3G Plaintext data not as expected"); return 0; } @@ -3032,14 +2662,15 @@ test_snow3g_authenticated_encryption(const struct snow3g_test_data *tdata) int retval; uint8_t *plaintext, *ciphertext; - uint8_t plaintext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned plaintext_pad_len; + unsigned plaintext_len; /* Create SNOW3G session */ - retval = create_snow3g_cipher_auth_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_cipher_auth_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_ENCRYPT, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len, tdata->aad.len, tdata->digest.len); if (retval < 0) @@ -3050,28 +2681,29 @@ test_snow3g_authenticated_encryption(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); - /* Append data which is padded to a multiple */ - /* of the algorithms block size */ - plaintext_pad_len = tdata->plaintext.len >> 3; - + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len >> 3); + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); /* Create SNOW3G operation */ - retval = create_snow3g_cipher_hash_operation(tdata->digest.data, + retval = create_snow3g_kasumi_cipher_hash_operation(tdata->digest.data, tdata->digest.len, tdata->aad.data, tdata->aad.len, /*tdata->plaintext.len,*/ plaintext_pad_len, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->iv.data, tdata->iv.len, tdata->validCipherLenInBits.len, tdata->validCipherOffsetLenInBits.len, tdata->validAuthLenInBits.len, - tdata->validAuthOffsetLenInBits.len); + tdata->validAuthOffsetLenInBits.len + ); if (retval < 0) return retval; @@ -3084,20 +2716,14 @@ test_snow3g_authenticated_encryption(const struct snow3g_test_data *tdata) + tdata->iv.len; else ciphertext = plaintext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8-lastByteValidBits); - (*(ciphertext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ciphertext, tdata->ciphertext.data, - tdata->ciphertext.len >> 3, + tdata->validDataLenInBits.len, "Snow3G Ciphertext data not as expected"); ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) @@ -3120,14 +2746,15 @@ test_snow3g_encrypted_authentication(const struct snow3g_test_data *tdata) int retval; uint8_t *plaintext, *ciphertext; - uint8_t plaintext_pad_len; - uint8_t lastByteValidBits = 8; - uint8_t lastByteMask = 0xFF; + unsigned plaintext_pad_len; + unsigned plaintext_len; /* Create SNOW3G session */ - retval = create_snow3g_auth_cipher_session(ts_params->valid_devs[0], + retval = create_snow3g_kasumi_auth_cipher_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_ENCRYPT, RTE_CRYPTO_AUTH_OP_GENERATE, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2, tdata->key.data, tdata->key.len, tdata->aad.len, tdata->digest.len); if (retval < 0) @@ -3139,20 +2766,18 @@ test_snow3g_encrypted_authentication(const struct snow3g_test_data *tdata) memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, rte_pktmbuf_tailroom(ut_params->ibuf)); - /* Append data which is padded to a multiple */ - /* of the algorithms block size */ - plaintext_pad_len = RTE_ALIGN_CEIL((tdata->plaintext.len >> 3), 8); - + plaintext_len = ceil_byte_length(tdata->plaintext.len); + /* Append data which is padded to a multiple of */ + /* the algorithms block size */ + plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - plaintext_pad_len); - memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len >> 3); + plaintext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); /* Create SNOW3G operation */ - retval = create_snow3g_auth_cipher_operation( + retval = create_snow3g_kasumi_auth_cipher_operation( tdata->digest.len, tdata->iv.data, tdata->iv.len, tdata->aad.data, tdata->aad.len, @@ -3160,7 +2785,9 @@ test_snow3g_encrypted_authentication(const struct snow3g_test_data *tdata) tdata->validCipherLenInBits.len, tdata->validCipherOffsetLenInBits.len, tdata->validAuthLenInBits.len, - tdata->validAuthOffsetLenInBits.len + tdata->validAuthOffsetLenInBits.len, + RTE_CRYPTO_AUTH_SNOW3G_UIA2, + RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ); if (retval < 0) @@ -3176,21 +2803,15 @@ test_snow3g_encrypted_authentication(const struct snow3g_test_data *tdata) else ciphertext = plaintext; - lastByteValidBits = (tdata->validDataLenInBits.len % 8); - if (lastByteValidBits == 0) - lastByteValidBits = 8; - lastByteMask = lastByteMask << (8-lastByteValidBits); - (*(ciphertext + (tdata->ciphertext.len >> 3) - 1)) &= lastByteMask; ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + plaintext_pad_len + tdata->aad.len + tdata->iv.len; - #ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( + TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ciphertext, tdata->ciphertext.data, - tdata->ciphertext.len >> 3, + tdata->validDataLenInBits.len, "Snow3G Ciphertext data not as expected"); /* Validate obuf */ @@ -3203,6 +2824,77 @@ test_snow3g_encrypted_authentication(const struct snow3g_test_data *tdata) } static int +test_kasumi_encryption_test_case_1(void) +{ + return test_kasumi_encryption(&kasumi_test_case_1); +} + +static int +test_kasumi_encryption_test_case_1_oop(void) +{ + return test_kasumi_encryption_oop(&kasumi_test_case_1); +} + +static int +test_kasumi_encryption_test_case_2(void) +{ + return test_kasumi_encryption(&kasumi_test_case_2); +} + +static int +test_kasumi_encryption_test_case_3(void) +{ + return test_kasumi_encryption(&kasumi_test_case_3); +} + +static int +test_kasumi_encryption_test_case_4(void) +{ + return test_kasumi_encryption(&kasumi_test_case_4); +} + +static int +test_kasumi_encryption_test_case_5(void) +{ + return test_kasumi_encryption(&kasumi_test_case_5); +} + +static int +test_kasumi_decryption_test_case_1(void) +{ + return test_kasumi_decryption(&kasumi_test_case_1); +} + +static int +test_kasumi_decryption_test_case_1_oop(void) +{ + return test_kasumi_decryption_oop(&kasumi_test_case_1); +} + +static int +test_kasumi_decryption_test_case_2(void) +{ + return test_kasumi_decryption(&kasumi_test_case_2); +} + +static int +test_kasumi_decryption_test_case_3(void) +{ + return test_kasumi_decryption(&kasumi_test_case_3); +} + +static int +test_kasumi_decryption_test_case_4(void) +{ + return test_kasumi_decryption(&kasumi_test_case_4); +} + +static int +test_kasumi_decryption_test_case_5(void) +{ + return test_kasumi_decryption(&kasumi_test_case_5); +} +static int test_snow3g_encryption_test_case_1(void) { return test_snow3g_encryption(&snow3g_test_case_1); @@ -3215,6 +2907,12 @@ test_snow3g_encryption_test_case_1_oop(void) } static int +test_snow3g_encryption_test_case_1_offset_oop(void) +{ + return test_snow3g_encryption_offset_oop(&snow3g_test_case_1); +} + +static int test_snow3g_encryption_test_case_2(void) { return test_snow3g_encryption(&snow3g_test_case_2); @@ -3308,9 +3006,8 @@ create_gcm_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = key_len; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "key:", key, key_len); -#endif + TEST_HEXDUMP(stdout, "key:", key, key_len); + /* Setup Authentication Parameters */ ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; ut_params->auth_xform.next = NULL; @@ -3371,11 +3068,9 @@ create_gcm_operation(enum rte_crypto_cipher_operation op, if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "digest:", - ut_params->op->digest.data, - ut_params->op->digest.length); -#endif + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); } /* iv */ @@ -3415,11 +3110,10 @@ create_gcm_operation(enum rte_crypto_cipher_operation op, memset(sym_op->auth.aad.data, 0, aad_buffer_len); rte_memcpy(sym_op->auth.aad.data, aad, aad_len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "iv:", ut_params->op->iv.data, iv_pad_len); - rte_hexdump(stdout, "aad:", - ut_params->op->additional_auth.data, aad_len); -#endif + TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len); + TEST_HEXDUMP(stdout, "aad:", + sym_op->auth.aad.data, aad_len); + sym_op->cipher.data.length = data_len; sym_op->cipher.data.offset = aad_buffer_len + iv_pad_len; @@ -3465,9 +3159,8 @@ test_mb_AES_GCM_authenticated_encryption(const struct gcm_test_data *tdata) plaintext_pad_len); memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->plaintext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len); + /* Create GCM opertaion */ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata->auth_tag.data, tdata->auth_tag.len, @@ -3498,10 +3191,9 @@ test_mb_AES_GCM_authenticated_encryption(const struct gcm_test_data *tdata) auth_tag = plaintext + plaintext_pad_len; } -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); - rte_hexdump(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); -#endif + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->auth_tag.len); + /* Validate obuf */ TEST_ASSERT_BUFFERS_ARE_EQUAL( ciphertext, @@ -3593,9 +3285,8 @@ test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata) ciphertext_pad_len); memcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len); -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); -#endif + TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len); + /* Create GCM opertaion */ retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata->auth_tag.data, tdata->auth_tag.len, @@ -3623,9 +3314,8 @@ test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata) else plaintext = ciphertext; -#ifdef RTE_APP_TEST_DEBUG - rte_hexdump(stdout, "plaintext:", plaintext, tdata->ciphertext.len); -#endif + TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len); + /* Validate obuf */ TEST_ASSERT_BUFFERS_ARE_EQUAL( plaintext, @@ -3781,12 +3471,19 @@ test_multi_session(void) /* * free mbuf - both obuf and ibuf are usually the same, - * but rte copes even if we call free twice + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. */ if (ut_params->obuf) { rte_pktmbuf_free(ut_params->obuf); + if (ut_params->ibuf == ut_params->obuf) + ut_params->ibuf = 0; ut_params->obuf = 0; } + if (ut_params->ibuf) { + rte_pktmbuf_free(ut_params->ibuf); + ut_params->ibuf = 0; + } } /* Next session create should fail */ @@ -3805,92 +3502,6 @@ test_multi_session(void) } static int -test_not_in_place_crypto(void) -{ - struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct rte_mbuf *dst_m = rte_pktmbuf_alloc(ts_params->mbuf_pool); - - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); - - /* Create multiple crypto sessions*/ - - ut_params->sess = rte_cryptodev_sym_session_create( - ts_params->valid_devs[0], &ut_params->auth_xform); - - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); - - - /* Generate test mbuf data and digest */ - ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, - (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, - QUOTE_512_BYTES, 0); - - ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, - DIGEST_BYTE_LENGTH_SHA512); - TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); - - rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, - DIGEST_BYTE_LENGTH_SHA512); - - /* Generate Crypto op data structure */ - ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); - TEST_ASSERT_NOT_NULL(ut_params->op, - "Failed to allocate symmetric crypto operation struct"); - - - /* Set crypto operation data parameters */ - rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); - - struct rte_crypto_sym_op *sym_op = ut_params->op->sym; - - /* set crypto operation source mbuf */ - sym_op->m_src = ut_params->ibuf; - sym_op->m_dst = dst_m; - - sym_op->auth.digest.data = ut_params->digest; - sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, QUOTE_512_BYTES); - sym_op->auth.digest.length = DIGEST_BYTE_LENGTH_SHA512; - - sym_op->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->auth.data.length = QUOTE_512_BYTES; - - - sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( - ut_params->ibuf, CIPHER_IV_LENGTH_AES_CBC); - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys_offset( - ut_params->ibuf, 0); - sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); - - sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - sym_op->cipher.data.length = QUOTE_512_BYTES; - - /* Process crypto operation */ - ut_params->op = process_crypto_request(ts_params->valid_devs[0], - ut_params->op); - TEST_ASSERT_NOT_NULL(ut_params->op, "no crypto operation returned"); - - TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, - "crypto operation processing failed"); - - /* Validate obuf */ - TEST_ASSERT_BUFFERS_ARE_EQUAL( - rte_pktmbuf_mtod(ut_params->op->sym->m_dst, char *), - catch_22_quote, - QUOTE_512_BYTES, - "Plaintext data not as expected"); - - return TEST_SUCCESS; -} - -static int test_null_cipher_only_operation(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -4260,30 +3871,7 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_encrypt_digest_oop), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_decrypt_digest_oop_ver), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA256_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA256_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA512_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA512_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_AES_XCBC_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_AES_XCBC_decrypt_digest_verify), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), TEST_CASE_ST(ut_setup, ut_teardown, test_stats), /** AES GCM Authenticated Encryption */ @@ -4371,31 +3959,7 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA256_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA256_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA512_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA512_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_AES_XCBC_encrypt_digest), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_AES_XCBC_decrypt_digest_verify), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless), - - TEST_CASE_ST(ut_setup, ut_teardown, - test_not_in_place_crypto), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), TEST_CASES_END() /**< NULL terminate unit test array */ } @@ -4442,6 +4006,64 @@ static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { } }; +static struct unit_test_suite cryptodev_sw_kasumi_testsuite = { + .suite_name = "Crypto Device SW KASUMI Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + /** KASUMI encrypt only (UEA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_5), + /** KASUMI decrypt only (UEA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_5), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_encryption_test_case_1_oop), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_decryption_test_case_1_oop), + + /** KASUMI hash only (UIA1) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_generate_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_verify_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_kasumi_hash_verify_test_case_5), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; static struct unit_test_suite cryptodev_sw_snow3g_testsuite = { .suite_name = "Crypto Device SW Snow3G Unit Test Suite", .setup = testsuite_setup, @@ -4459,6 +4081,13 @@ static struct unit_test_suite cryptodev_sw_snow3g_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1_oop), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_1_oop), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1_offset_oop), /** Snow3G decrypt only (UEA2) */ TEST_CASE_ST(ut_setup, ut_teardown, @@ -4477,12 +4106,26 @@ static struct unit_test_suite cryptodev_sw_snow3g_testsuite = { test_snow3g_hash_generate_test_case_2), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_hash_generate_test_case_3), + /* Tests with buffers which length is not byte-aligned */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_generate_test_case_6), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_hash_verify_test_case_1), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_hash_verify_test_case_2), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_hash_verify_test_case_3), + /* Tests with buffers which length is not byte-aligned */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_verify_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_verify_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_hash_verify_test_case_6), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_authenticated_encryption_test_case_1), TEST_CASE_ST(ut_setup, ut_teardown, @@ -4577,8 +4220,22 @@ static struct test_command cryptodev_sw_snow3g_cmd = { .callback = test_cryptodev_sw_snow3g, }; +static int +test_cryptodev_sw_kasumi(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_KASUMI_PMD; + + return unit_test_suite_runner(&cryptodev_sw_kasumi_testsuite); +} + +static struct test_command cryptodev_sw_kasumi_cmd = { + .command = "cryptodev_sw_kasumi_autotest", + .callback = test_cryptodev_sw_kasumi, +}; + REGISTER_TEST_COMMAND(cryptodev_qat_cmd); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_cmd); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_cmd); REGISTER_TEST_COMMAND(cryptodev_null_cmd); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_cmd); +REGISTER_TEST_COMMAND(cryptodev_sw_kasumi_cmd); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 6059a01c..3c37c323 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -46,7 +46,7 @@ #define DEFAULT_BURST_SIZE (64) #define DEFAULT_NUM_XFORMS (2) #define NUM_MBUFS (8191) -#define MBUF_CACHE_SIZE (250) +#define MBUF_CACHE_SIZE (256) #define MBUF_DATAPAYLOAD_SIZE (2048 + DIGEST_BYTE_LENGTH_SHA512) #define MBUF_SIZE (sizeof(struct rte_mbuf) + \ RTE_PKTMBUF_HEADROOM + MBUF_DATAPAYLOAD_SIZE) @@ -61,10 +61,13 @@ #define DIGEST_BYTE_LENGTH_SHA512 (BYTE_LENGTH(512)) #define DIGEST_BYTE_LENGTH_AES_XCBC (BYTE_LENGTH(96)) #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) +#define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) +#define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA256 (16) +#define TRUNCATED_DIGEST_BYTE_LENGTH_SHA384 (24) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA512 (32) #endif /* TEST_CRYPTODEV_H_ */ diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c new file mode 100644 index 00000000..bf832b62 --- /dev/null +++ b/app/test/test_cryptodev_aes.c @@ -0,0 +1,683 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-2016 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <rte_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_aes.h" + +#ifndef AES_TEST_MSG_LEN +#define AES_TEST_MSG_LEN 256 +#endif + +#define AES_TEST_OP_ENCRYPT 0x01 +#define AES_TEST_OP_DECRYPT 0x02 +#define AES_TEST_OP_AUTH_GEN 0x04 +#define AES_TEST_OP_AUTH_VERIFY 0x08 + +#define AES_TEST_FEATURE_OOP 0x01 +#define AES_TEST_FEATURE_SESSIONLESS 0x02 +#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ + +#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ + AES_TEST_OP_DECRYPT) + +#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ + AES_TEST_OP_AUTH_VERIFY) + +#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ + AES_TEST_OP_AUTH_GEN) + +#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ + AES_TEST_OP_AUTH_VERIFY) + +struct aes_test_case { + const char *test_descr; /* test description */ + const struct aes_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +static const struct aes_test_case aes_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .feature_mask = AES_TEST_FEATURE_SESSIONLESS, + .pmd_mask = AES_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB | + AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .feature_mask = AES_TEST_FEATURE_OOP, + .pmd_mask = AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = AES_TEST_FEATURE_OOP, + .pmd_mask = AES_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = AES_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = AES_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = AES_TEST_TARGET_PMD_MB + }, +}; + +static int +test_AES_one_case(const struct aes_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct aes_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & AES_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & AES_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & AES_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed */ + if (t->op_mask & AES_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & AES_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & AES_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used */ + if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & AES_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & AES_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() + * call */ + if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || + (t->op_mask == AES_TEST_OP_DECRYPT)) { + if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || + (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & AES_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & AES_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & AES_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & AES_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & AES_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & AES_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & AES_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & AES_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & AES_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & AES_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_AES_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[AES_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = sizeof(aes_test_cases) / + sizeof(aes_test_cases[0]); + uint32_t target_pmd_mask = 0; + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = AES_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = AES_TEST_TARGET_PMD_QAT; + break; + default: + TEST_ASSERT(-1, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct aes_test_case *tc = &aes_test_cases[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_AES_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h new file mode 100644 index 00000000..ef518e0a --- /dev/null +++ b/app/test/test_cryptodev_aes.h @@ -0,0 +1,1124 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_CRYPTODEV_AES_H_ +#define TEST_CRYPTODEV_AES_H_ + +struct aes_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned len; + } iv; + + struct { + uint8_t data[2048]; + unsigned len; + } plaintext; + + struct { + uint8_t data[2048]; + unsigned len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned len; /* for qat */ + unsigned truncated_len; /* for mb */ + } digest; +}; + +int +test_AES_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type); + +/* test vectors */ +/* AES128-CTR-SHA1 test vector */ +static const struct aes_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 + }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE + }, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct aes_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, + }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 + }, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct aes_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 + }, + .len = 64 + }, + .ciphertext = { + .data = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 + }, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct aes_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct aes_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct aes_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct aes_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct aes_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct aes_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C + }, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_kasumi_hash_test_vectors.h b/app/test/test_cryptodev_kasumi_hash_test_vectors.h new file mode 100644 index 00000000..c080b9f5 --- /dev/null +++ b/app/test/test_cryptodev_kasumi_hash_test_vectors.h @@ -0,0 +1,260 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_CRYPTODEV_KASUMI_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_KASUMI_HASH_TEST_VECTORS_H_ + +struct kasumi_hash_test_data { + struct { + uint8_t data[16]; + unsigned len; + } key; + + /* Includes: COUNT (4 bytes) and FRESH (4 bytes) */ + struct { + uint8_t data[8]; + unsigned len; + } aad; + + /* Includes message and DIRECTION (1 bit), plus 1 0*, + * with enough 0s, so total length is multiple of 64 bits */ + struct { + uint8_t data[2056]; + unsigned len; /* length must be in Bits */ + } plaintext; + + /* Actual length of data to be hashed */ + struct { + unsigned len; + } validAuthLenInBits; + + struct { + unsigned len; + } validAuthOffsetLenInBits; + + struct { + uint8_t data[64]; + unsigned len; + } digest; +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_1 = { + .key = { + .data = { + 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, + 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 + }, + .len = 16 + }, + .aad = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x6B, 0x22, 0x77, 0x37, 0x29, 0x6F, 0x39, 0x3C, + 0x80, 0x79, 0x35, 0x3E, 0xDC, 0x87, 0xE2, 0xE8, + 0x05, 0xD2, 0xEC, 0x49, 0xA4, 0xF2, 0xD8, 0xE2 + }, + .len = 192 + }, + .validAuthLenInBits = { + .len = 189 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0xF6, 0x3B, 0xD7, 0x2C}, + .len = 4 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_2 = { + .key = { + .data = { + 0xD4, 0x2F, 0x68, 0x24, 0x28, 0x20, 0x1C, 0xAF, + 0xCD, 0x9F, 0x97, 0x94, 0x5E, 0x6D, 0xE7, 0xB7 + }, + .len = 16 + }, + .aad = { + .data = { + 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xB5, 0x92, 0x43, 0x84, 0x32, 0x8A, 0x4A, 0xE0, + 0x0B, 0x73, 0x71, 0x09, 0xF8, 0xB6, 0xC8, 0xDD, + 0x2B, 0x4D, 0xB6, 0x3D, 0xD5, 0x33, 0x98, 0x1C, + 0xEB, 0x19, 0xAA, 0xD5, 0x2A, 0x5B, 0x2B, 0xC3 + }, + .len = 256 + }, + .validAuthLenInBits = { + .len = 254 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0xA9, 0xDA, 0xF1, 0xFF}, + .len = 4 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_3 = { + .key = { + .data = { + 0xFD, 0xB9, 0xCF, 0xDF, 0x28, 0x93, 0x6C, 0xC4, + 0x83, 0xA3, 0x18, 0x69, 0xD8, 0x1B, 0x8F, 0xAB + }, + .len = 16 + }, + .aad = { + .data = { + 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x59, 0x32, 0xBC, 0x0A, 0xCE, 0x2B, 0x0A, 0xBA, + 0x33, 0xD8, 0xAC, 0x18, 0x8A, 0xC5, 0x4F, 0x34, + 0x6F, 0xAD, 0x10, 0xBF, 0x9D, 0xEE, 0x29, 0x20, + 0xB4, 0x3B, 0xD0, 0xC5, 0x3A, 0x91, 0x5C, 0xB7, + 0xDF, 0x6C, 0xAA, 0x72, 0x05, 0x3A, 0xBF, 0xF3, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + .len = 384 + }, + .validAuthLenInBits = { + .len = 319 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0x15, 0x37, 0xD3, 0x16}, + .len = 4 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_4 = { + .key = { + .data = { + 0xC7, 0x36, 0xC6, 0xAA, 0xB2, 0x2B, 0xFF, 0xF9, + 0x1E, 0x26, 0x98, 0xD2, 0xE2, 0x2A, 0xD5, 0x7E + }, + .len = 16 + }, + .aad = { + .data = { + 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xD0, 0xA7, 0xD4, 0x63, 0xDF, 0x9F, 0xB2, 0xB2, + 0x78, 0x83, 0x3F, 0xA0, 0x2E, 0x23, 0x5A, 0xA1, + 0x72, 0xBD, 0x97, 0x0C, 0x14, 0x73, 0xE1, 0x29, + 0x07, 0xFB, 0x64, 0x8B, 0x65, 0x99, 0xAA, 0xA0, + 0xB2, 0x4A, 0x03, 0x86, 0x65, 0x42, 0x2B, 0x20, + 0xA4, 0x99, 0x27, 0x6A, 0x50, 0x42, 0x70, 0x09, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + .len = 448 + }, + .validAuthLenInBits = { + .len = 384 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0xDD, 0x7D, 0xFA, 0xDD }, + .len = 4 + } +}; + +struct kasumi_hash_test_data kasumi_hash_test_case_5 = { + .key = { + .data = { + 0xF4, 0xEB, 0xEC, 0x69, 0xE7, 0x3E, 0xAF, 0x2E, + 0xB2, 0xCF, 0x6A, 0xF4, 0xB3, 0x12, 0x0F, 0xFD + }, + .len = 16 + }, + .aad = { + .data = { + 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x10, 0xBF, 0xFF, 0x83, 0x9E, 0x0C, 0x71, 0x65, + 0x8D, 0xBB, 0x2D, 0x17, 0x07, 0xE1, 0x45, 0x72, + 0x4F, 0x41, 0xC1, 0x6F, 0x48, 0xBF, 0x40, 0x3C, + 0x3B, 0x18, 0xE3, 0x8F, 0xD5, 0xD1, 0x66, 0x3B, + 0x6F, 0x6D, 0x90, 0x01, 0x93, 0xE3, 0xCE, 0xA8, + 0xBB, 0x4F, 0x1B, 0x4F, 0x5B, 0xE8, 0x22, 0x03, + 0x22, 0x32, 0xA7, 0x8D, 0x7D, 0x75, 0x23, 0x8D, + 0x5E, 0x6D, 0xAE, 0xCD, 0x3B, 0x43, 0x22, 0xCF, + 0x59, 0xBC, 0x7E, 0xA8, 0x4A, 0xB1, 0x88, 0x11, + 0xB5, 0xBF, 0xB7, 0xBC, 0x55, 0x3F, 0x4F, 0xE4, + 0x44, 0x78, 0xCE, 0x28, 0x7A, 0x14, 0x87, 0x99, + 0x90, 0xD1, 0x8D, 0x12, 0xCA, 0x79, 0xD2, 0xC8, + 0x55, 0x14, 0x90, 0x21, 0xCD, 0x5C, 0xE8, 0xCA, + 0x03, 0x71, 0xCA, 0x04, 0xFC, 0xCE, 0x14, 0x3E, + 0x3D, 0x7C, 0xFE, 0xE9, 0x45, 0x85, 0xB5, 0x88, + 0x5C, 0xAC, 0x46, 0x06, 0x8B, 0xC0, 0x00, 0x00 + }, + .len = 1024 + }, + .validAuthLenInBits = { + .len = 1000 + }, + .validAuthOffsetLenInBits = { + .len = 64 + }, + .digest = { + .data = {0xC3, 0x83, 0x83, 0x9D}, + .len = 4 + } +}; +#endif /* TEST_CRYPTODEV_KASUMI_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_kasumi_test_vectors.h b/app/test/test_cryptodev_kasumi_test_vectors.h new file mode 100644 index 00000000..9163d7c5 --- /dev/null +++ b/app/test/test_cryptodev_kasumi_test_vectors.h @@ -0,0 +1,308 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ + +struct kasumi_test_data { + struct { + uint8_t data[64]; + unsigned len; + } key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned len; + } iv; + + struct { + uint8_t data[1024]; + unsigned len; /* length must be in Bits */ + } plaintext; + + struct { + uint8_t data[1024]; + unsigned len; /* length must be in Bits */ + } ciphertext; + + struct { + unsigned len; + } validCipherLenInBits; + + struct { + unsigned len; + } validCipherOffsetLenInBits; +}; + +struct kasumi_test_data kasumi_test_case_1 = { + .key = { + .data = { + 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, + 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 + }, + .len = 16 + }, + .iv = { + .data = { + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x7E, 0xC6, 0x12, 0x72, 0x74, 0x3B, 0xF1, 0x61, + 0x47, 0x26, 0x44, 0x6A, 0x6C, 0x38, 0xCE, 0xD1, + 0x66, 0xF6, 0xCA, 0x76, 0xEB, 0x54, 0x30, 0x04, + 0x42, 0x86, 0x34, 0x6C, 0xEF, 0x13, 0x0F, 0x92, + 0x92, 0x2B, 0x03, 0x45, 0x0D, 0x3A, 0x99, 0x75, + 0xE5, 0xBD, 0x2E, 0xA0, 0xEB, 0x55, 0xAD, 0x8E, + 0x1B, 0x19, 0x9E, 0x3E, 0xC4, 0x31, 0x60, 0x20, + 0xE9, 0xA1, 0xB2, 0x85, 0xE7, 0x62, 0x79, 0x53, + 0x59, 0xB7, 0xBD, 0xFD, 0x39, 0xBE, 0xF4, 0xB2, + 0x48, 0x45, 0x83, 0xD5, 0xAF, 0xE0, 0x82, 0xAE, + 0xE6, 0x38, 0xBF, 0x5F, 0xD5, 0xA6, 0x06, 0x19, + 0x39, 0x01, 0xA0, 0x8F, 0x4A, 0xB4, 0x1A, 0xAB, + 0x9B, 0x13, 0x48, 0x80 + }, + .len = 800 + }, + .ciphertext = { + .data = { + 0xD1, 0xE2, 0xDE, 0x70, 0xEE, 0xF8, 0x6C, 0x69, + 0x64, 0xFB, 0x54, 0x2B, 0xC2, 0xD4, 0x60, 0xAA, + 0xBF, 0xAA, 0x10, 0xA4, 0xA0, 0x93, 0x26, 0x2B, + 0x7D, 0x19, 0x9E, 0x70, 0x6F, 0xC2, 0xD4, 0x89, + 0x15, 0x53, 0x29, 0x69, 0x10, 0xF3, 0xA9, 0x73, + 0x01, 0x26, 0x82, 0xE4, 0x1C, 0x4E, 0x2B, 0x02, + 0xBE, 0x20, 0x17, 0xB7, 0x25, 0x3B, 0xBF, 0x93, + 0x09, 0xDE, 0x58, 0x19, 0xCB, 0x42, 0xE8, 0x19, + 0x56, 0xF4, 0xC9, 0x9B, 0xC9, 0x76, 0x5C, 0xAF, + 0x53, 0xB1, 0xD0, 0xBB, 0x82, 0x79, 0x82, 0x6A, + 0xDB, 0xBC, 0x55, 0x22, 0xE9, 0x15, 0xC1, 0x20, + 0xA6, 0x18, 0xA5, 0xA7, 0xF5, 0xE8, 0x97, 0x08, + 0x93, 0x39, 0x65, 0x0F + }, + .len = 800 + }, + .validCipherLenInBits = { + .len = 798 + }, + .validCipherOffsetLenInBits = { + .len = 64 + }, +}; + +struct kasumi_test_data kasumi_test_case_2 = { + .key = { + .data = { + 0xEF, 0xA8, 0xB2, 0x22, 0x9E, 0x72, 0x0C, 0x2A, + 0x7C, 0x36, 0xEA, 0x55, 0xE9, 0x60, 0x56, 0x95 + }, + .len = 16 + }, + .iv = { + .data = { + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x10, 0x11, 0x12, 0x31, 0xE0, 0x60, 0x25, 0x3A, + 0x43, 0xFD, 0x3F, 0x57, 0xE3, 0x76, 0x07, 0xAB, + 0x28, 0x27, 0xB5, 0x99, 0xB6, 0xB1, 0xBB, 0xDA, + 0x37, 0xA8, 0xAB, 0xCC, 0x5A, 0x8C, 0x55, 0x0D, + 0x1B, 0xFB, 0x2F, 0x49, 0x46, 0x24, 0xFB, 0x50, + 0x36, 0x7F, 0xA3, 0x6C, 0xE3, 0xBC, 0x68, 0xF1, + 0x1C, 0xF9, 0x3B, 0x15, 0x10, 0x37, 0x6B, 0x02, + 0x13, 0x0F, 0x81, 0x2A, 0x9F, 0xA1, 0x69, 0xD8 + }, + .len = 512 + }, + .ciphertext = { + .data = { + 0x3D, 0xEA, 0xCC, 0x7C, 0x15, 0x82, 0x1C, 0xAA, + 0x89, 0xEE, 0xCA, 0xDE, 0x9B, 0x5B, 0xD3, 0x61, + 0x4B, 0xD0, 0xC8, 0x41, 0x9D, 0x71, 0x03, 0x85, + 0xDD, 0xBE, 0x58, 0x49, 0xEF, 0x1B, 0xAC, 0x5A, + 0xE8, 0xB1, 0x4A, 0x5B, 0x0A, 0x67, 0x41, 0x52, + 0x1E, 0xB4, 0xE0, 0x0B, 0xB9, 0xEC, 0xF3, 0xE9, + 0xF7, 0xCC, 0xB9, 0xCA, 0xE7, 0x41, 0x52, 0xD7, + 0xF4, 0xE2, 0xA0, 0x34, 0xB6, 0xEA, 0x00, 0xEC + }, + .len = 512 + }, + .validCipherLenInBits = { + .len = 510 + }, + .validCipherOffsetLenInBits = { + .len = 64 + } +}; + +struct kasumi_test_data kasumi_test_case_3 = { + .key = { + .data = { + 0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D, 0x51, 0x20, + 0x4E, 0xA5, 0xF1, 0x45, 0x10, 0x10, 0xD8, 0x52 + }, + .len = 16 + }, + .iv = { + .data = { + 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0xAD, 0x9C, 0x44, 0x1F, 0x89, 0x0B, 0x38, 0xC4, + 0x57, 0xA4, 0x9D, 0x42, 0x14, 0x07, 0xE8 + }, + .len = 120 + }, + .ciphertext = { + .data = { + 0x9B, 0xC9, 0x2C, 0xA8, 0x03, 0xC6, 0x7B, 0x28, + 0xA1, 0x1A, 0x4B, 0xEE, 0x5A, 0x0C, 0x25 + }, + .len = 120 + }, + .validCipherLenInBits = { + .len = 120 + }, + .validCipherOffsetLenInBits = { + .len = 64 + } +}; + +struct kasumi_test_data kasumi_test_case_4 = { + .key = { + .data = { + 0xD3, 0xC5, 0xD5, 0x92, 0x32, 0x7F, 0xB1, 0x1C, + 0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1 + }, + .len = 16 + }, + .iv = { + .data = { + 0x39, 0x8A, 0x59, 0xB4, 0x2C, 0x00, 0x00, 0x00, + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x98, 0x1B, 0xA6, 0x82, 0x4C, 0x1B, 0xFB, 0x1A, + 0xB4, 0x85, 0x47, 0x20, 0x29, 0xB7, 0x1D, 0x80, + 0x8C, 0xE3, 0x3E, 0x2C, 0xC3, 0xC0, 0xB5, 0xFC, + 0x1F, 0x3D, 0xE8, 0xA6, 0xDC, 0x66, 0xB1, 0xF0 + }, + .len = 256 + }, + .ciphertext = { + .data = { + 0x5B, 0xB9, 0x43, 0x1B, 0xB1, 0xE9, 0x8B, 0xD1, + 0x1B, 0x93, 0xDB, 0x7C, 0x3D, 0x45, 0x13, 0x65, + 0x59, 0xBB, 0x86, 0xA2, 0x95, 0xAA, 0x20, 0x4E, + 0xCB, 0xEB, 0xF6, 0xF7, 0xA5, 0x10, 0x15, 0x10 + }, + .len = 256 + }, + .validCipherLenInBits = { + .len = 253 + }, + .validCipherOffsetLenInBits = { + .len = 64 + } +}; + +struct kasumi_test_data kasumi_test_case_5 = { + .key = { + .data = { + 0x60, 0x90, 0xEA, 0xE0, 0x4C, 0x83, 0x70, 0x6E, + 0xEC, 0xBF, 0x65, 0x2B, 0xE8, 0xE3, 0x65, 0x66 + }, + .len = 16 + }, + .iv = { + .data = { + 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00 + }, + .len = 8 + }, + .plaintext = { + .data = { + 0x40, 0x98, 0x1B, 0xA6, 0x82, 0x4C, 0x1B, 0xFB, + 0x42, 0x86, 0xB2, 0x99, 0x78, 0x3D, 0xAF, 0x44, + 0x2C, 0x09, 0x9F, 0x7A, 0xB0, 0xF5, 0x8D, 0x5C, + 0x8E, 0x46, 0xB1, 0x04, 0xF0, 0x8F, 0x01, 0xB4, + 0x1A, 0xB4, 0x85, 0x47, 0x20, 0x29, 0xB7, 0x1D, + 0x36, 0xBD, 0x1A, 0x3D, 0x90, 0xDC, 0x3A, 0x41, + 0xB4, 0x6D, 0x51, 0x67, 0x2A, 0xC4, 0xC9, 0x66, + 0x3A, 0x2B, 0xE0, 0x63, 0xDA, 0x4B, 0xC8, 0xD2, + 0x80, 0x8C, 0xE3, 0x3E, 0x2C, 0xCC, 0xBF, 0xC6, + 0x34, 0xE1, 0xB2, 0x59, 0x06, 0x08, 0x76, 0xA0, + 0xFB, 0xB5, 0xA4, 0x37, 0xEB, 0xCC, 0x8D, 0x31, + 0xC1, 0x9E, 0x44, 0x54, 0x31, 0x87, 0x45, 0xE3, + 0x98, 0x76, 0x45, 0x98, 0x7A, 0x98, 0x6F, 0x2C, + 0xB0 + }, + .len = 840 + }, + .ciphertext = { + .data = { + 0xDD, 0xB3, 0x64, 0xDD, 0x2A, 0xAE, 0xC2, 0x4D, + 0xFF, 0x29, 0x19, 0x57, 0xB7, 0x8B, 0xAD, 0x06, + 0x3A, 0xC5, 0x79, 0xCD, 0x90, 0x41, 0xBA, 0xBE, + 0x89, 0xFD, 0x19, 0x5C, 0x05, 0x78, 0xCB, 0x9F, + 0xDE, 0x42, 0x17, 0x56, 0x61, 0x78, 0xD2, 0x02, + 0x40, 0x20, 0x6D, 0x07, 0xCF, 0xA6, 0x19, 0xEC, + 0x05, 0x9F, 0x63, 0x51, 0x44, 0x59, 0xFC, 0x10, + 0xD4, 0x2D, 0xC9, 0x93, 0x4E, 0x56, 0xEB, 0xC0, + 0xCB, 0xC6, 0x0D, 0x4D, 0x2D, 0xF1, 0x74, 0x77, + 0x4C, 0xBD, 0xCD, 0x5D, 0xA4, 0xA3, 0x50, 0x31, + 0x7A, 0x7F, 0x12, 0xE1, 0x94, 0x94, 0x71, 0xF8, + 0xA2, 0x95, 0xF2, 0x72, 0xE6, 0x8F, 0xC0, 0x71, + 0x59, 0xB0, 0x7D, 0x8E, 0x2D, 0x26, 0xE4, 0x59, + 0x9E + }, + .len = 840 + }, + .validCipherLenInBits = { + .len = 837 + }, + .validCipherOffsetLenInBits = { + .len = 64 + }, +}; + +#endif /* TEST_CRYPTODEV_KASUMI_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index b3f4fd9c..d7282112 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -38,7 +38,6 @@ #include <rte_crypto.h> #include <rte_cryptodev.h> #include <rte_cycles.h> -#include <rte_hexdump.h> #include "test.h" #include "test_cryptodev.h" @@ -58,6 +57,25 @@ struct crypto_testsuite_params { uint8_t dev_id; }; +enum chain_mode { + CIPHER_HASH, + HASH_CIPHER, + CIPHER_ONLY, + HASH_ONLY +}; + +struct perf_test_params { + + unsigned total_operations; + unsigned burst_size; + unsigned buf_size; + + enum chain_mode chain; + + enum rte_crypto_cipher_algorithm cipher_algo; + unsigned cipher_key_length; + enum rte_crypto_auth_algorithm auth_algo; +}; #define MAX_NUM_OF_OPS_PER_UT (128) @@ -75,6 +93,98 @@ struct crypto_unittest_params { uint8_t *digest; }; +static struct rte_cryptodev_sym_session * +test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo); +static struct rte_mbuf * +test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned data_len, + unsigned digest_len); +static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); + + +static const char *chain_mode_name(enum chain_mode mode) +{ + switch (mode) { + case CIPHER_HASH: return "cipher_hash"; break; + case HASH_CIPHER: return "hash_cipher"; break; + case CIPHER_ONLY: return "cipher_only"; break; + case HASH_ONLY: return "hash_only"; break; + default: return ""; break; + } +} + +static const char *pmd_name(enum rte_cryptodev_type pmd) +{ + switch (pmd) { + case RTE_CRYPTODEV_NULL_PMD: return CRYPTODEV_NAME_NULL_PMD; break; + case RTE_CRYPTODEV_AESNI_GCM_PMD: + return CRYPTODEV_NAME_AESNI_GCM_PMD; + case RTE_CRYPTODEV_AESNI_MB_PMD: + return CRYPTODEV_NAME_AESNI_MB_PMD; + case RTE_CRYPTODEV_QAT_SYM_PMD: + return CRYPTODEV_NAME_QAT_SYM_PMD; + case RTE_CRYPTODEV_SNOW3G_PMD: + return CRYPTODEV_NAME_SNOW3G_PMD; + default: + return ""; + } +} + +static const char *cipher_algo_name(enum rte_crypto_cipher_algorithm cipher_algo) +{ + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_NULL: return "NULL"; + case RTE_CRYPTO_CIPHER_3DES_CBC: return "3DES_CBC"; + case RTE_CRYPTO_CIPHER_3DES_CTR: return "3DES_CTR"; + case RTE_CRYPTO_CIPHER_3DES_ECB: return "3DES_ECB"; + case RTE_CRYPTO_CIPHER_AES_CBC: return "AES_CBC"; + case RTE_CRYPTO_CIPHER_AES_CCM: return "AES_CCM"; + case RTE_CRYPTO_CIPHER_AES_CTR: return "AES_CTR"; + case RTE_CRYPTO_CIPHER_AES_ECB: return "AES_ECB"; + case RTE_CRYPTO_CIPHER_AES_F8: return "AES_F8"; + case RTE_CRYPTO_CIPHER_AES_GCM: return "AES_GCM"; + case RTE_CRYPTO_CIPHER_AES_XTS: return "AES_XTS"; + case RTE_CRYPTO_CIPHER_ARC4: return "ARC4"; + case RTE_CRYPTO_CIPHER_KASUMI_F8: return "KASUMI_F8"; + case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: return "SNOW3G_UEA2"; + case RTE_CRYPTO_CIPHER_ZUC_EEA3: return "ZUC_EEA3"; + default: return "Another cipher algo"; + } +} + +static const char *auth_algo_name(enum rte_crypto_auth_algorithm auth_algo) +{ + switch (auth_algo) { + case RTE_CRYPTO_AUTH_NULL: return "NULL"; break; + case RTE_CRYPTO_AUTH_AES_CBC_MAC: return "AES_CBC_MAC"; break; + case RTE_CRYPTO_AUTH_AES_CCM: return "AES_CCM"; break; + case RTE_CRYPTO_AUTH_AES_CMAC: return "AES_CMAC,"; break; + case RTE_CRYPTO_AUTH_AES_GCM: return "AES_GCM"; break; + case RTE_CRYPTO_AUTH_AES_GMAC: return "AES_GMAC"; break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: return "AES_XCBC_MAC"; break; + case RTE_CRYPTO_AUTH_KASUMI_F9: return "KASUMI_F9"; break; + case RTE_CRYPTO_AUTH_MD5: return "MD5"; break; + case RTE_CRYPTO_AUTH_MD5_HMAC: return "MD5_HMAC,"; break; + case RTE_CRYPTO_AUTH_SHA1: return "SHA1"; break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: return "SHA1_HMAC"; break; + case RTE_CRYPTO_AUTH_SHA224: return "SHA224"; break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: return "SHA224_HMAC"; break; + case RTE_CRYPTO_AUTH_SHA256: return "SHA256"; break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: return "SHA256_HMAC"; break; + case RTE_CRYPTO_AUTH_SHA384: return "SHA384,"; break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: return "SHA384_HMAC,"; break; + case RTE_CRYPTO_AUTH_SHA512: return "SHA512,"; break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: return "SHA512_HMAC,"; break; + case RTE_CRYPTO_AUTH_SNOW3G_UIA2: return "SNOW3G_UIA2"; break; + case RTE_CRYPTO_AUTH_ZUC_EIA3: return "RTE_CRYPTO_AUTH_ZUC_EIA3"; break; + default: return "Another auth algo"; break; + }; +} + static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, const uint8_t *data, size_t len, uint8_t blocksize) @@ -97,7 +207,7 @@ setup_test_string(struct rte_mempool *mpool, static struct crypto_testsuite_params testsuite_params = { NULL }; static struct crypto_unittest_params unittest_params; -static enum rte_cryptodev_type gbl_cryptodev_preftest_devtype; +static enum rte_cryptodev_type gbl_cryptodev_perftest_devtype; static int testsuite_setup(void) @@ -134,7 +244,7 @@ testsuite_setup(void) } /* Create 2 AESNI MB devices if required */ - if (gbl_cryptodev_preftest_devtype == RTE_CRYPTODEV_AESNI_MB_PMD) { + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_MB_PMD) { nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_AESNI_MB_PMD); if (nb_devs < 2) { for (i = nb_devs; i < 2; i++) { @@ -148,6 +258,21 @@ testsuite_setup(void) } } + /* Create 2 SNOW3G devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_SNOW3G_PMD) { + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_SNOW3G_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + CRYPTODEV_NAME_SNOW3G_PMD, NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, CRYPTODEV_NAME_SNOW3G_PMD); + } + } + } + nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { RTE_LOG(ERR, USER1, "No crypto devices found?"); @@ -157,7 +282,7 @@ testsuite_setup(void) /* Search for the first valid */ for (i = 0; i < nb_devs; i++) { rte_cryptodev_info_get(i, &info); - if (info.dev_type == gbl_cryptodev_preftest_devtype) { + if (info.dev_type == gbl_cryptodev_perftest_devtype) { ts_params->dev_id = i; valid_dev_id = 1; break; @@ -218,7 +343,10 @@ testsuite_teardown(void) if (ts_params->mbuf_mp != NULL) RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", - rte_mempool_count(ts_params->mbuf_mp)); + rte_mempool_avail_count(ts_params->mbuf_mp)); + if (ts_params->op_mpool != NULL) + RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_OP POOL count %u\n", + rte_mempool_avail_count(ts_params->op_mpool)); } static int @@ -267,7 +395,7 @@ ut_teardown(void) if (ts_params->mbuf_mp != NULL) RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n", - rte_mempool_count(ts_params->mbuf_mp)); + rte_mempool_avail_count(ts_params->mbuf_mp)); rte_cryptodev_stats_get(ts_params->dev_id, &stats); @@ -363,12 +491,11 @@ const char plaintext_quote[] = #define CIPHER_KEY_LENGTH_AES_CBC (16) #define CIPHER_IV_LENGTH_AES_CBC (CIPHER_KEY_LENGTH_AES_CBC) - -static uint8_t aes_cbc_key[] = { +static uint8_t aes_cbc_128_key[] = { 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_cbc_128_iv[] = { 0xf5, 0xd3, 0x89, 0x0f, 0x47, 0x00, 0xcb, 0x52, 0x42, 0x1a, 0x7d, 0x3d, 0xf5, 0x82, 0x80, 0xf1 }; @@ -1693,7 +1820,6 @@ struct crypto_data_params aes_cbc_hmac_sha256_output[MAX_PACKET_SIZE_INDEX] = { { AES_CBC_ciphertext_2048B, HMAC_SHA256_ciphertext_2048B_digest } } }; - static int test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) { @@ -1718,7 +1844,7 @@ test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = aes_cbc_128_key; ut_params->cipher_xform.cipher.key.length = CIPHER_IV_LENGTH_AES_CBC; @@ -1774,7 +1900,7 @@ test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); op->sym->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(op->sym->cipher.iv.data, aes_cbc_iv, + rte_memcpy(op->sym->cipher.iv.data, aes_cbc_128_iv, CIPHER_IV_LENGTH_AES_CBC); op->sym->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1829,7 +1955,7 @@ test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) } while (num_received != num_to_submit) { - if (gbl_cryptodev_preftest_devtype == + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_AESNI_MB_PMD) rte_cryptodev_enqueue_burst(dev_num, 0, NULL, 0); @@ -1857,192 +1983,906 @@ test_perf_crypto_qp_vary_burst_size(uint16_t dev_num) } static int -test_perf_AES_CBC_HMAC_SHA256_encrypt_digest_vary_req_size(uint16_t dev_num) +test_perf_snow3G_optimise_cyclecount(struct perf_test_params *pparams) { - uint16_t index; - uint32_t burst_sent, burst_received; - uint32_t b, num_sent, num_received; - uint64_t failed_polls, retries, start_cycles, end_cycles; - const uint64_t mhz = rte_get_tsc_hz()/1000000; - double throughput, mmps; - - struct rte_crypto_op *c_ops[DEFAULT_BURST_SIZE]; - struct rte_crypto_op *proc_ops[DEFAULT_BURST_SIZE]; - + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; struct crypto_testsuite_params *ts_params = &testsuite_params; - struct crypto_unittest_params *ut_params = &unittest_params; - struct crypto_data_params *data_params = aes_cbc_hmac_sha256_output; + static struct rte_cryptodev_sym_session *sess; if (rte_cryptodev_count() == 0) { - printf("\nNo crypto devices available. Is kernel driver loaded?\n"); + printf("\nNo crypto devices found. Is PMD build configured?\n"); + printf("\nAnd is kernel driver loaded for HW PMDs?\n"); return TEST_FAILED; } - /* Setup Cipher Parameters */ - ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; - ut_params->cipher_xform.next = &ut_params->auth_xform; + /* Create Crypto session*/ + sess = test_perf_create_snow3g_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); - ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; - ut_params->cipher_xform.cipher.key.length = CIPHER_IV_LENGTH_AES_CBC; + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); - /* Setup HMAC Parameters */ - ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; - ut_params->auth_xform.next = NULL; + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); - ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha256_key; - ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256; - ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256; + op = test_perf_set_crypto_op_snow3g(op, m, sess, pparams->buf_size, + get_auth_digest_length(pparams->auth_algo)); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); - /* Create Crypto session*/ - ut_params->sess = rte_cryptodev_sym_session_create(ts_params->dev_id, - &ut_params->cipher_xform); + c_ops[i] = op; + } - TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, auth_algo:%s, " + "Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); - printf("\nThroughput test which will continually attempt to send " - "AES128_CBC_SHA256_HMAC requests with a constant burst " - "size of %u while varying payload sizes", DEFAULT_BURST_SIZE); - printf("\nDev No\tQP No\tReq Size(B)\tNum Sent\tNum Received\t" - "Mrps\tThoughput(Gbps)"); - printf("\tRetries (Attempted a burst, but the device was busy)"); - for (index = 0; index < MAX_PACKET_SIZE_INDEX; index++) { + for (i = 2; i <= 128 ; i *= 2) { num_sent = 0; - num_received = 0; + num_ops_received = 0; retries = 0; failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit-num_sent) < burst_size) ? + num_to_submit-num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + if (gbl_cryptodev_perftest_devtype == + RTE_CRYPTODEV_AESNI_MB_PMD) + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, + NULL, 0); + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + +static int +test_perf_snow3G_vary_burst_size(void) +{ + unsigned total_operations = 4096; + /*no need to vary pkt size for QAT, should have no effect on IA cycles */ + uint16_t buf_lengths[] = {40}; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_ONLY, + .cipher_algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + }, + { + .chain = HASH_ONLY, + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2, + .cipher_key_length = 16 + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not busy," + " i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; + j < RTE_DIM(buf_lengths); + j++) { + + params_set[i].buf_size = buf_lengths[j]; + + test_perf_snow3G_optimise_cyclecount(¶ms_set[i]); + } + + } + + return 0; +} + +static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) +{ + switch (algo) { + case RTE_CRYPTO_AUTH_SNOW3G_UIA2: + return 16; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + return 64; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + return 64; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + return 64; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + return 128; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + return 128; + default: + return 0; + } +} + +static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) +{ + switch (algo) { + case RTE_CRYPTO_AUTH_SNOW3G_UIA2: + return 4; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + return TRUNCATED_DIGEST_BYTE_LENGTH_SHA1; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + return TRUNCATED_DIGEST_BYTE_LENGTH_SHA224; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + return TRUNCATED_DIGEST_BYTE_LENGTH_SHA256; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + default: + return 0; + } +} + +static uint8_t aes_cbc_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static uint8_t aes_cbc_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static uint8_t hmac_sha_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static uint8_t snow3g_cipher_key[] = { + 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, + 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 +}; + +static uint8_t snow3g_iv[] = { + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00, + 0x72, 0xA4, 0xF2, 0x0F, 0x64, 0x00, 0x00, 0x00 +}; + +static uint8_t snow3g_hash_key[] = { + 0xC7, 0x36, 0xC6, 0xAA, 0xB2, 0x2B, 0xFF, 0xF9, + 0x1E, 0x26, 0x98, 0xD2, 0xE2, 0x2A, 0xD5, 0x7E +}; + +static struct rte_cryptodev_sym_session * +test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup HMAC Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + auth_xform.auth.key.data = hmac_sha_key; + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +static struct rte_cryptodev_sym_session * +test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = {0}; + struct rte_crypto_sym_xform auth_xform = {0}; + + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + cipher_xform.cipher.key.data = snow3g_cipher_key; + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup HMAC Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + auth_xform.auth.key.data = snow3g_hash_key; + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + case CIPHER_ONLY: + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_ONLY: + auth_xform.next = NULL; + /* Create Crypto session */ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_CBC_BLOCK_SIZE 16 +#define AES_CBC_CIPHER_IV_LENGTH 16 +#define SNOW3G_CIPHER_IV_LENGTH 16 + +static struct rte_mbuf * +test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) +{ + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + + if (rte_pktmbuf_append(m, buf_sz) == NULL) { + rte_pktmbuf_free(m); + return NULL; + } + + memset(rte_pktmbuf_mtod(m, uint8_t *), 0, buf_sz); + + return m; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned data_len, + unsigned digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } - /* Generate Crypto op data structure(s) */ - for (b = 0; b < DEFAULT_BURST_SIZE ; b++) { - struct rte_mbuf *m = setup_test_string( - ts_params->mbuf_mp, - (const uint8_t *) - data_params[index].plaintext, - data_params[index].length, - 0); + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_cbc_iv; + op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; - ut_params->digest = (uint8_t *)rte_pktmbuf_append(m, - DIGEST_BYTE_LENGTH_SHA256); - TEST_ASSERT_NOT_NULL(ut_params->digest - , "no room to append digest"); + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_cbc_iv; + op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; - rte_memcpy(ut_params->digest, - data_params[index].expected.digest, - DIGEST_BYTE_LENGTH_SHA256); + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; - struct rte_crypto_op *op = rte_crypto_op_alloc( - ts_params->op_mpool, - RTE_CRYPTO_OP_TYPE_SYMMETRIC); + op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; - rte_crypto_op_attach_sym_session(op, ut_params->sess); + op->sym->m_src = m; - op->sym->auth.digest.data = ut_params->digest; - op->sym->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(m, - data_params[index].length); - op->sym->auth.digest.length = DIGEST_BYTE_LENGTH_SHA256; + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned data_len, + unsigned digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = snow3g_iv; + op->sym->auth.aad.length = SNOW3G_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = snow3g_iv; + op->sym->cipher.iv.length = SNOW3G_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len << 3; + + op->sym->cipher.data.offset = 0; + op->sym->cipher.data.length = data_len << 3; + + op->sym->m_src = m; + + return op; +} + + + +/* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at + * same time, i.e. as they're not dereferenced there's no need to wait until + * finished with to re-use */ +#define NUM_MBUF_SETS 8 + +static int +test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; - op->sym->auth.data.offset = CIPHER_IV_LENGTH_AES_CBC; - op->sym->auth.data.length = data_params[index].length; + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; - op->sym->cipher.iv.data = (uint8_t *) - rte_pktmbuf_prepend(m, - CIPHER_IV_LENGTH_AES_CBC); - op->sym->cipher.iv.phys_addr = rte_pktmbuf_mtophys(m); - op->sym->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; + uint16_t digest_length = get_auth_digest_length(pparams->auth_algo); - rte_memcpy(op->sym->cipher.iv.data, aes_cbc_iv, - CIPHER_IV_LENGTH_AES_CBC); + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; - op->sym->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; - op->sym->cipher.data.length = data_params[index].length; + struct rte_mbuf *mbufs[pparams->burst_size * 8]; + struct crypto_testsuite_params *ts_params = &testsuite_params; - op->sym->m_src = m; + static struct rte_cryptodev_sym_session *sess; + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices available. Is kernel driver loaded?\n"); + return TEST_FAILED; + } - c_ops[b] = op; + /* Create Crypto session*/ + sess = test_perf_create_aes_sha_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; } - start_cycles = rte_rdtsc_precise(); - while (num_sent < DEFAULT_NUM_REQS_TO_SUBMIT) { - uint16_t burst_size = (DEFAULT_NUM_REQS_TO_SUBMIT - - num_sent) < DEFAULT_BURST_SIZE ? - DEFAULT_NUM_REQS_TO_SUBMIT - - num_sent : DEFAULT_BURST_SIZE; - - burst_sent = rte_cryptodev_enqueue_burst( - dev_num, 0, c_ops, burst_size); - if (burst_sent == 0) + + } + + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued+pparams->burst_size <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations-total_enqueued; + uint16_t ops_needed = burst_size-ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) retries++; - else - num_sent += burst_sent; - burst_received = rte_cryptodev_dequeue_burst(dev_num, - 0, proc_ops, DEFAULT_BURST_SIZE); - if (burst_received == 0) - failed_polls++; - else - num_received += burst_received; + ops_unused = burst_size-burst_enqueued; + total_enqueued += burst_enqueued; } - while (num_received != DEFAULT_NUM_REQS_TO_SUBMIT) { - if (gbl_cryptodev_preftest_devtype == - RTE_CRYPTODEV_AESNI_MB_PMD) - rte_cryptodev_enqueue_burst(dev_num, 0, - NULL, 0); - burst_received = rte_cryptodev_dequeue_burst( - dev_num, 0, proc_ops, - DEFAULT_BURST_SIZE); - if (burst_received == 0) - failed_polls++; - else - num_received += burst_received; + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); } - end_cycles = rte_rdtsc_precise(); - mmps = ((double)num_received * mhz) / - (end_cycles - start_cycles); - throughput = (mmps * data_params[index].length * 8) / 1000; - - printf("\n%u\t%u\t%u\t\t%u\t%u", dev_num, 0, - data_params[index].length, - num_sent, num_received); - printf("\t%.2f\t%.2f", mmps, throughput); - printf("\t\t%"PRIu64, retries); - for (b = 0; b < DEFAULT_BURST_SIZE ; b++) { - rte_pktmbuf_free(c_ops[b]->sym->m_src); - rte_crypto_op_free(c_ops[b]); + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * 8) / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, ops_s/1000000, + throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + + +static int +test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + uint16_t digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + printf("\nAnd is kernel driver loaded for HW PMDs?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_snow3g_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + (total_enqueued+pparams->burst_size) + <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations-total_enqueued; + uint16_t ops_needed = burst_size-ops_unused; + /* Handle the last burst correctly */ + uint16_t op_offset = pparams->burst_size - burst_size; + + if (ops_needed != + rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, + ops+op_offset, ops_needed)) { + printf("\nFailed to alloc enough ops."); + /*Don't exit, dequeue, more ops should become available*/ + } else { + for (i = 0; i < ops_needed; i++) { + ops[i+op_offset] = + test_perf_set_crypto_op_snow3g(ops[i+op_offset], + mbufs[i + + (pparams->burst_size * (j % NUM_MBUF_SETS))], + sess, + pparams->buf_size, digest_length); + } + + /* enqueue burst */ + burst_enqueued = + rte_cryptodev_enqueue_burst(dev_id, queue_id, + ops+op_offset, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size-burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) { + failed_polls++; + } else { + processed += burst_dequeued; + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); } } + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) * rte_get_tsc_hz(); + double cycles_burst = (double) (tsc_end - tsc_start) / + (double) processed * pparams->burst_size; + double cycles_buff = (double) (tsc_end - tsc_start) / (double) processed; + double cycles_B = cycles_buff / pparams->buf_size; + double throughput = (ops_s * pparams->buf_size * 8) / 1000000; + + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { + /* Cycle count misleading on HW devices for this test, so don't print */ + printf("%4u\t%6.2f\t%10.2f\t n/a \t\t n/a " + "\t\t n/a \t\t%8"PRIu64"\t%8"PRIu64, + pparams->buf_size, ops_s/1000000, + throughput, retries, failed_polls); + } else { + printf("%4u\t%6.2f\t%10.2f\t%10.2f\t%8.2f" + "\t%8.2f\t%8"PRIu64"\t%8"PRIu64, + pparams->buf_size, ops_s/1000000, throughput, cycles_burst, + cycles_buff, cycles_B, retries, failed_polls); + } + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + printf("\n"); return TEST_SUCCESS; } +/* + + perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); + perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA_256); + perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA_512); + + perf_test_aes_sha("avx2", CIPHER_HASH, 32, CBC, SHA1); + perf_test_aes_sha("avx2", CIPHER_HASH, 32, CBC, SHA_256); + perf_test_aes_sha("avx2", CIPHER_HASH, 32, CBC, SHA_512); + + perf_test_aes_sha("avx2", HASH_CIPHER, 32, CBC, SHA1); + perf_test_aes_sha("avx2", HASH_CIPHER, 32, CBC, SHA_256); + perf_test_aes_sha("avx2", HASH_CIPHER, 32, CBC, SHA_512); + */ +static int +test_perf_aes_cbc_encrypt_digest_vary_pkt_size(void) +{ + unsigned total_operations = 1000000; + unsigned burst_size = 32; + unsigned buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\t" + "Retries\tEmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_aes_sha(testsuite_params.dev_id, 0, + ¶ms_set[i]); + } + } + return 0; +} + static int -test_perf_encrypt_digest_vary_req_size(void) +test_perf_snow3G_vary_pkt_size(void) { - return test_perf_AES_CBC_HMAC_SHA256_encrypt_digest_vary_req_size( - testsuite_params.dev_id); + unsigned total_operations = 1000000; + uint8_t i, j; + unsigned k; + uint16_t burst_sizes[] = {64}; + uint16_t buf_lengths[] = {40, 64, 80, 120, 240, 256, 400, 512, 600, 1024, 2048}; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_ONLY, + .cipher_algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + }, + { + .chain = HASH_ONLY, + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2, + .cipher_key_length = 16 + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nTest to measure max throughput at various pkt sizes."); + printf("\nOn HW devices t'put maximised when high Retries and EmptyPolls" + " so cycle cost not relevant (n/a displayed)."); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n\n"); + params_set[i].total_operations = total_operations; + for (k = 0; k < RTE_DIM(burst_sizes); k++) { + printf("\nOn %s dev%u qp%u, %s, " + "cipher algo:%s, auth algo:%s, burst_size: %d ops", + pmd_name(gbl_cryptodev_perftest_devtype), + testsuite_params.dev_id, 0, + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + burst_sizes[k]); + + params_set[i].burst_size = burst_sizes[k]; + printf("\nPktSzB\tOp/s(M)\tThruput(Mbps)\tCycles/Burst\t" + "Cycles/buf\tCycles/B\tRetries\t\tEmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + + params_set[i].buf_size = buf_lengths[j]; + + test_perf_snow3g(testsuite_params.dev_id, 0, ¶ms_set[i]); + } + } + } + + return 0; } static int -test_perf_vary_burst_size(void) +test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); } - +#if 1 static struct unit_test_suite cryptodev_testsuite = { .suite_name = "Crypto Device Unit Test Suite", .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_encrypt_digest_vary_req_size), + test_perf_aes_cbc_encrypt_digest_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_aes_cbc_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; +#endif +static struct unit_test_suite cryptodev_aes_testsuite = { + .suite_name = "Crypto Device AESNI MB Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_aes_cbc_encrypt_digest_vary_pkt_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_snow3g_testsuite = { + .suite_name = "Crypto Device Snow3G Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_snow3G_vary_pkt_size), TEST_CASE_ST(ut_setup, ut_teardown, - test_perf_vary_burst_size), + test_perf_snow3G_vary_burst_size), TEST_CASES_END() /**< NULL terminate unit test array */ } }; @@ -2050,19 +2890,35 @@ static struct unit_test_suite cryptodev_testsuite = { static int perftest_aesni_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) { - gbl_cryptodev_preftest_devtype = RTE_CRYPTODEV_AESNI_MB_PMD; + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_AESNI_MB_PMD; - return unit_test_suite_runner(&cryptodev_testsuite); + return unit_test_suite_runner(&cryptodev_aes_testsuite); } static int perftest_qat_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) { - gbl_cryptodev_preftest_devtype = RTE_CRYPTODEV_QAT_SYM_PMD; + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_QAT_SYM_PMD; return unit_test_suite_runner(&cryptodev_testsuite); } +static int +perftest_sw_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_SNOW3G_PMD; + + return unit_test_suite_runner(&cryptodev_snow3g_testsuite); +} + +static int +perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_QAT_SYM_PMD; + + return unit_test_suite_runner(&cryptodev_snow3g_testsuite); +} + static struct test_command cryptodev_aesni_mb_perf_cmd = { .command = "cryptodev_aesni_mb_perftest", .callback = perftest_aesni_mb_cryptodev, @@ -2073,5 +2929,17 @@ static struct test_command cryptodev_qat_perf_cmd = { .callback = perftest_qat_cryptodev, }; +static struct test_command cryptodev_sw_snow3g_perf_cmd = { + .command = "cryptodev_sw_snow3g_perftest", + .callback = perftest_sw_snow3g_cryptodev, +}; + +static struct test_command cryptodev_qat_snow3g_perf_cmd = { + .command = "cryptodev_qat_snow3g_perftest", + .callback = perftest_qat_snow3g_cryptodev, +}; + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perf_cmd); REGISTER_TEST_COMMAND(cryptodev_qat_perf_cmd); +REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perf_cmd); +REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perf_cmd); diff --git a/app/test/test_cryptodev_snow3g_hash_test_vectors.h b/app/test/test_cryptodev_snow3g_hash_test_vectors.h index fe4906bc..a8a47db5 100644 --- a/app/test/test_cryptodev_snow3g_hash_test_vectors.h +++ b/app/test/test_cryptodev_snow3g_hash_test_vectors.h @@ -438,4 +438,111 @@ struct snow3g_hash_test_data snow3g_hash_test_case_3 = { } }; +struct snow3g_hash_test_data snow3g_hash_test_case_4 = { + .key = { + .data = { + 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, + 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 + }, + .len = 16 + }, + .aad = { + .data = { + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + 0x38, 0xA6, 0xF0, 0x56, 0x05, 0xD2, 0xEC, 0x49, + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x6B, 0x22, 0x77, 0x37, 0x29, 0x6F, 0x39, 0x3C, + 0x80, 0x79, 0x35, 0x3E, 0xDC, 0x87, 0xE2, 0xE8, + 0x05, 0xD2, 0xEC, 0x49, 0xA4, 0xF2, 0xD8, 0xE0 + }, + .len = 189 + }, + .validAuthLenInBits = { + .len = 189 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x2B, 0xCE, 0x18, 0x20}, + .len = 4 + } +}; + +struct snow3g_hash_test_data snow3g_hash_test_case_5 = { + .key = { + .data = { + 0xD4, 0x2F, 0x68, 0x24, 0x28, 0x20, 0x1C, 0xAF, + 0xCD, 0x9F, 0x97, 0x94, 0x5E, 0x6D, 0xE7, 0xB7 + }, + .len = 16 + }, + .aad = { + .data = { + 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2, + 0xBE, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0x58, 0xE2 + }, + .len = 16 + }, + .plaintext = { + .data = { + 0xB5, 0x92, 0x43, 0x84, 0x32, 0x8A, 0x4A, 0xE0, + 0x0B, 0x73, 0x71, 0x09, 0xF8, 0xB6, 0xC8, 0xDD, + 0x2B, 0x4D, 0xB6, 0x3D, 0xD5, 0x33, 0x98, 0x1C, + 0xEB, 0x19, 0xAA, 0xD5, 0x2A, 0x5B, 0x2B, 0xC0 + }, + .len = 254 + }, + .validAuthLenInBits = { + .len = 254 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0xFC, 0x7B, 0x18, 0xBD}, + .len = 4 + } +}; + +struct snow3g_hash_test_data snow3g_hash_test_case_6 = { + .key = { + .data = { + 0xFD, 0xB9, 0xCF, 0xDF, 0x28, 0x93, 0x6C, 0xC4, + 0x83, 0xA3, 0x18, 0x69, 0xD8, 0x1B, 0x8F, 0xAB + }, + .len = 16 + }, + .aad = { + .data = { + 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A, + 0xB6, 0xAF, 0x61, 0x44, 0x98, 0x38, 0x70, 0x3A + }, + .len = 16 + }, + .plaintext = { + .data = { + 0x59, 0x32, 0xBC, 0x0A, 0xCE, 0x2B, 0x0A, 0xBA, + 0x33, 0xD8, 0xAC, 0x18, 0x8A, 0xC5, 0x4F, 0x34, + 0x6F, 0xAD, 0x10, 0xBF, 0x9D, 0xEE, 0x29, 0x20, + 0xB4, 0x3B, 0xD0, 0xC5, 0x3A, 0x91, 0x5C, 0xB7, + 0xDF, 0x6C, 0xAA, 0x72, 0x05, 0x3A, 0xBF, 0xF2 + }, + .len = 319 + }, + .validAuthLenInBits = { + .len = 319 + }, + .validAuthOffsetLenInBits = { + .len = 128 + }, + .digest = { + .data = {0x02, 0xF1, 0xFA, 0xAF}, + .len = 4 + } +}; #endif /* TEST_CRYPTODEV_SNOW3G_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_hash.c b/app/test/test_hash.c index adbdb4a8..7e41725a 100644 --- a/app/test/test_hash.c +++ b/app/test/test_hash.c @@ -176,7 +176,7 @@ static struct rte_hash_parameters ut_params = { .socket_id = 0, }; -#define CRC32_ITERATIONS (1U << 20) +#define CRC32_ITERATIONS (1U << 10) #define CRC32_DWORDS (1U << 6) /* * Test if all CRC32 implementations yield the same hash value @@ -486,7 +486,7 @@ static int test_five_keys(void) for(i = 0; i < 5; i++) key_array[i] = &keys[i]; - ret = rte_hash_lookup_multi(handle, &key_array[0], 5, (int32_t *)pos); + ret = rte_hash_lookup_bulk(handle, &key_array[0], 5, (int32_t *)pos); if(ret == 0) for(i = 0; i < 5; i++) { print_key_info("Lkp", key_array[i], pos[i]); @@ -527,7 +527,7 @@ static int test_five_keys(void) } /* Lookup multi */ - ret = rte_hash_lookup_multi(handle, &key_array[0], 5, (int32_t *)pos); + ret = rte_hash_lookup_bulk(handle, &key_array[0], 5, (int32_t *)pos); if (ret == 0) for (i = 0; i < 5; i++) { print_key_info("Lkp", key_array[i], pos[i]); @@ -1081,7 +1081,7 @@ test_hash_creation_with_good_parameters(void) return 0; } -#define ITERATIONS 50 +#define ITERATIONS 3 /* * Test to see the average table utilization (entries added/max entries) * before hitting a random entry that cannot be added @@ -1098,7 +1098,7 @@ static int test_average_table_utilization(void) "\n before adding elements begins to fail\n"); printf("Measuring performance, please wait"); fflush(stdout); - ut_params.entries = 1 << 20; + ut_params.entries = 1 << 16; ut_params.name = "test_average_utilization"; ut_params.hash_func = rte_jhash; handle = rte_hash_create(&ut_params); @@ -1138,7 +1138,7 @@ static int test_average_table_utilization(void) return 0; } -#define NUM_ENTRIES 1024 +#define NUM_ENTRIES 256 static int test_hash_iteration(void) { struct rte_hash *handle; diff --git a/app/test/test_hash_multiwriter.c b/app/test/test_hash_multiwriter.c new file mode 100644 index 00000000..b0f31b00 --- /dev/null +++ b/app/test/test_hash_multiwriter.c @@ -0,0 +1,287 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <inttypes.h> +#include <locale.h> + +#include <rte_cycles.h> +#include <rte_hash.h> +#include <rte_hash_crc.h> +#include <rte_launch.h> +#include <rte_malloc.h> +#include <rte_random.h> +#include <rte_spinlock.h> + +#include "test.h" + +/* + * Check condition and return an error if true. Assumes that "handle" is the + * name of the hash structure pointer to be freed. + */ +#define RETURN_IF_ERROR(cond, str, ...) do { \ + if (cond) { \ + printf("ERROR line %d: " str "\n", __LINE__, \ + ##__VA_ARGS__); \ + if (handle) \ + rte_hash_free(handle); \ + return -1; \ + } \ +} while (0) + +#define RTE_APP_TEST_HASH_MULTIWRITER_FAILED 0 + +struct { + uint32_t *keys; + uint32_t *found; + uint32_t nb_tsx_insertion; + struct rte_hash *h; +} tbl_multiwriter_test_params; + +const uint32_t nb_entries = 16*1024*1024; +const uint32_t nb_total_tsx_insertion = 15*1024*1024; +uint32_t rounded_nb_total_tsx_insertion; + +static rte_atomic64_t gcycles; +static rte_atomic64_t ginsertions; + +static int use_htm; + +static int +test_hash_multiwriter_worker(__attribute__((unused)) void *arg) +{ + uint64_t i, offset; + uint32_t lcore_id = rte_lcore_id(); + uint64_t begin, cycles; + + offset = (lcore_id - rte_get_master_lcore()) + * tbl_multiwriter_test_params.nb_tsx_insertion; + + printf("Core #%d inserting %d: %'"PRId64" - %'"PRId64"\n", + lcore_id, tbl_multiwriter_test_params.nb_tsx_insertion, + offset, offset + tbl_multiwriter_test_params.nb_tsx_insertion); + + begin = rte_rdtsc_precise(); + + for (i = offset; + i < offset + tbl_multiwriter_test_params.nb_tsx_insertion; + i++) { + if (rte_hash_add_key(tbl_multiwriter_test_params.h, + tbl_multiwriter_test_params.keys + i) < 0) + break; + } + + cycles = rte_rdtsc_precise() - begin; + rte_atomic64_add(&gcycles, cycles); + rte_atomic64_add(&ginsertions, i - offset); + + for (; i < offset + tbl_multiwriter_test_params.nb_tsx_insertion; i++) + tbl_multiwriter_test_params.keys[i] + = RTE_APP_TEST_HASH_MULTIWRITER_FAILED; + + return 0; +} + + +static int +test_hash_multiwriter(void) +{ + unsigned int i, rounded_nb_total_tsx_insertion; + static unsigned calledCount = 1; + + uint32_t *keys; + uint32_t *found; + + struct rte_hash_parameters hash_params = { + .entries = nb_entries, + .key_len = sizeof(uint32_t), + .hash_func = rte_hash_crc, + .hash_func_init_val = 0, + .socket_id = rte_socket_id(), + }; + if (use_htm) + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT + | RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + else + hash_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + + struct rte_hash *handle; + char name[RTE_HASH_NAMESIZE]; + + const void *next_key; + void *next_data; + uint32_t iter = 0; + + uint32_t duplicated_keys = 0; + uint32_t lost_keys = 0; + + snprintf(name, 32, "test%u", calledCount++); + hash_params.name = name; + + handle = rte_hash_create(&hash_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + + tbl_multiwriter_test_params.h = handle; + tbl_multiwriter_test_params.nb_tsx_insertion = + nb_total_tsx_insertion / rte_lcore_count(); + + rounded_nb_total_tsx_insertion = (nb_total_tsx_insertion / + tbl_multiwriter_test_params.nb_tsx_insertion) + * tbl_multiwriter_test_params.nb_tsx_insertion; + + rte_srand(rte_rdtsc()); + + keys = rte_malloc(NULL, sizeof(uint32_t) * nb_entries, 0); + + if (keys == NULL) { + printf("RTE_MALLOC failed\n"); + goto err1; + } + + found = rte_zmalloc(NULL, sizeof(uint32_t) * nb_entries, 0); + if (found == NULL) { + printf("RTE_ZMALLOC failed\n"); + goto err2; + } + + for (i = 0; i < nb_entries; i++) + keys[i] = i; + + tbl_multiwriter_test_params.keys = keys; + tbl_multiwriter_test_params.found = found; + + rte_atomic64_init(&gcycles); + rte_atomic64_clear(&gcycles); + + rte_atomic64_init(&ginsertions); + rte_atomic64_clear(&ginsertions); + + /* Fire all threads. */ + rte_eal_mp_remote_launch(test_hash_multiwriter_worker, + NULL, CALL_MASTER); + rte_eal_mp_wait_lcore(); + + while (rte_hash_iterate(handle, &next_key, &next_data, &iter) >= 0) { + /* Search for the key in the list of keys added .*/ + i = *(const uint32_t *)next_key; + tbl_multiwriter_test_params.found[i]++; + } + + for (i = 0; i < rounded_nb_total_tsx_insertion; i++) { + if (tbl_multiwriter_test_params.keys[i] + != RTE_APP_TEST_HASH_MULTIWRITER_FAILED) { + if (tbl_multiwriter_test_params.found[i] > 1) { + duplicated_keys++; + break; + } + if (tbl_multiwriter_test_params.found[i] == 0) { + lost_keys++; + printf("key %d is lost\n", i); + break; + } + } + } + + if (duplicated_keys > 0) { + printf("%d key duplicated\n", duplicated_keys); + goto err3; + } + + if (lost_keys > 0) { + printf("%d key lost\n", lost_keys); + goto err3; + } + + printf("No key corrupted during multiwriter insertion.\n"); + + unsigned long long int cycles_per_insertion = + rte_atomic64_read(&gcycles)/ + rte_atomic64_read(&ginsertions); + + printf(" cycles per insertion: %llu\n", cycles_per_insertion); + + rte_free(tbl_multiwriter_test_params.found); + rte_free(tbl_multiwriter_test_params.keys); + rte_hash_free(handle); + return 0; + +err3: + rte_free(tbl_multiwriter_test_params.found); +err2: + rte_free(tbl_multiwriter_test_params.keys); +err1: + rte_hash_free(handle); + return -1; +} + +static int +test_hash_multiwriter_main(void) +{ + int r = -1; + + if (rte_lcore_count() == 1) { + printf("More than one lcore is required to do multiwriter test\n"); + return 0; + } + + + setlocale(LC_NUMERIC, ""); + + + if (!rte_tm_supported()) { + printf("Hardware transactional memory (lock elision) " + "is NOT supported\n"); + } else { + printf("Hardware transactional memory (lock elision) " + "is supported\n"); + + printf("Test multi-writer with Hardware transactional memory\n"); + + use_htm = 1; + r = test_hash_multiwriter(); + } + + printf("Test multi-writer without Hardware transactional memory\n"); + use_htm = 0; + r = test_hash_multiwriter(); + + return r; +} + + +static struct test_command hash_scaling_cmd = { + .command = "hash_multiwriter_autotest", + .callback = test_hash_multiwriter_main, +}; + +REGISTER_TEST_COMMAND(hash_scaling_cmd); diff --git a/app/test/test_interrupts.c b/app/test/test_interrupts.c index 6e3dec31..df6d2618 100644 --- a/app/test/test_interrupts.c +++ b/app/test/test_interrupts.c @@ -41,7 +41,7 @@ #include "test.h" -#define TEST_INTERRUPT_CHECK_INTERVAL 1000 /* ms */ +#define TEST_INTERRUPT_CHECK_INTERVAL 100 /* ms */ /* predefined interrupt handle types */ enum test_interrupt_handle_type { @@ -372,7 +372,7 @@ test_interrupt_full_path_check(enum test_interrupt_handle_type intr_type) if (test_interrupt_trigger_interrupt() < 0) return -1; - /* check flag in 3 seconds */ + /* check flag */ for (count = 0; flag == 0 && count < 3; count++) rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL); diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c index 7cbc2891..eeb13954 100644 --- a/app/test/test_link_bonding.c +++ b/app/test/test_link_bonding.c @@ -83,7 +83,7 @@ #define MAX_PKT_BURST (512) #define DEF_PKT_BURST (16) -#define BONDED_DEV_NAME ("unit_test_bonded_device") +#define BONDED_DEV_NAME ("unit_test_bond_dev") #define INVALID_SOCKET_ID (-1) #define INVALID_PORT_ID (-1) diff --git a/app/test/test_link_bonding_mode4.c b/app/test/test_link_bonding_mode4.c index 31640cd6..a3f1f088 100644 --- a/app/test/test_link_bonding_mode4.c +++ b/app/test/test_link_bonding_mode4.c @@ -151,6 +151,8 @@ static struct rte_eth_conf default_pmd_conf = { .lpbk_mode = 0, }; +static uint8_t lacpdu_rx_count[RTE_MAX_ETHPORTS] = {0, }; + #define FOR_EACH(_i, _item, _array, _size) \ for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++) @@ -320,8 +322,26 @@ remove_slave(struct slave_conf *slave) return 0; } +static void +lacp_recv_cb(uint8_t slave_id, struct rte_mbuf *lacp_pkt) +{ + struct ether_hdr *hdr; + struct slow_protocol_frame *slow_hdr; + + RTE_VERIFY(lacp_pkt != NULL); + + hdr = rte_pktmbuf_mtod(lacp_pkt, struct ether_hdr *); + RTE_VERIFY(hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_SLOW)); + + slow_hdr = rte_pktmbuf_mtod(lacp_pkt, struct slow_protocol_frame *); + RTE_VERIFY(slow_hdr->slow_protocol.subtype == SLOW_SUBTYPE_LACP); + + lacpdu_rx_count[slave_id]++; + rte_pktmbuf_free(lacp_pkt); +} + static int -initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t start) +initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t external_sm) { uint8_t i; @@ -337,9 +357,17 @@ initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t start) rte_eth_bond_8023ad_setup(test_params.bonded_port_id, NULL); rte_eth_promiscuous_disable(test_params.bonded_port_id); - if (start) - TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id), - "Failed to start bonded device"); + if (external_sm) { + struct rte_eth_bond_8023ad_conf conf; + + rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); + conf.slowrx_cb = lacp_recv_cb; + rte_eth_bond_8023ad_setup(test_params.bonded_port_id, &conf); + + } + + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id), + "Failed to start bonded device"); return TEST_SUCCESS; } @@ -640,7 +668,7 @@ test_mode4_lacp(void) { int retval; - retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 1); + retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); /* Test LACP handshake function */ @@ -738,7 +766,8 @@ test_mode4_rx(void) struct ether_addr dst_mac; struct ether_addr bonded_mac; - retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, + 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); retval = bond_handshake(); @@ -915,7 +944,7 @@ test_mode4_tx_burst(void) struct ether_addr dst_mac = { { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } }; struct ether_addr bonded_mac; - retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); retval = bond_handshake(); @@ -1099,7 +1128,8 @@ test_mode4_marker(void) uint8_t i, j; const uint16_t ethtype_slow_be = rte_be_to_cpu_16(ETHER_TYPE_SLOW); - retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, 1); + retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, + 0); TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); /* Test LACP handshake function */ @@ -1184,7 +1214,8 @@ test_mode4_expired(void) struct rte_eth_bond_8023ad_conf conf; - retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, 1); + retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, + 0); /* Set custom timeouts to make test last shorter. */ rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf); conf.fast_periodic_ms = 100; @@ -1266,6 +1297,156 @@ test_mode4_expired(void) } static int +test_mode4_ext_ctrl(void) +{ + /* + * configure bonded interface without the external sm enabled + * . try to transmit lacpdu (should fail) + * . try to set collecting and distributing flags (should fail) + * reconfigure w/external sm + * . transmit one lacpdu on each slave using new api + * . make sure each slave receives one lacpdu using the callback api + * . transmit one data pdu on each slave (should fail) + * . enable distribution and collection, send one data pdu each again + */ + + int retval; + struct slave_conf *slave = NULL; + uint8_t i; + + struct rte_mbuf *lacp_tx_buf[SLAVE_COUNT]; + struct ether_addr src_mac, dst_mac; + struct lacpdu_header lacpdu = { + .lacpdu = { + .subtype = SLOW_SUBTYPE_LACP, + }, + }; + + ether_addr_copy(&parnter_system, &src_mac); + ether_addr_copy(&slow_protocol_mac_addr, &dst_mac); + + initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac, + ETHER_TYPE_SLOW, 0, 0); + + for (i = 0; i < SLAVE_COUNT; i++) { + lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool); + rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *), + &lacpdu, sizeof(lacpdu)); + rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu); + } + + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 0); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + FOR_EACH_SLAVE(i, slave) { + TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_slowtx( + test_params.bonded_port_id, + slave->port_id, lacp_tx_buf[i]), + "Slave should not allow manual LACP xmit"); + TEST_ASSERT_FAIL(rte_eth_bond_8023ad_ext_collect( + test_params.bonded_port_id, + slave->port_id, 1), + "Slave should not allow external state controls"); + } + + free_pkts(lacp_tx_buf, RTE_DIM(lacp_tx_buf)); + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Bonded device cleanup failed."); + + return TEST_SUCCESS; +} + + +static int +test_mode4_ext_lacp(void) +{ + int retval; + struct slave_conf *slave = NULL; + uint8_t all_slaves_done = 0, i; + uint16_t nb_pkts; + const unsigned int delay = bond_get_update_timeout_ms(); + + struct rte_mbuf *lacp_tx_buf[SLAVE_COUNT]; + struct rte_mbuf *buf[SLAVE_COUNT]; + struct ether_addr src_mac, dst_mac; + struct lacpdu_header lacpdu = { + .lacpdu = { + .subtype = SLOW_SUBTYPE_LACP, + }, + }; + + ether_addr_copy(&parnter_system, &src_mac); + ether_addr_copy(&slow_protocol_mac_addr, &dst_mac); + + initialize_eth_header(&lacpdu.eth_hdr, &src_mac, &dst_mac, + ETHER_TYPE_SLOW, 0, 0); + + for (i = 0; i < SLAVE_COUNT; i++) { + lacp_tx_buf[i] = rte_pktmbuf_alloc(test_params.mbuf_pool); + rte_memcpy(rte_pktmbuf_mtod(lacp_tx_buf[i], char *), + &lacpdu, sizeof(lacpdu)); + rte_pktmbuf_pkt_len(lacp_tx_buf[i]) = sizeof(lacpdu); + } + + retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 1); + TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device"); + + memset(lacpdu_rx_count, 0, sizeof(lacpdu_rx_count)); + + /* Wait for new settings to be applied. */ + for (i = 0; i < 30; ++i) + rte_delay_ms(delay); + + FOR_EACH_SLAVE(i, slave) { + retval = rte_eth_bond_8023ad_ext_slowtx( + test_params.bonded_port_id, + slave->port_id, lacp_tx_buf[i]); + TEST_ASSERT_SUCCESS(retval, + "Slave should allow manual LACP xmit"); + } + + nb_pkts = bond_tx(NULL, 0); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets transmitted unexpectedly"); + + FOR_EACH_SLAVE(i, slave) { + nb_pkts = slave_get_pkts(slave, buf, RTE_DIM(buf)); + TEST_ASSERT_EQUAL(nb_pkts, 1, "found %u packets on slave %d\n", + nb_pkts, i); + slave_put_pkts(slave, buf, nb_pkts); + } + + nb_pkts = bond_rx(buf, RTE_DIM(buf)); + free_pkts(buf, nb_pkts); + TEST_ASSERT_EQUAL(nb_pkts, 0, "Packets received unexpectedly"); + + /* wait for the periodic callback to run */ + for (i = 0; i < 30 && all_slaves_done == 0; ++i) { + uint8_t s, total = 0; + + rte_delay_ms(delay); + FOR_EACH_SLAVE(s, slave) { + total += lacpdu_rx_count[slave->port_id]; + } + + if (total >= SLAVE_COUNT) + all_slaves_done = 1; + } + + FOR_EACH_SLAVE(i, slave) { + TEST_ASSERT_EQUAL(lacpdu_rx_count[slave->port_id], 1, + "Slave port %u should have received 1 lacpdu (count=%u)", + slave->port_id, + lacpdu_rx_count[slave->port_id]); + } + + retval = remove_slaves_and_stop_bonded_device(); + TEST_ASSERT_SUCCESS(retval, "Test cleanup failed."); + + return TEST_SUCCESS; +} + +static int check_environment(void) { struct slave_conf *port; @@ -1381,6 +1562,18 @@ test_mode4_expired_wrapper(void) return test_mode4_executor(&test_mode4_expired); } +static int +test_mode4_ext_ctrl_wrapper(void) +{ + return test_mode4_executor(&test_mode4_ext_ctrl); +} + +static int +test_mode4_ext_lacp_wrapper(void) +{ + return test_mode4_executor(&test_mode4_ext_lacp); +} + static struct unit_test_suite link_bonding_mode4_test_suite = { .suite_name = "Link Bonding mode 4 Unit Test Suite", .setup = test_setup, @@ -1391,6 +1584,10 @@ static struct unit_test_suite link_bonding_mode4_test_suite = { TEST_CASE_NAMED("test_mode4_tx_burst", test_mode4_tx_burst_wrapper), TEST_CASE_NAMED("test_mode4_marker", test_mode4_marker_wrapper), TEST_CASE_NAMED("test_mode4_expired", test_mode4_expired_wrapper), + TEST_CASE_NAMED("test_mode4_ext_ctrl", + test_mode4_ext_ctrl_wrapper), + TEST_CASE_NAMED("test_mode4_ext_lacp", + test_mode4_ext_lacp_wrapper), TEST_CASES_END() /**< NULL terminate unit test array */ } diff --git a/app/test/test_logs.c b/app/test/test_logs.c index 18a3b6aa..d0a99623 100644 --- a/app/test/test_logs.c +++ b/app/test/test_logs.c @@ -65,27 +65,23 @@ test_logs(void) rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1); rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 1); - /* log in debug level */ - rte_set_log_level(RTE_LOG_DEBUG); - RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n"); - RTE_LOG(INFO, TESTAPP1, "this is a info level message\n"); - RTE_LOG(WARNING, TESTAPP1, "this is a warning level message\n"); + /* log in error level */ + rte_set_log_level(RTE_LOG_ERR); + RTE_LOG(ERR, TESTAPP1, "error message\n"); + RTE_LOG(CRIT, TESTAPP1, "critical message\n"); - /* log in info level */ - rte_set_log_level(RTE_LOG_INFO); - RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n"); - RTE_LOG(INFO, TESTAPP2, "this is a info level message\n"); - RTE_LOG(WARNING, TESTAPP2, "this is a warning level message\n"); + /* log in critical level */ + rte_set_log_level(RTE_LOG_CRIT); + RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); + RTE_LOG(CRIT, TESTAPP2, "critical message\n"); /* disable one log type */ rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 0); - /* log in debug level */ - rte_set_log_level(RTE_LOG_DEBUG); - RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n"); - RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n"); - - rte_log_dump_history(stdout); + /* log in error level */ + rte_set_log_level(RTE_LOG_ERR); + RTE_LOG(ERR, TESTAPP1, "error message\n"); + RTE_LOG(ERR, TESTAPP2, "error message (not displayed)\n"); return 0; } diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c index 40fbbc65..f6930fbd 100644 --- a/app/test/test_lpm.c +++ b/app/test/test_lpm.c @@ -34,20 +34,10 @@ #include <stdio.h> #include <stdint.h> #include <stdlib.h> -#include <errno.h> -#include <sys/queue.h> -#include <rte_common.h> -#include <rte_cycles.h> -#include <rte_memory.h> -#include <rte_random.h> -#include <rte_branch_prediction.h> -#include <rte_ip.h> -#include <time.h> +#include <rte_lpm.h> #include "test.h" - -#include "rte_lpm.h" #include "test_lpm_routes.h" #include "test_xmmt_ops.h" @@ -78,7 +68,6 @@ static int32_t test14(void); static int32_t test15(void); static int32_t test16(void); static int32_t test17(void); -static int32_t perf_test(void); rte_lpm_test tests[] = { /* Test Cases */ @@ -100,7 +89,6 @@ rte_lpm_test tests[] = { test15, test16, test17, - perf_test, }; #define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0])) @@ -1230,202 +1218,7 @@ test17(void) } /* - * Lookup performance test - */ - -#define ITERATIONS (1 << 10) -#define BATCH_SIZE (1 << 12) -#define BULK_SIZE 32 - -static void -print_route_distribution(const struct route_rule *table, uint32_t n) -{ - unsigned i, j; - - printf("Route distribution per prefix width: \n"); - printf("DEPTH QUANTITY (PERCENT)\n"); - printf("--------------------------- \n"); - - /* Count depths. */ - for (i = 1; i <= 32; i++) { - unsigned depth_counter = 0; - double percent_hits; - - for (j = 0; j < n; j++) - if (table[j].depth == (uint8_t) i) - depth_counter++; - - percent_hits = ((double)depth_counter)/((double)n) * 100; - printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); - } - printf("\n"); -} - -int32_t -perf_test(void) -{ - struct rte_lpm *lpm = NULL; - struct rte_lpm_config config; - - config.max_rules = 1000000; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - uint64_t begin, total_time, lpm_used_entries = 0; - unsigned i, j; - uint32_t next_hop_add = 0xAA, next_hop_return = 0; - int status = 0; - uint64_t cache_line_counter = 0; - int64_t count = 0; - - rte_srand(rte_rdtsc()); - - printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES); - - print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES); - - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Measue add. */ - begin = rte_rdtsc(); - - for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { - if (rte_lpm_add(lpm, large_route_table[i].ip, - large_route_table[i].depth, next_hop_add) == 0) - status++; - } - /* End Timer. */ - total_time = rte_rdtsc() - begin; - - printf("Unique added entries = %d\n", status); - /* Obtain add statistics. */ - for (i = 0; i < RTE_LPM_TBL24_NUM_ENTRIES; i++) { - if (lpm->tbl24[i].valid) - lpm_used_entries++; - - if (i % 32 == 0) { - if ((uint64_t)count < lpm_used_entries) { - cache_line_counter++; - count = lpm_used_entries; - } - } - } - - printf("Used table 24 entries = %u (%g%%)\n", - (unsigned) lpm_used_entries, - (lpm_used_entries * 100.0) / RTE_LPM_TBL24_NUM_ENTRIES); - printf("64 byte Cache entries used = %u (%u bytes)\n", - (unsigned) cache_line_counter, (unsigned) cache_line_counter * 64); - - printf("Average LPM Add: %g cycles\n", - (double)total_time / NUM_ROUTE_ENTRIES); - - /* Measure single Lookup */ - total_time = 0; - count = 0; - - for (i = 0; i < ITERATIONS; i++) { - static uint32_t ip_batch[BATCH_SIZE]; - - for (j = 0; j < BATCH_SIZE; j++) - ip_batch[j] = rte_rand(); - - /* Lookup per batch */ - begin = rte_rdtsc(); - - for (j = 0; j < BATCH_SIZE; j++) { - if (rte_lpm_lookup(lpm, ip_batch[j], &next_hop_return) != 0) - count++; - } - - total_time += rte_rdtsc() - begin; - - } - printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n", - (double)total_time / ((double)ITERATIONS * BATCH_SIZE), - (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); - - /* Measure bulk Lookup */ - total_time = 0; - count = 0; - for (i = 0; i < ITERATIONS; i++) { - static uint32_t ip_batch[BATCH_SIZE]; - uint32_t next_hops[BULK_SIZE]; - - /* Create array of random IP addresses */ - for (j = 0; j < BATCH_SIZE; j++) - ip_batch[j] = rte_rand(); - - /* Lookup per batch */ - begin = rte_rdtsc(); - for (j = 0; j < BATCH_SIZE; j += BULK_SIZE) { - unsigned k; - rte_lpm_lookup_bulk(lpm, &ip_batch[j], next_hops, BULK_SIZE); - for (k = 0; k < BULK_SIZE; k++) - if (unlikely(!(next_hops[k] & RTE_LPM_LOOKUP_SUCCESS))) - count++; - } - - total_time += rte_rdtsc() - begin; - } - printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n", - (double)total_time / ((double)ITERATIONS * BATCH_SIZE), - (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); - - /* Measure LookupX4 */ - total_time = 0; - count = 0; - for (i = 0; i < ITERATIONS; i++) { - static uint32_t ip_batch[BATCH_SIZE]; - uint32_t next_hops[4]; - - /* Create array of random IP addresses */ - for (j = 0; j < BATCH_SIZE; j++) - ip_batch[j] = rte_rand(); - - /* Lookup per batch */ - begin = rte_rdtsc(); - for (j = 0; j < BATCH_SIZE; j += RTE_DIM(next_hops)) { - unsigned k; - xmm_t ipx4; - - ipx4 = vect_loadu_sil128((xmm_t *)(ip_batch + j)); - ipx4 = *(xmm_t *)(ip_batch + j); - rte_lpm_lookupx4(lpm, ipx4, next_hops, UINT32_MAX); - for (k = 0; k < RTE_DIM(next_hops); k++) - if (unlikely(next_hops[k] == UINT32_MAX)) - count++; - } - - total_time += rte_rdtsc() - begin; - } - printf("LPM LookupX4: %.1f cycles (fails = %.1f%%)\n", - (double)total_time / ((double)ITERATIONS * BATCH_SIZE), - (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); - - /* Delete */ - status = 0; - begin = rte_rdtsc(); - - for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { - /* rte_lpm_delete(lpm, ip, depth) */ - status += rte_lpm_delete(lpm, large_route_table[i].ip, - large_route_table[i].depth); - } - - total_time += rte_rdtsc() - begin; - - printf("Average LPM Delete: %g cycles\n", - (double)total_time / NUM_ROUTE_ENTRIES); - - rte_lpm_delete_all(lpm); - rte_lpm_free(lpm); - - return PASS; -} - -/* - * Do all unit and performance tests. + * Do all unit tests. */ static int diff --git a/app/test/test_lpm6.c b/app/test/test_lpm6.c index b464342c..458a10bf 100644 --- a/app/test/test_lpm6.c +++ b/app/test/test_lpm6.c @@ -30,25 +30,16 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <errno.h> -#include <sys/queue.h> - -#include <time.h> -#include "test.h" - -#include <rte_common.h> -#include <rte_cycles.h> #include <rte_memory.h> -#include <rte_random.h> -#include <rte_branch_prediction.h> -#include <rte_ip.h> +#include <rte_lpm6.h> -#include "rte_lpm6.h" +#include "test.h" #include "test_lpm6_routes.h" #define TEST_LPM_ASSERT(cond) do { \ @@ -88,7 +79,6 @@ static int32_t test24(void); static int32_t test25(void); static int32_t test26(void); static int32_t test27(void); -static int32_t perf_test(void); rte_lpm6_test tests6[] = { /* Test Cases */ @@ -120,12 +110,9 @@ rte_lpm6_test tests6[] = { test25, test26, test27, - perf_test, }; #define NUM_LPM6_TESTS (sizeof(tests6)/sizeof(tests6[0])) -#define RTE_LPM6_TBL24_NUM_ENTRIES (1 << 24) -#define RTE_LPM6_LOOKUP_SUCCESS 0x04000000 #define MAX_DEPTH 128 #define MAX_RULES 1000000 #define NUMBER_TBL8S (1 << 16) @@ -231,7 +218,7 @@ test1(void) } /* - * Create lpm table then delete lpm table 100 times + * Create lpm table then delete lpm table 20 times * Use a slightly different rules size each time */ int32_t @@ -245,7 +232,7 @@ test2(void) config.flags = 0; /* rte_lpm6_free: Free NULL */ - for (i = 0; i < 100; i++) { + for (i = 0; i < 20; i++) { config.max_rules = MAX_RULES - i; lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); TEST_LPM_ASSERT(lpm != NULL); @@ -704,7 +691,7 @@ test13(void) } /* - * Add 2^16 routes with different first 16 bits and depth 25. + * Add 2^12 routes with different first 12 bits and depth 25. * Add one more route with the same depth and check that results in a failure. * After that delete the last rule and create the one that was attempted to be * created. This checks tbl8 exhaustion. @@ -717,10 +704,10 @@ test14(void) uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t depth = 25, next_hop_add = 100; int32_t status = 0; - int i, j; + int i; config.max_rules = MAX_RULES; - config.number_tbl8s = NUMBER_TBL8S; + config.number_tbl8s = 256; config.flags = 0; lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); @@ -728,28 +715,22 @@ test14(void) for (i = 0; i < 256; i++) { ip[0] = (uint8_t)i; - for (j = 0; j < 256; j++) { - ip[1] = (uint8_t)j; - status = rte_lpm6_add(lpm, ip, depth, next_hop_add); - TEST_LPM_ASSERT(status == 0); - } + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); } ip[0] = 255; - ip[1] = 255; - ip[2] = 1; + ip[1] = 1; status = rte_lpm6_add(lpm, ip, depth, next_hop_add); TEST_LPM_ASSERT(status == -ENOSPC); ip[0] = 255; - ip[1] = 255; - ip[2] = 0; + ip[1] = 0; status = rte_lpm6_delete(lpm, ip, depth); TEST_LPM_ASSERT(status == 0); ip[0] = 255; - ip[1] = 255; - ip[2] = 1; + ip[1] = 1; status = rte_lpm6_add(lpm, ip, depth, next_hop_add); TEST_LPM_ASSERT(status == 0); @@ -858,7 +839,7 @@ test17(void) TEST_LPM_ASSERT(lpm != NULL); /* Loop with rte_lpm6_add. */ - for (depth = 1; depth <= 128; depth++) { + for (depth = 1; depth <= 16; depth++) { /* Let the next_hop_add value = depth. Just for change. */ next_hop_add = depth; @@ -875,7 +856,7 @@ test17(void) } /* Loop with rte_lpm6_delete. */ - for (depth = 128; depth >= 1; depth--) { + for (depth = 16; depth >= 1; depth--) { next_hop_add = (uint8_t) (depth - 1); status = rte_lpm6_delete(lpm, ip2, depth); @@ -1504,7 +1485,7 @@ test22(void) /* * Add an extended rule (i.e. depth greater than 24, lookup (hit), delete, - * lookup (miss) in a for loop of 1000 times. This will check tbl8 extension + * lookup (miss) in a for loop of 30 times. This will check tbl8 extension * and contraction. */ int32_t @@ -1528,7 +1509,7 @@ test23(void) depth = 128; next_hop_add = 100; - for (i = 0; i < 1000; i++) { + for (i = 0; i < 30; i++) { status = rte_lpm6_add(lpm, ip, depth, next_hop_add); TEST_LPM_ASSERT(status == 0); @@ -1762,143 +1743,7 @@ test27(void) } /* - * Lookup performance test - */ - -#define ITERATIONS (1 << 10) -#define BATCH_SIZE 100000 - -static void -print_route_distribution(const struct rules_tbl_entry *table, uint32_t n) -{ - unsigned i, j; - - printf("Route distribution per prefix width: \n"); - printf("DEPTH QUANTITY (PERCENT)\n"); - printf("--------------------------- \n"); - - /* Count depths. */ - for(i = 1; i <= 128; i++) { - unsigned depth_counter = 0; - double percent_hits; - - for (j = 0; j < n; j++) - if (table[j].depth == (uint8_t) i) - depth_counter++; - - percent_hits = ((double)depth_counter)/((double)n) * 100; - printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); - } - printf("\n"); -} - -int32_t -perf_test(void) -{ - struct rte_lpm6 *lpm = NULL; - struct rte_lpm6_config config; - uint64_t begin, total_time; - unsigned i, j; - uint8_t next_hop_add = 0xAA, next_hop_return = 0; - int status = 0; - int64_t count = 0; - - config.max_rules = 1000000; - config.number_tbl8s = NUMBER_TBL8S; - config.flags = 0; - - rte_srand(rte_rdtsc()); - - printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES); - - print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES); - - lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Measure add. */ - begin = rte_rdtsc(); - - for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { - if (rte_lpm6_add(lpm, large_route_table[i].ip, - large_route_table[i].depth, next_hop_add) == 0) - status++; - } - /* End Timer. */ - total_time = rte_rdtsc() - begin; - - printf("Unique added entries = %d\n", status); - printf("Average LPM Add: %g cycles\n", - (double)total_time / NUM_ROUTE_ENTRIES); - - /* Measure single Lookup */ - total_time = 0; - count = 0; - - for (i = 0; i < ITERATIONS; i ++) { - begin = rte_rdtsc(); - - for (j = 0; j < NUM_IPS_ENTRIES; j ++) { - if (rte_lpm6_lookup(lpm, large_ips_table[j].ip, - &next_hop_return) != 0) - count++; - } - - total_time += rte_rdtsc() - begin; - - } - printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n", - (double)total_time / ((double)ITERATIONS * BATCH_SIZE), - (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); - - /* Measure bulk Lookup */ - total_time = 0; - count = 0; - - uint8_t ip_batch[NUM_IPS_ENTRIES][16]; - int16_t next_hops[NUM_IPS_ENTRIES]; - - for (i = 0; i < NUM_IPS_ENTRIES; i++) - memcpy(ip_batch[i], large_ips_table[i].ip, 16); - - for (i = 0; i < ITERATIONS; i ++) { - - /* Lookup per batch */ - begin = rte_rdtsc(); - rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES); - total_time += rte_rdtsc() - begin; - - for (j = 0; j < NUM_IPS_ENTRIES; j++) - if (next_hops[j] < 0) - count++; - } - printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n", - (double)total_time / ((double)ITERATIONS * BATCH_SIZE), - (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); - - /* Delete */ - status = 0; - begin = rte_rdtsc(); - - for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { - /* rte_lpm_delete(lpm, ip, depth) */ - status += rte_lpm6_delete(lpm, large_route_table[i].ip, - large_route_table[i].depth); - } - - total_time += rte_rdtsc() - begin; - - printf("Average LPM Delete: %g cycles\n", - (double)total_time / NUM_ROUTE_ENTRIES); - - rte_lpm6_delete_all(lpm); - rte_lpm6_free(lpm); - - return PASS; -} - -/* - * Do all unit and performance tests. + * Do all unit tests. */ static int test_lpm6(void) @@ -1907,6 +1752,7 @@ test_lpm6(void) int status = -1, global_status = 0; for (i = 0; i < NUM_LPM6_TESTS; i++) { + printf("# test %02d\n", i); status = tests6[i](); if (status < 0) { diff --git a/app/test/test_lpm6_perf.c b/app/test/test_lpm6_perf.c new file mode 100644 index 00000000..b7d46314 --- /dev/null +++ b/app/test/test_lpm6_perf.c @@ -0,0 +1,191 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <rte_cycles.h> +#include <rte_random.h> +#include <rte_memory.h> +#include <rte_lpm6.h> + +#include "test.h" +#include "test_lpm6_routes.h" + +#define TEST_LPM_ASSERT(cond) do { \ + if (!(cond)) { \ + printf("Error at line %d: \n", __LINE__); \ + return -1; \ + } \ +} while(0) + +#define ITERATIONS (1 << 10) +#define BATCH_SIZE 100000 +#define NUMBER_TBL8S (1 << 16) + +static void +print_route_distribution(const struct rules_tbl_entry *table, uint32_t n) +{ + unsigned i, j; + + printf("Route distribution per prefix width: \n"); + printf("DEPTH QUANTITY (PERCENT)\n"); + printf("--------------------------- \n"); + + /* Count depths. */ + for(i = 1; i <= 128; i++) { + unsigned depth_counter = 0; + double percent_hits; + + for (j = 0; j < n; j++) + if (table[j].depth == (uint8_t) i) + depth_counter++; + + percent_hits = ((double)depth_counter)/((double)n) * 100; + printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); + } + printf("\n"); +} + +static int +test_lpm6_perf(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint64_t begin, total_time; + unsigned i, j; + uint8_t next_hop_add = 0xAA, next_hop_return = 0; + int status = 0; + int64_t count = 0; + + config.max_rules = 1000000; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + rte_srand(rte_rdtsc()); + + printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES); + + print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES); + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Measure add. */ + begin = rte_rdtsc(); + + for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { + if (rte_lpm6_add(lpm, large_route_table[i].ip, + large_route_table[i].depth, next_hop_add) == 0) + status++; + } + /* End Timer. */ + total_time = rte_rdtsc() - begin; + + printf("Unique added entries = %d\n", status); + printf("Average LPM Add: %g cycles\n", + (double)total_time / NUM_ROUTE_ENTRIES); + + /* Measure single Lookup */ + total_time = 0; + count = 0; + + for (i = 0; i < ITERATIONS; i ++) { + begin = rte_rdtsc(); + + for (j = 0; j < NUM_IPS_ENTRIES; j ++) { + if (rte_lpm6_lookup(lpm, large_ips_table[j].ip, + &next_hop_return) != 0) + count++; + } + + total_time += rte_rdtsc() - begin; + + } + printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n", + (double)total_time / ((double)ITERATIONS * BATCH_SIZE), + (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); + + /* Measure bulk Lookup */ + total_time = 0; + count = 0; + + uint8_t ip_batch[NUM_IPS_ENTRIES][16]; + int16_t next_hops[NUM_IPS_ENTRIES]; + + for (i = 0; i < NUM_IPS_ENTRIES; i++) + memcpy(ip_batch[i], large_ips_table[i].ip, 16); + + for (i = 0; i < ITERATIONS; i ++) { + + /* Lookup per batch */ + begin = rte_rdtsc(); + rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES); + total_time += rte_rdtsc() - begin; + + for (j = 0; j < NUM_IPS_ENTRIES; j++) + if (next_hops[j] < 0) + count++; + } + printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n", + (double)total_time / ((double)ITERATIONS * BATCH_SIZE), + (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); + + /* Delete */ + status = 0; + begin = rte_rdtsc(); + + for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { + /* rte_lpm_delete(lpm, ip, depth) */ + status += rte_lpm6_delete(lpm, large_route_table[i].ip, + large_route_table[i].depth); + } + + total_time += rte_rdtsc() - begin; + + printf("Average LPM Delete: %g cycles\n", + (double)total_time / NUM_ROUTE_ENTRIES); + + rte_lpm6_delete_all(lpm); + rte_lpm6_free(lpm); + + return 0; +} + +static struct test_command lpm6_perf_cmd = { + .command = "lpm6_perf_autotest", + .callback = test_lpm6_perf, +}; +REGISTER_TEST_COMMAND(lpm6_perf_cmd); diff --git a/app/test/test_lpm_perf.c b/app/test/test_lpm_perf.c new file mode 100644 index 00000000..41da811c --- /dev/null +++ b/app/test/test_lpm_perf.c @@ -0,0 +1,249 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + +#include <rte_cycles.h> +#include <rte_random.h> +#include <rte_branch_prediction.h> +#include <rte_lpm.h> + +#include "test.h" +#include "test_lpm_routes.h" +#include "test_xmmt_ops.h" + +#define TEST_LPM_ASSERT(cond) do { \ + if (!(cond)) { \ + printf("Error at line %d: \n", __LINE__); \ + return -1; \ + } \ +} while(0) + +#define ITERATIONS (1 << 10) +#define BATCH_SIZE (1 << 12) +#define BULK_SIZE 32 + +static void +print_route_distribution(const struct route_rule *table, uint32_t n) +{ + unsigned i, j; + + printf("Route distribution per prefix width: \n"); + printf("DEPTH QUANTITY (PERCENT)\n"); + printf("--------------------------- \n"); + + /* Count depths. */ + for (i = 1; i <= 32; i++) { + unsigned depth_counter = 0; + double percent_hits; + + for (j = 0; j < n; j++) + if (table[j].depth == (uint8_t) i) + depth_counter++; + + percent_hits = ((double)depth_counter)/((double)n) * 100; + printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); + } + printf("\n"); +} + +static int +test_lpm_perf(void) +{ + struct rte_lpm *lpm = NULL; + struct rte_lpm_config config; + + config.max_rules = 1000000; + config.number_tbl8s = 256; + config.flags = 0; + uint64_t begin, total_time, lpm_used_entries = 0; + unsigned i, j; + uint32_t next_hop_add = 0xAA, next_hop_return = 0; + int status = 0; + uint64_t cache_line_counter = 0; + int64_t count = 0; + + rte_srand(rte_rdtsc()); + + printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES); + + print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES); + + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Measue add. */ + begin = rte_rdtsc(); + + for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { + if (rte_lpm_add(lpm, large_route_table[i].ip, + large_route_table[i].depth, next_hop_add) == 0) + status++; + } + /* End Timer. */ + total_time = rte_rdtsc() - begin; + + printf("Unique added entries = %d\n", status); + /* Obtain add statistics. */ + for (i = 0; i < RTE_LPM_TBL24_NUM_ENTRIES; i++) { + if (lpm->tbl24[i].valid) + lpm_used_entries++; + + if (i % 32 == 0) { + if ((uint64_t)count < lpm_used_entries) { + cache_line_counter++; + count = lpm_used_entries; + } + } + } + + printf("Used table 24 entries = %u (%g%%)\n", + (unsigned) lpm_used_entries, + (lpm_used_entries * 100.0) / RTE_LPM_TBL24_NUM_ENTRIES); + printf("64 byte Cache entries used = %u (%u bytes)\n", + (unsigned) cache_line_counter, (unsigned) cache_line_counter * 64); + + printf("Average LPM Add: %g cycles\n", + (double)total_time / NUM_ROUTE_ENTRIES); + + /* Measure single Lookup */ + total_time = 0; + count = 0; + + for (i = 0; i < ITERATIONS; i++) { + static uint32_t ip_batch[BATCH_SIZE]; + + for (j = 0; j < BATCH_SIZE; j++) + ip_batch[j] = rte_rand(); + + /* Lookup per batch */ + begin = rte_rdtsc(); + + for (j = 0; j < BATCH_SIZE; j++) { + if (rte_lpm_lookup(lpm, ip_batch[j], &next_hop_return) != 0) + count++; + } + + total_time += rte_rdtsc() - begin; + + } + printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n", + (double)total_time / ((double)ITERATIONS * BATCH_SIZE), + (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); + + /* Measure bulk Lookup */ + total_time = 0; + count = 0; + for (i = 0; i < ITERATIONS; i++) { + static uint32_t ip_batch[BATCH_SIZE]; + uint32_t next_hops[BULK_SIZE]; + + /* Create array of random IP addresses */ + for (j = 0; j < BATCH_SIZE; j++) + ip_batch[j] = rte_rand(); + + /* Lookup per batch */ + begin = rte_rdtsc(); + for (j = 0; j < BATCH_SIZE; j += BULK_SIZE) { + unsigned k; + rte_lpm_lookup_bulk(lpm, &ip_batch[j], next_hops, BULK_SIZE); + for (k = 0; k < BULK_SIZE; k++) + if (unlikely(!(next_hops[k] & RTE_LPM_LOOKUP_SUCCESS))) + count++; + } + + total_time += rte_rdtsc() - begin; + } + printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n", + (double)total_time / ((double)ITERATIONS * BATCH_SIZE), + (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); + + /* Measure LookupX4 */ + total_time = 0; + count = 0; + for (i = 0; i < ITERATIONS; i++) { + static uint32_t ip_batch[BATCH_SIZE]; + uint32_t next_hops[4]; + + /* Create array of random IP addresses */ + for (j = 0; j < BATCH_SIZE; j++) + ip_batch[j] = rte_rand(); + + /* Lookup per batch */ + begin = rte_rdtsc(); + for (j = 0; j < BATCH_SIZE; j += RTE_DIM(next_hops)) { + unsigned k; + xmm_t ipx4; + + ipx4 = vect_loadu_sil128((xmm_t *)(ip_batch + j)); + ipx4 = *(xmm_t *)(ip_batch + j); + rte_lpm_lookupx4(lpm, ipx4, next_hops, UINT32_MAX); + for (k = 0; k < RTE_DIM(next_hops); k++) + if (unlikely(next_hops[k] == UINT32_MAX)) + count++; + } + + total_time += rte_rdtsc() - begin; + } + printf("LPM LookupX4: %.1f cycles (fails = %.1f%%)\n", + (double)total_time / ((double)ITERATIONS * BATCH_SIZE), + (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); + + /* Delete */ + status = 0; + begin = rte_rdtsc(); + + for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { + /* rte_lpm_delete(lpm, ip, depth) */ + status += rte_lpm_delete(lpm, large_route_table[i].ip, + large_route_table[i].depth); + } + + total_time += rte_rdtsc() - begin; + + printf("Average LPM Delete: %g cycles\n", + (double)total_time / NUM_ROUTE_ENTRIES); + + rte_lpm_delete_all(lpm); + rte_lpm_free(lpm); + + return 0; +} + +static struct test_command lpm_perf_cmd = { + .command = "lpm_perf_autotest", + .callback = test_lpm_perf, +}; +REGISTER_TEST_COMMAND(lpm_perf_cmd); diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c index 98ff93af..8664885d 100644 --- a/app/test/test_mbuf.c +++ b/app/test/test_mbuf.c @@ -511,10 +511,14 @@ test_attach_from_different_pool(void) rte_pktmbuf_detach(clone); if (c_data != rte_pktmbuf_mtod(clone, char *)) GOTO_FAIL("clone was not detached properly\n"); + if (rte_mbuf_refcnt_read(m) != 2) + GOTO_FAIL("invalid refcnt in m\n"); rte_pktmbuf_detach(clone2); if (c_data2 != rte_pktmbuf_mtod(clone2, char *)) GOTO_FAIL("clone2 was not detached properly\n"); + if (rte_mbuf_refcnt_read(m) != 1) + GOTO_FAIL("invalid refcnt in m\n"); /* free the clones and the initial mbuf */ rte_pktmbuf_free(clone2); @@ -713,7 +717,7 @@ test_refcnt_iter(unsigned lcore, unsigned iter) * - increment it's reference up to N+1, * - enqueue it N times into the ring for slave cores to free. */ - for (i = 0, n = rte_mempool_count(refcnt_pool); + for (i = 0, n = rte_mempool_avail_count(refcnt_pool); i != n && (m = rte_pktmbuf_alloc(refcnt_pool)) != NULL; i++) { ref = RTE_MAX(rte_rand() % REFCNT_MAX_REF, 1UL); @@ -741,14 +745,14 @@ test_refcnt_iter(unsigned lcore, unsigned iter) /* check that all mbufs are back into mempool by now */ for (wn = 0; wn != REFCNT_MAX_TIMEOUT; wn++) { - if ((i = rte_mempool_count(refcnt_pool)) == n) { + if ((i = rte_mempool_avail_count(refcnt_pool)) == n) { refcnt_lcore[lcore] += tref; printf("%s(lcore=%u, iter=%u) completed, " "%u references processed\n", __func__, lcore, iter, tref); return; } - rte_delay_ms(1000); + rte_delay_ms(100); } rte_panic("(lcore=%u, iter=%u): after %us only " diff --git a/app/test/test_memcpy.c b/app/test/test_memcpy.c index b2bb4e0e..8195e209 100644 --- a/app/test/test_memcpy.c +++ b/app/test/test_memcpy.c @@ -37,10 +37,7 @@ #include <stdlib.h> #include <rte_common.h> -#include <rte_cycles.h> #include <rte_random.h> -#include <rte_malloc.h> - #include <rte_memcpy.h> #include "test.h" @@ -65,18 +62,6 @@ static size_t buf_sizes[TEST_VALUE_RANGE]; #define SMALL_BUFFER_SIZE TEST_VALUE_RANGE #endif /* TEST_VALUE_RANGE == 0 */ - -/* - * Arrays of this size are used for measuring uncached memory accesses by - * picking a random location within the buffer. Make this smaller if there are - * memory allocation errors. - */ -#define LARGE_BUFFER_SIZE (100 * 1024 * 1024) - -/* How many times to run timing loop for performance tests */ -#define TEST_ITERATIONS 1000000 -#define TEST_BATCH_SIZE 100 - /* Data is aligned on this many bytes (power of 2) */ #define ALIGNMENT_UNIT 32 diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c index f0f823b9..9ea98314 100644 --- a/app/test/test_mempool.c +++ b/app/test/test_mempool.c @@ -71,19 +71,23 @@ * put them back in the pool. */ -#define N 65536 -#define TIME_S 5 #define MEMPOOL_ELT_SIZE 2048 -#define MAX_KEEP 128 +#define MAX_KEEP 16 #define MEMPOOL_SIZE ((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE))-1) -static struct rte_mempool *mp; -static struct rte_mempool *mp_cache, *mp_nocache; +#define LOG_ERR() printf("test failed at %s():%d\n", __func__, __LINE__) +#define RET_ERR() do { \ + LOG_ERR(); \ + return -1; \ + } while (0) +#define GOTO_ERR(var, label) do { \ + LOG_ERR(); \ + var = -1; \ + goto label; \ + } while (0) static rte_atomic32_t synchro; - - /* * save the object number in the first 4 bytes of object data. All * other bytes are set to 0. @@ -93,13 +97,14 @@ my_obj_init(struct rte_mempool *mp, __attribute__((unused)) void *arg, void *obj, unsigned i) { uint32_t *objnum = obj; + memset(obj, 0, mp->elt_size); *objnum = i; } /* basic tests (done on one core) */ static int -test_mempool_basic(void) +test_mempool_basic(struct rte_mempool *mp, int use_external_cache) { uint32_t *objnum; void **objtable; @@ -107,48 +112,62 @@ test_mempool_basic(void) char *obj_data; int ret = 0; unsigned i, j; + int offset; + struct rte_mempool_cache *cache; + + if (use_external_cache) { + /* Create a user-owned mempool cache. */ + cache = rte_mempool_cache_create(RTE_MEMPOOL_CACHE_MAX_SIZE, + SOCKET_ID_ANY); + if (cache == NULL) + RET_ERR(); + } else { + /* May be NULL if cache is disabled. */ + cache = rte_mempool_default_cache(mp, rte_lcore_id()); + } /* dump the mempool status */ rte_mempool_dump(stdout, mp); printf("get an object\n"); - if (rte_mempool_get(mp, &obj) < 0) - return -1; + if (rte_mempool_generic_get(mp, &obj, 1, cache, 0) < 0) + GOTO_ERR(ret, out); rte_mempool_dump(stdout, mp); /* tests that improve coverage */ printf("get object count\n"); - if (rte_mempool_count(mp) != MEMPOOL_SIZE - 1) - return -1; + /* We have to count the extra caches, one in this case. */ + offset = use_external_cache ? 1 * cache->len : 0; + if (rte_mempool_avail_count(mp) + offset != MEMPOOL_SIZE - 1) + GOTO_ERR(ret, out); printf("get private data\n"); - if (rte_mempool_get_priv(mp) != - (char*) mp + MEMPOOL_HEADER_SIZE(mp, mp->pg_num)) - return -1; + if (rte_mempool_get_priv(mp) != (char *)mp + + MEMPOOL_HEADER_SIZE(mp, mp->cache_size)) + GOTO_ERR(ret, out); +#ifndef RTE_EXEC_ENV_BSDAPP /* rte_mem_virt2phy() not supported on bsd */ printf("get physical address of an object\n"); - if (MEMPOOL_IS_CONTIG(mp) && - rte_mempool_virt2phy(mp, obj) != - (phys_addr_t) (mp->phys_addr + - (phys_addr_t) ((char*) obj - (char*) mp))) - return -1; + if (rte_mempool_virt2phy(mp, obj) != rte_mem_virt2phy(obj)) + GOTO_ERR(ret, out); +#endif printf("put the object back\n"); - rte_mempool_put(mp, obj); + rte_mempool_generic_put(mp, &obj, 1, cache, 0); rte_mempool_dump(stdout, mp); printf("get 2 objects\n"); - if (rte_mempool_get(mp, &obj) < 0) - return -1; - if (rte_mempool_get(mp, &obj2) < 0) { - rte_mempool_put(mp, obj); - return -1; + if (rte_mempool_generic_get(mp, &obj, 1, cache, 0) < 0) + GOTO_ERR(ret, out); + if (rte_mempool_generic_get(mp, &obj2, 1, cache, 0) < 0) { + rte_mempool_generic_put(mp, &obj, 1, cache, 0); + GOTO_ERR(ret, out); } rte_mempool_dump(stdout, mp); printf("put the objects back\n"); - rte_mempool_put(mp, obj); - rte_mempool_put(mp, obj2); + rte_mempool_generic_put(mp, &obj, 1, cache, 0); + rte_mempool_generic_put(mp, &obj2, 1, cache, 0); rte_mempool_dump(stdout, mp); /* @@ -156,12 +175,11 @@ test_mempool_basic(void) * on other cores may not be empty. */ objtable = malloc(MEMPOOL_SIZE * sizeof(void *)); - if (objtable == NULL) { - return -1; - } + if (objtable == NULL) + GOTO_ERR(ret, out); - for (i=0; i<MEMPOOL_SIZE; i++) { - if (rte_mempool_get(mp, &objtable[i]) < 0) + for (i = 0; i < MEMPOOL_SIZE; i++) { + if (rte_mempool_generic_get(mp, &objtable[i], 1, cache, 0) < 0) break; } @@ -174,22 +192,28 @@ test_mempool_basic(void) obj_data = obj; objnum = obj; if (*objnum > MEMPOOL_SIZE) { - printf("bad object number\n"); + printf("bad object number(%d)\n", *objnum); ret = -1; break; } - for (j=sizeof(*objnum); j<mp->elt_size; j++) { + for (j = sizeof(*objnum); j < mp->elt_size; j++) { if (obj_data[j] != 0) ret = -1; } - rte_mempool_put(mp, objtable[i]); + rte_mempool_generic_put(mp, &objtable[i], 1, cache, 0); } free(objtable); if (ret == -1) printf("objects were modified!\n"); +out: + if (use_external_cache) { + rte_mempool_cache_flush(cache, mp); + rte_mempool_cache_free(cache); + } + return ret; } @@ -197,14 +221,17 @@ static int test_mempool_creation_with_exceeded_cache_size(void) { struct rte_mempool *mp_cov; - mp_cov = rte_mempool_create("test_mempool_creation_with_exceeded_cache_size", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, - RTE_MEMPOOL_CACHE_MAX_SIZE + 32, 0, - NULL, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, 0); - if(NULL != mp_cov) { - return -1; + mp_cov = rte_mempool_create("test_mempool_cache_too_big", + MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, + RTE_MEMPOOL_CACHE_MAX_SIZE + 32, 0, + NULL, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, 0); + + if (mp_cov != NULL) { + rte_mempool_free(mp_cov); + RET_ERR(); } return 0; @@ -222,7 +249,7 @@ static int test_mempool_single_producer(void) unsigned int i; void *obj = NULL; uint64_t start_cycles, end_cycles; - uint64_t duration = rte_get_timer_hz() * 8; + uint64_t duration = rte_get_timer_hz() / 4; start_cycles = rte_get_timer_cycles(); while (1) { @@ -242,10 +269,10 @@ static int test_mempool_single_producer(void) continue; } if (rte_mempool_from_obj(obj) != mp_spsc) { - printf("test_mempool_single_producer there is an obj not owned by this mempool\n"); - return -1; + printf("obj not owned by this mempool\n"); + RET_ERR(); } - rte_mempool_sp_put(mp_spsc, obj); + rte_mempool_put(mp_spsc, obj); rte_spinlock_lock(&scsp_spinlock); scsp_obj_table[i] = NULL; rte_spinlock_unlock(&scsp_spinlock); @@ -262,7 +289,7 @@ static int test_mempool_single_consumer(void) unsigned int i; void * obj; uint64_t start_cycles, end_cycles; - uint64_t duration = rte_get_timer_hz() * 5; + uint64_t duration = rte_get_timer_hz() / 8; start_cycles = rte_get_timer_cycles(); while (1) { @@ -278,7 +305,7 @@ static int test_mempool_single_consumer(void) rte_spinlock_unlock(&scsp_spinlock); if (i >= MAX_KEEP) continue; - if (rte_mempool_sc_get(mp_spsc, &obj) < 0) + if (rte_mempool_get(mp_spsc, &obj) < 0) break; rte_spinlock_lock(&scsp_spinlock); scsp_obj_table[i] = obj; @@ -289,14 +316,17 @@ static int test_mempool_single_consumer(void) } /* - * test function for mempool test based on singple consumer and single producer, can run on one lcore only + * test function for mempool test based on singple consumer and single producer, + * can run on one lcore only */ -static int test_mempool_launch_single_consumer(__attribute__((unused)) void *arg) +static int +test_mempool_launch_single_consumer(__attribute__((unused)) void *arg) { return test_mempool_single_consumer(); } -static void my_mp_init(struct rte_mempool * mp, __attribute__((unused)) void * arg) +static void +my_mp_init(struct rte_mempool *mp, __attribute__((unused)) void *arg) { printf("mempool name is %s\n", mp->name); /* nothing to be implemented here*/ @@ -314,33 +344,41 @@ test_mempool_sp_sc(void) unsigned lcore_next; /* create a mempool with single producer/consumer ring */ - if (NULL == mp_spsc) { + if (mp_spsc == NULL) { mp_spsc = rte_mempool_create("test_mempool_sp_sc", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - my_mp_init, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, MEMPOOL_F_NO_CACHE_ALIGN | MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET); - if (NULL == mp_spsc) { - return -1; - } + MEMPOOL_ELT_SIZE, 0, 0, + my_mp_init, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, + MEMPOOL_F_NO_CACHE_ALIGN | MEMPOOL_F_SP_PUT | + MEMPOOL_F_SC_GET); + if (mp_spsc == NULL) + RET_ERR(); } if (rte_mempool_lookup("test_mempool_sp_sc") != mp_spsc) { printf("Cannot lookup mempool from its name\n"); - return -1; + rte_mempool_free(mp_spsc); + RET_ERR(); } lcore_next = rte_get_next_lcore(lcore_id, 0, 1); - if (RTE_MAX_LCORE <= lcore_next) - return -1; - if (rte_eal_lcore_role(lcore_next) != ROLE_RTE) - return -1; + if (lcore_next >= RTE_MAX_LCORE) { + rte_mempool_free(mp_spsc); + RET_ERR(); + } + if (rte_eal_lcore_role(lcore_next) != ROLE_RTE) { + rte_mempool_free(mp_spsc); + RET_ERR(); + } rte_spinlock_init(&scsp_spinlock); memset(scsp_obj_table, 0, sizeof(scsp_obj_table)); - rte_eal_remote_launch(test_mempool_launch_single_consumer, NULL, lcore_next); - if(test_mempool_single_producer() < 0) + rte_eal_remote_launch(test_mempool_launch_single_consumer, NULL, + lcore_next); + if (test_mempool_single_producer() < 0) ret = -1; - if(rte_eal_wait_lcore(lcore_next) < 0) + if (rte_eal_wait_lcore(lcore_next) < 0) ret = -1; + rte_mempool_free(mp_spsc); return ret; } @@ -349,7 +387,7 @@ test_mempool_sp_sc(void) * it tests some more basic of mempool */ static int -test_mempool_basic_ex(struct rte_mempool * mp) +test_mempool_basic_ex(struct rte_mempool *mp) { unsigned i; void **obj; @@ -359,38 +397,41 @@ test_mempool_basic_ex(struct rte_mempool * mp) if (mp == NULL) return ret; - obj = rte_calloc("test_mempool_basic_ex", MEMPOOL_SIZE , sizeof(void *), 0); + obj = rte_calloc("test_mempool_basic_ex", MEMPOOL_SIZE, + sizeof(void *), 0); if (obj == NULL) { printf("test_mempool_basic_ex fail to rte_malloc\n"); return ret; } - printf("test_mempool_basic_ex now mempool (%s) has %u free entries\n", mp->name, rte_mempool_free_count(mp)); + printf("test_mempool_basic_ex now mempool (%s) has %u free entries\n", + mp->name, rte_mempool_in_use_count(mp)); if (rte_mempool_full(mp) != 1) { - printf("test_mempool_basic_ex the mempool is not full but it should be\n"); + printf("test_mempool_basic_ex the mempool should be full\n"); goto fail_mp_basic_ex; } for (i = 0; i < MEMPOOL_SIZE; i ++) { - if (rte_mempool_mc_get(mp, &obj[i]) < 0) { - printf("fail_mp_basic_ex fail to get mempool object for [%u]\n", i); + if (rte_mempool_get(mp, &obj[i]) < 0) { + printf("test_mp_basic_ex fail to get object for [%u]\n", + i); goto fail_mp_basic_ex; } } - if (rte_mempool_mc_get(mp, &err_obj) == 0) { - printf("test_mempool_basic_ex get an impossible obj from mempool\n"); + if (rte_mempool_get(mp, &err_obj) == 0) { + printf("test_mempool_basic_ex get an impossible obj\n"); goto fail_mp_basic_ex; } printf("number: %u\n", i); if (rte_mempool_empty(mp) != 1) { - printf("test_mempool_basic_ex the mempool is not empty but it should be\n"); + printf("test_mempool_basic_ex the mempool should be empty\n"); goto fail_mp_basic_ex; } - for (i = 0; i < MEMPOOL_SIZE; i ++) { - rte_mempool_mp_put(mp, obj[i]); - } + for (i = 0; i < MEMPOOL_SIZE; i++) + rte_mempool_put(mp, obj[i]); + if (rte_mempool_full(mp) != 1) { - printf("test_mempool_basic_ex the mempool is not full but it should be\n"); + printf("test_mempool_basic_ex the mempool should be full\n"); goto fail_mp_basic_ex; } @@ -406,24 +447,30 @@ fail_mp_basic_ex: static int test_mempool_same_name_twice_creation(void) { - struct rte_mempool *mp_tc; - - mp_tc = rte_mempool_create("test_mempool_same_name_twice_creation", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - NULL, NULL, - NULL, NULL, - SOCKET_ID_ANY, 0); - if (NULL == mp_tc) - return -1; - - mp_tc = rte_mempool_create("test_mempool_same_name_twice_creation", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - NULL, NULL, - NULL, NULL, - SOCKET_ID_ANY, 0); - if (NULL != mp_tc) - return -1; + struct rte_mempool *mp_tc, *mp_tc2; + + mp_tc = rte_mempool_create("test_mempool_same_name", MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, 0, 0, + NULL, NULL, + NULL, NULL, + SOCKET_ID_ANY, 0); + + if (mp_tc == NULL) + RET_ERR(); + + mp_tc2 = rte_mempool_create("test_mempool_same_name", MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, 0, 0, + NULL, NULL, + NULL, NULL, + SOCKET_ID_ANY, 0); + + if (mp_tc2 != NULL) { + rte_mempool_free(mp_tc); + rte_mempool_free(mp_tc2); + RET_ERR(); + } + rte_mempool_free(mp_tc); return 0; } @@ -444,7 +491,7 @@ test_mempool_xmem_misc(void) usz = rte_mempool_xmem_usage(NULL, elt_num, total_size, 0, 1, MEMPOOL_PG_SHIFT_MAX); - if(sz != (size_t)usz) { + if (sz != (size_t)usz) { printf("failure @ %s: rte_mempool_xmem_usage(%u, %u) " "returns: %#zx, while expected: %#zx;\n", __func__, elt_num, total_size, sz, (size_t)usz); @@ -457,68 +504,109 @@ test_mempool_xmem_misc(void) static int test_mempool(void) { + struct rte_mempool *mp_cache = NULL; + struct rte_mempool *mp_nocache = NULL; + struct rte_mempool *mp_ext = NULL; + struct rte_mempool *mp_stack = NULL; + rte_atomic32_init(&synchro); /* create a mempool (without cache) */ - if (mp_nocache == NULL) - mp_nocache = rte_mempool_create("test_nocache", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, 0, 0, - NULL, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, 0); - if (mp_nocache == NULL) - return -1; + mp_nocache = rte_mempool_create("test_nocache", MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, 0, 0, + NULL, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, 0); + + if (mp_nocache == NULL) { + printf("cannot allocate mp_nocache mempool\n"); + goto err; + } /* create a mempool (with cache) */ - if (mp_cache == NULL) - mp_cache = rte_mempool_create("test_cache", MEMPOOL_SIZE, - MEMPOOL_ELT_SIZE, - RTE_MEMPOOL_CACHE_MAX_SIZE, 0, - NULL, NULL, - my_obj_init, NULL, - SOCKET_ID_ANY, 0); - if (mp_cache == NULL) - return -1; + mp_cache = rte_mempool_create("test_cache", MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, + RTE_MEMPOOL_CACHE_MAX_SIZE, 0, + NULL, NULL, + my_obj_init, NULL, + SOCKET_ID_ANY, 0); + + if (mp_cache == NULL) { + printf("cannot allocate mp_cache mempool\n"); + goto err; + } + /* create a mempool with an external handler */ + mp_stack = rte_mempool_create_empty("test_stack", + MEMPOOL_SIZE, + MEMPOOL_ELT_SIZE, + RTE_MEMPOOL_CACHE_MAX_SIZE, 0, + SOCKET_ID_ANY, 0); + + if (mp_stack == NULL) { + printf("cannot allocate mp_stack mempool\n"); + goto err; + } + if (rte_mempool_set_ops_byname(mp_stack, "stack", NULL) < 0) { + printf("cannot set stack handler\n"); + goto err; + } + if (rte_mempool_populate_default(mp_stack) < 0) { + printf("cannot populate mp_stack mempool\n"); + goto err; + } + rte_mempool_obj_iter(mp_stack, my_obj_init, NULL); /* retrieve the mempool from its name */ if (rte_mempool_lookup("test_nocache") != mp_nocache) { printf("Cannot lookup mempool from its name\n"); - return -1; + goto err; } rte_mempool_list_dump(stdout); /* basic tests without cache */ - mp = mp_nocache; - if (test_mempool_basic() < 0) - return -1; + if (test_mempool_basic(mp_nocache, 0) < 0) + goto err; /* basic tests with cache */ - mp = mp_cache; - if (test_mempool_basic() < 0) - return -1; + if (test_mempool_basic(mp_cache, 0) < 0) + goto err; + + /* basic tests with user-owned cache */ + if (test_mempool_basic(mp_nocache, 1) < 0) + goto err; /* more basic tests without cache */ if (test_mempool_basic_ex(mp_nocache) < 0) - return -1; + goto err; /* mempool operation test based on single producer and single comsumer */ if (test_mempool_sp_sc() < 0) - return -1; + goto err; if (test_mempool_creation_with_exceeded_cache_size() < 0) - return -1; + goto err; if (test_mempool_same_name_twice_creation() < 0) - return -1; + goto err; if (test_mempool_xmem_misc() < 0) - return -1; + goto err; + + /* test the stack handler */ + if (test_mempool_basic(mp_stack, 1) < 0) + goto err; rte_mempool_list_dump(stdout); return 0; + +err: + rte_mempool_free(mp_nocache); + rte_mempool_free(mp_cache); + rte_mempool_free(mp_ext); + return -1; } static struct test_command mempool_cmd = { diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c index cdc02a00..4fac04cd 100644 --- a/app/test/test_mempool_perf.c +++ b/app/test/test_mempool_perf.c @@ -78,6 +78,9 @@ * - One core without cache * - Two cores without cache * - Max. cores without cache + * - One core with user-owned cache + * - Two cores with user-owned cache + * - Max. cores with user-owned cache * * - Bulk size (*n_get_bulk*, *n_put_bulk*) * @@ -96,8 +99,21 @@ #define MAX_KEEP 128 #define MEMPOOL_SIZE ((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE))-1) +#define LOG_ERR() printf("test failed at %s():%d\n", __func__, __LINE__) +#define RET_ERR() do { \ + LOG_ERR(); \ + return -1; \ + } while (0) +#define GOTO_ERR(var, label) do { \ + LOG_ERR(); \ + var = -1; \ + goto label; \ + } while (0) + static struct rte_mempool *mp; static struct rte_mempool *mp_cache, *mp_nocache; +static int use_external_cache; +static unsigned external_cache_size = RTE_MEMPOOL_CACHE_MAX_SIZE; static rte_atomic32_t synchro; @@ -110,7 +126,7 @@ static unsigned n_keep; /* number of enqueues / dequeues */ struct mempool_test_stats { - unsigned enq_count; + uint64_t enq_count; } __rte_cache_aligned; static struct mempool_test_stats stats[RTE_MAX_LCORE]; @@ -134,15 +150,27 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg) void *obj_table[MAX_KEEP]; unsigned i, idx; unsigned lcore_id = rte_lcore_id(); - int ret; + int ret = 0; uint64_t start_cycles, end_cycles; uint64_t time_diff = 0, hz = rte_get_timer_hz(); + struct rte_mempool_cache *cache; + + if (use_external_cache) { + /* Create a user-owned mempool cache. */ + cache = rte_mempool_cache_create(external_cache_size, + SOCKET_ID_ANY); + if (cache == NULL) + RET_ERR(); + } else { + /* May be NULL if cache is disabled. */ + cache = rte_mempool_default_cache(mp, lcore_id); + } /* n_get_bulk and n_put_bulk must be divisors of n_keep */ if (((n_keep / n_get_bulk) * n_get_bulk) != n_keep) - return -1; + GOTO_ERR(ret, out); if (((n_keep / n_put_bulk) * n_put_bulk) != n_keep) - return -1; + GOTO_ERR(ret, out); stats[lcore_id].enq_count = 0; @@ -157,13 +185,14 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg) /* get n_keep objects by bulk of n_bulk */ idx = 0; while (idx < n_keep) { - ret = rte_mempool_get_bulk(mp, &obj_table[idx], - n_get_bulk); + ret = rte_mempool_generic_get(mp, + &obj_table[idx], + n_get_bulk, + cache, 0); if (unlikely(ret < 0)) { rte_mempool_dump(stdout, mp); - rte_ring_dump(stdout, mp->ring); /* in this case, objects are lost... */ - return -1; + GOTO_ERR(ret, out); } idx += n_get_bulk; } @@ -171,8 +200,9 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg) /* put the objects back */ idx = 0; while (idx < n_keep) { - rte_mempool_put_bulk(mp, &obj_table[idx], - n_put_bulk); + rte_mempool_generic_put(mp, &obj_table[idx], + n_put_bulk, + cache, 0); idx += n_put_bulk; } } @@ -181,7 +211,13 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg) stats[lcore_id].enq_count += N; } - return 0; +out: + if (use_external_cache) { + rte_mempool_cache_flush(cache, mp); + rte_mempool_cache_free(cache); + } + + return ret; } /* launch all the per-lcore test, and display the result */ @@ -189,7 +225,7 @@ static int launch_cores(unsigned cores) { unsigned lcore_id; - unsigned rate; + uint64_t rate; int ret; unsigned cores_save = cores; @@ -200,9 +236,11 @@ launch_cores(unsigned cores) printf("mempool_autotest cache=%u cores=%u n_get_bulk=%u " "n_put_bulk=%u n_keep=%u ", - (unsigned) mp->cache_size, cores, n_get_bulk, n_put_bulk, n_keep); + use_external_cache ? + external_cache_size : (unsigned) mp->cache_size, + cores, n_get_bulk, n_put_bulk, n_keep); - if (rte_mempool_count(mp) != MEMPOOL_SIZE) { + if (rte_mempool_avail_count(mp) != MEMPOOL_SIZE) { printf("mempool is not full\n"); return -1; } @@ -238,7 +276,7 @@ launch_cores(unsigned cores) for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) rate += (stats[lcore_id].enq_count / TIME_S); - printf("rate_persec=%u\n", rate); + printf("rate_persec=%" PRIu64 "\n", rate); return 0; } @@ -324,6 +362,20 @@ test_mempool_perf(void) if (do_one_mempool_test(rte_lcore_count()) < 0) return -1; + /* performance test with 1, 2 and max cores */ + printf("start performance test (with user-owned cache)\n"); + mp = mp_nocache; + use_external_cache = 1; + + if (do_one_mempool_test(1) < 0) + return -1; + + if (do_one_mempool_test(2) < 0) + return -1; + + if (do_one_mempool_test(rte_lcore_count()) < 0) + return -1; + rte_mempool_list_dump(stdout); return 0; diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c index 4dfe418e..f66b68f2 100644 --- a/app/test/test_mp_secondary.c +++ b/app/test/test_mp_secondary.c @@ -245,6 +245,7 @@ run_object_creation_tests(void) printf("# Checked rte_lpm_create() OK\n"); #endif +#ifdef RTE_APP_TEST_RESOURCE_TAR /* Run a test_pci call */ if (test_pci() != 0) { printf("PCI scan failed in secondary\n"); @@ -252,6 +253,7 @@ run_object_creation_tests(void) return -1; } else printf("PCI scan succeeded in secondary\n"); +#endif return 0; } @@ -266,9 +268,11 @@ test_mp_secondary(void) { if (rte_eal_process_type() == RTE_PROC_PRIMARY) { if (!test_pci_run) { +#ifdef RTE_APP_TEST_RESOURCE_TAR printf("=== Running pre-requisite test of test_pci\n"); test_pci(); printf("=== Requisite test done\n"); +#endif } return run_secondary_instances(); } diff --git a/app/test/test_pci.c b/app/test/test_pci.c index 0ed357e6..354a0ad9 100644 --- a/app/test/test_pci.c +++ b/app/test/test_pci.c @@ -43,6 +43,7 @@ #include <rte_devargs.h> #include "test.h" +#include "resource.h" /* Generic maximum number of drivers to have room to allocate all drivers */ #define NUM_MAX_DRIVERS 256 @@ -66,21 +67,14 @@ static int my_driver_init(struct rte_pci_driver *dr, /* IXGBE NICS */ struct rte_pci_id my_driver_id[] = { - -#define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) {RTE_PCI_DEVICE(vend, dev)}, -#include <rte_pci_dev_ids.h> - -{ .vendor_id = 0, /* sentinel */ }, + {RTE_PCI_DEVICE(0x0001, 0x1234)}, + { .vendor_id = 0, /* sentinel */ }, }; struct rte_pci_id my_driver_id2[] = { - -/* IGB & EM NICS */ -#define RTE_PCI_DEV_ID_DECL_EM(vend, dev) {RTE_PCI_DEVICE(vend, dev)}, -#define RTE_PCI_DEV_ID_DECL_IGB(vend, dev) {RTE_PCI_DEVICE(vend, dev)}, -#include <rte_pci_dev_ids.h> - -{ .vendor_id = 0, /* sentinel */ }, + {RTE_PCI_DEVICE(0x0001, 0x4444)}, + {RTE_PCI_DEVICE(0x0002, 0xabcd)}, + { .vendor_id = 0, /* sentinel */ }, }; struct rte_pci_driver my_driver = { @@ -144,23 +138,102 @@ static void free_devargs_list(void) } } -int -test_pci(void) +/* backup real devices & drivers (not used for testing) */ +struct pci_driver_list real_pci_driver_list = + TAILQ_HEAD_INITIALIZER(real_pci_driver_list); +struct pci_device_list real_pci_device_list = + TAILQ_HEAD_INITIALIZER(real_pci_device_list); + +REGISTER_LINKED_RESOURCE(test_pci_sysfs); + +static int +test_pci_setup(void) { - struct rte_devargs_list save_devargs_list; - struct rte_pci_driver *dr = NULL; - struct rte_pci_driver *save_pci_driver_list[NUM_MAX_DRIVERS]; - unsigned i, num_drivers = 0; + struct rte_pci_device *dev; + struct rte_pci_driver *dr; + const struct resource *r; + int ret; - printf("Dump all devices\n"); - rte_eal_pci_dump(stdout); + r = resource_find("test_pci_sysfs"); + TEST_ASSERT_NOT_NULL(r, "missing resource test_pci_sysfs"); + + ret = resource_untar(r); + TEST_ASSERT_SUCCESS(ret, "failed to untar %s", r->name); + + ret = setenv("SYSFS_PCI_DEVICES", "test_pci_sysfs/bus/pci/devices", 1); + TEST_ASSERT_SUCCESS(ret, "failed to setenv"); - /* Unregister all previous drivers */ - TAILQ_FOREACH(dr, &pci_driver_list, next) { + /* Unregister original devices & drivers lists */ + while (!TAILQ_EMPTY(&pci_driver_list)) { + dr = TAILQ_FIRST(&pci_driver_list); rte_eal_pci_unregister(dr); - save_pci_driver_list[num_drivers++] = dr; + TAILQ_INSERT_TAIL(&real_pci_driver_list, dr, next); } + while (!TAILQ_EMPTY(&pci_device_list)) { + dev = TAILQ_FIRST(&pci_device_list); + TAILQ_REMOVE(&pci_device_list, dev, next); + TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next); + } + + ret = rte_eal_pci_scan(); + TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus"); + rte_eal_pci_dump(stdout); + + return 0; +} + +static int +test_pci_cleanup(void) +{ + struct rte_pci_device *dev; + struct rte_pci_driver *dr; + const struct resource *r; + int ret; + + unsetenv("SYSFS_PCI_DEVICES"); + + r = resource_find("test_pci_sysfs"); + TEST_ASSERT_NOT_NULL(r, "missing resource test_pci_sysfs"); + + ret = resource_rm_by_tar(r); + TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name); + + /* + * FIXME: there is no API in DPDK to free a rte_pci_device so we + * cannot free the devices in the right way. Let's assume that we + * don't care for tests. + */ + while (!TAILQ_EMPTY(&pci_device_list)) { + dev = TAILQ_FIRST(&pci_device_list); + TAILQ_REMOVE(&pci_device_list, dev, next); + } + + /* Restore original devices & drivers lists */ + while (!TAILQ_EMPTY(&real_pci_driver_list)) { + dr = TAILQ_FIRST(&real_pci_driver_list); + TAILQ_REMOVE(&real_pci_driver_list, dr, next); + rte_eal_pci_register(dr); + } + + while (!TAILQ_EMPTY(&real_pci_device_list)) { + dev = TAILQ_FIRST(&real_pci_device_list); + TAILQ_REMOVE(&real_pci_device_list, dev, next); + TAILQ_INSERT_TAIL(&pci_device_list, dev, next); + } + + return 0; +} + +static int +test_pci_blacklist(void) +{ + struct rte_devargs_list save_devargs_list; + + printf("Dump all devices\n"); + TEST_ASSERT(TAILQ_EMPTY(&pci_driver_list), + "pci_driver_list not empty"); + rte_eal_pci_register(&my_driver); rte_eal_pci_register(&my_driver2); @@ -196,9 +269,48 @@ test_pci(void) rte_eal_pci_unregister(&my_driver); rte_eal_pci_unregister(&my_driver2); - /* Restore original driver list */ - for (i = 0; i < num_drivers; i++) - rte_eal_pci_register(save_pci_driver_list[i]); + return 0; +} + +static int test_pci_sysfs(void) +{ + const char *orig; + const char *newpath; + int ret; + + orig = pci_get_sysfs_path(); + ret = setenv("SYSFS_PCI_DEVICES", "My Documents", 1); + TEST_ASSERT_SUCCESS(ret, "Failed setenv to My Documents"); + + newpath = pci_get_sysfs_path(); + TEST_ASSERT(!strcmp(newpath, "My Documents"), + "pci_get_sysfs_path() should return 'My Documents' " + "but gives %s", newpath); + + ret = setenv("SYSFS_PCI_DEVICES", orig, 1); + TEST_ASSERT_SUCCESS(ret, "Failed setenv back to '%s'", orig); + + newpath = pci_get_sysfs_path(); + TEST_ASSERT(!strcmp(orig, newpath), + "pci_get_sysfs_path returned unexpected path: " + "%s (expected: %s)", newpath, orig); + return 0; +} + +int +test_pci(void) +{ + if (test_pci_sysfs()) + return -1; + + if (test_pci_setup()) + return -1; + + if (test_pci_blacklist()) + return -1; + + if (test_pci_cleanup()) + return -1; return 0; } diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class new file mode 100644 index 00000000..2f9c1dad --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/class @@ -0,0 +1 @@ +0x020000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config Binary files differnew file mode 100644 index 00000000..7752421c --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/config diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits new file mode 100644 index 00000000..900731ff --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/consistent_dma_mask_bits @@ -0,0 +1 @@ +64 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device new file mode 100644 index 00000000..48a62909 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/device @@ -0,0 +1 @@ +0x1234 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits new file mode 100644 index 00000000..900731ff --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/dma_mask_bits @@ -0,0 +1 @@ +64 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/enable @@ -0,0 +1 @@ +1 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/irq @@ -0,0 +1 @@ +0 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias new file mode 100644 index 00000000..f4c76ed9 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/modalias @@ -0,0 +1 @@ +pci:v00008086d000010FBsv00008086sd00000003bc02sc00i00 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/msi_bus @@ -0,0 +1 @@ +1 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node new file mode 100644 index 00000000..3a2e3f49 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/numa_node @@ -0,0 +1 @@ +-1 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource new file mode 100644 index 00000000..f3889296 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/resource @@ -0,0 +1,13 @@ +0x00000000d0080000 0x00000000d00fffff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x000000000000e020 0x000000000000e03f 0x0000000000040101 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000d0104000 0x00000000d0107fff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab000000 0x00000000ab0fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab100000 0x00000000ab1fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_numvfs @@ -0,0 +1 @@ +0 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs new file mode 100644 index 00000000..4b9026d8 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/sriov_totalvfs @@ -0,0 +1 @@ +63 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device new file mode 100644 index 00000000..89a932cc --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_device @@ -0,0 +1 @@ +0x0003 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor new file mode 100644 index 00000000..446afb4b --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/subsystem_vendor @@ -0,0 +1 @@ +0x0001 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent new file mode 100644 index 00000000..1dbe34de --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/uevent @@ -0,0 +1,6 @@ +DRIVER=ixgbe +PCI_CLASS=20000 +PCI_ID=8086:10FB +PCI_SUBSYS_ID=8086:0003 +PCI_SLOT_NAME=0000:01:00.0 +MODALIAS=pci:v00008086d000010FBsv00008086sd00000003bc02sc00i00 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor new file mode 100644 index 00000000..446afb4b --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:00.0/vendor @@ -0,0 +1 @@ +0x0001 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class new file mode 100644 index 00000000..22dd9361 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/class @@ -0,0 +1 @@ +0x100000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device new file mode 100644 index 00000000..f61bbe63 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/device @@ -0,0 +1 @@ +0xabcd diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource new file mode 100644 index 00000000..f3889296 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/resource @@ -0,0 +1,13 @@ +0x00000000d0080000 0x00000000d00fffff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x000000000000e020 0x000000000000e03f 0x0000000000040101 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000d0104000 0x00000000d0107fff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab000000 0x00000000ab0fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab100000 0x00000000ab1fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device new file mode 100644 index 00000000..f61bbe63 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_device @@ -0,0 +1 @@ +0xabcd diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor new file mode 100644 index 00000000..4321b81f --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/subsystem_vendor @@ -0,0 +1 @@ +0x0002 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor new file mode 100644 index 00000000..4321b81f --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:01:02.0/vendor @@ -0,0 +1 @@ +0x0002 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class new file mode 100644 index 00000000..22dd9361 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/class @@ -0,0 +1 @@ +0x100000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device new file mode 100644 index 00000000..ccaa4982 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/device @@ -0,0 +1 @@ +0x4444 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource new file mode 100644 index 00000000..f3889296 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/resource @@ -0,0 +1,13 @@ +0x00000000d0080000 0x00000000d00fffff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x000000000000e020 0x000000000000e03f 0x0000000000040101 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000d0104000 0x00000000d0107fff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab000000 0x00000000ab0fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x00000000ab100000 0x00000000ab1fffff 0x0000000000140204 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device new file mode 100644 index 00000000..ccaa4982 --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_device @@ -0,0 +1 @@ +0x4444 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor new file mode 100644 index 00000000..446afb4b --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/subsystem_vendor @@ -0,0 +1 @@ +0x0001 diff --git a/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor new file mode 100644 index 00000000..446afb4b --- /dev/null +++ b/app/test/test_pci_sysfs/bus/pci/devices/0000:02:ab.0/vendor @@ -0,0 +1 @@ +0x0001 diff --git a/app/test/test_per_lcore.c b/app/test/test_per_lcore.c index b16449a9..f452cdb0 100644 --- a/app/test/test_per_lcore.c +++ b/app/test/test_per_lcore.c @@ -92,8 +92,8 @@ display_vars(__attribute__((unused)) void *arg) static int test_per_lcore_delay(__attribute__((unused)) void *arg) { - rte_delay_ms(5000); - printf("wait 5000ms on lcore %u\n", rte_lcore_id()); + rte_delay_ms(100); + printf("wait 100ms on lcore %u\n", rte_lcore_id()); return 0; } diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c index 59803f7c..3d56cd29 100644 --- a/app/test/test_pmd_perf.c +++ b/app/test/test_pmd_perf.c @@ -709,9 +709,6 @@ test_pmd_perf(void) return -1; } - if (nb_ports > RTE_MAX_ETHPORTS) - nb_ports = RTE_MAX_ETHPORTS; - nb_lcores = rte_lcore_count(); memset(lcore_conf, 0, sizeof(lcore_conf)); diff --git a/app/test/test_red.c b/app/test/test_red.c index 81c9d679..2384c556 100644 --- a/app/test/test_red.c +++ b/app/test/test_red.c @@ -57,6 +57,7 @@ #define MSEC_PER_SEC 1000 /**< Milli-seconds per second */ #define USEC_PER_MSEC 1000 /**< Micro-seconds per milli-second */ #define USEC_PER_SEC 1000000 /**< Micro-seconds per second */ +#define NSEC_PER_SEC (USEC_PER_SEC * 1000) /**< Nano-seconds per second */ /**< structures for testing rte_red performance and function */ struct test_rte_red_config { /**< Test structure for RTE_RED config */ @@ -280,12 +281,15 @@ static uint64_t get_machclk_freq(void) uint64_t start = 0; uint64_t end = 0; uint64_t diff = 0; - uint64_t clk_freq_hz = 0; + static uint64_t clk_freq_hz; struct timespec tv_start = {0, 0}, tv_end = {0, 0}; struct timespec req = {0, 0}; - req.tv_sec = 1; - req.tv_nsec = 0; + if (clk_freq_hz != 0) + return clk_freq_hz; + + req.tv_sec = 0; + req.tv_nsec = NSEC_PER_SEC / 4; clock_gettime(CLOCK_REALTIME, &tv_start); start = rte_rdtsc(); @@ -435,8 +439,8 @@ static struct test_queue ft_tqueue = { }; static struct test_var ft_tvar = { - .wait_usec = 250000, - .num_iterations = 20, + .wait_usec = 10000, + .num_iterations = 5, .num_ops = 10000, .clk_freq = 0, .dropped = ft_dropped, @@ -1747,6 +1751,16 @@ struct tests func_tests[] = { { &ovfl_test1_config, ovfl_test1 }, }; +struct tests func_tests_quick[] = { + { &func_test1_config, func_test1 }, + { &func_test2_config, func_test2 }, + { &func_test3_config, func_test3 }, + /* no test 4 as it takes a lot of time */ + { &func_test5_config, func_test5 }, + { &func_test6_config, func_test6 }, + { &ovfl_test1_config, ovfl_test1 }, +}; + struct tests perf_tests[] = { { &perf1_test1_config, perf1_test }, { &perf1_test2_config, perf1_test }, @@ -1850,27 +1864,60 @@ test_invalid_parameters(void) return 0; } +static void +show_stats(const uint32_t num_tests, const uint32_t num_pass) +{ + if (num_pass == num_tests) + printf("[total: %u, pass: %u]\n", num_tests, num_pass); + else + printf("[total: %u, pass: %u, fail: %u]\n", num_tests, num_pass, + num_tests - num_pass); +} + +static int +tell_the_result(const uint32_t num_tests, const uint32_t num_pass) +{ + return (num_pass == num_tests) ? 0 : 1; +} + static int test_red(void) { uint32_t num_tests = 0; uint32_t num_pass = 0; - int ret = 0; if (test_invalid_parameters() < 0) return -1; + run_tests(func_tests_quick, RTE_DIM(func_tests_quick), + &num_tests, &num_pass); + show_stats(num_tests, num_pass); + return tell_the_result(num_tests, num_pass); +} + +static int +test_red_perf(void) +{ + uint32_t num_tests = 0; + uint32_t num_pass = 0; - run_tests(func_tests, RTE_DIM(func_tests), &num_tests, &num_pass); run_tests(perf_tests, RTE_DIM(perf_tests), &num_tests, &num_pass); + show_stats(num_tests, num_pass); + return tell_the_result(num_tests, num_pass); +} - if (num_pass == num_tests) { - printf("[total: %u, pass: %u]\n", num_tests, num_pass); - ret = 0; - } else { - printf("[total: %u, pass: %u, fail: %u]\n", num_tests, num_pass, num_tests - num_pass); - ret = -1; - } - return ret; +static int +test_red_all(void) +{ + uint32_t num_tests = 0; + uint32_t num_pass = 0; + + if (test_invalid_parameters() < 0) + return -1; + + run_tests(func_tests, RTE_DIM(func_tests), &num_tests, &num_pass); + run_tests(perf_tests, RTE_DIM(perf_tests), &num_tests, &num_pass); + show_stats(num_tests, num_pass); + return tell_the_result(num_tests, num_pass); } static struct test_command red_cmd = { @@ -1878,3 +1925,15 @@ static struct test_command red_cmd = { .callback = test_red, }; REGISTER_TEST_COMMAND(red_cmd); + +static struct test_command red_cmd_perf = { + .command = "red_perf", + .callback = test_red_perf, +}; +REGISTER_TEST_COMMAND(red_cmd_perf); + +static struct test_command red_cmd_all = { + .command = "red_all", + .callback = test_red_all, +}; +REGISTER_TEST_COMMAND(red_cmd_all); diff --git a/app/test/test_resource.c b/app/test/test_resource.c new file mode 100644 index 00000000..39a64689 --- /dev/null +++ b/app/test/test_resource.c @@ -0,0 +1,137 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 RehiveTech. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of RehiveTech nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> + +#include "test.h" +#include "resource.h" + +const char test_resource_dpdk_blob[] = { + '\x44', '\x50', '\x44', '\x4b', '\x00' +}; + +REGISTER_RESOURCE(test_resource_dpdk, + test_resource_dpdk_blob, test_resource_dpdk_blob + 4); + +static int test_resource_dpdk(void) +{ + const struct resource *r; + + r = resource_find("test_resource_dpdk"); + TEST_ASSERT_NOT_NULL(r, "Could not find test_resource_dpdk"); + TEST_ASSERT(!strcmp(r->name, "test_resource_dpdk"), + "Found resource %s, expected test_resource_dpdk", + r->name); + + TEST_ASSERT(!strncmp("DPDK", r->begin, 4), + "Unexpected payload: %.4s...", r->begin); + + return 0; +} + +REGISTER_LINKED_RESOURCE(test_resource_c); + +static int test_resource_c(void) +{ + const struct resource *r; + FILE *f; + + r = resource_find("test_resource_c"); + TEST_ASSERT_NOT_NULL(r, "No test_resource_c found"); + TEST_ASSERT(!strcmp(r->name, "test_resource_c"), + "Found resource %s, expected test_resource_c", + r->name); + + TEST_ASSERT_SUCCESS(resource_fwrite_file(r, "test_resource.c"), + "Failed to to write file %s", r->name); + + f = fopen("test_resource.c", "r"); + TEST_ASSERT_NOT_NULL(f, + "Missing extracted file resource.c"); + fclose(f); + remove("test_resource.c"); + + return 0; +} + +#ifdef RTE_APP_TEST_RESOURCE_TAR +REGISTER_LINKED_RESOURCE(test_resource_tar); + +static int test_resource_tar(void) +{ + const struct resource *r; + FILE *f; + + r = resource_find("test_resource_tar"); + TEST_ASSERT_NOT_NULL(r, "No test_resource_tar found"); + TEST_ASSERT(!strcmp(r->name, "test_resource_tar"), + "Found resource %s, expected test_resource_tar", + r->name); + + TEST_ASSERT_SUCCESS(resource_untar(r), + "Failed to to untar %s", r->name); + + f = fopen("test_resource.c", "r"); + TEST_ASSERT_NOT_NULL(f, + "Missing extracted file test_resource.c"); + fclose(f); + + TEST_ASSERT_SUCCESS(resource_rm_by_tar(r), + "Failed to remove extracted contents of %s", r->name); + return 0; +} + +#endif /* RTE_APP_TEST_RESOURCE_TAR */ + +static int test_resource(void) +{ + if (test_resource_dpdk()) + return -1; + + if (test_resource_c()) + return -1; + +#ifdef RTE_APP_TEST_RESOURCE_TAR + if (test_resource_tar()) + return -1; +#endif /* RTE_APP_TEST_RESOURCE_TAR */ + + return 0; +} + +static struct test_command resource_cmd = { + .command = "resource_autotest", + .callback = test_resource, +}; +REGISTER_TEST_COMMAND(resource_cmd); diff --git a/app/test/test_ring.c b/app/test/test_ring.c index 0d7523ed..9095e597 100644 --- a/app/test/test_ring.c +++ b/app/test/test_ring.c @@ -100,8 +100,6 @@ #define RING_SIZE 4096 #define MAX_BULK 32 -#define N 65536 -#define TIME_S 5 static rte_atomic32_t synchro; @@ -130,7 +128,7 @@ check_live_watermark_change(__attribute__((unused)) void *dummy) /* init the object table */ memset(obj_table, 0, sizeof(obj_table)); - end_time = rte_get_timer_cycles() + (hz * 2); + end_time = rte_get_timer_cycles() + (hz / 4); /* check that bulk and watermark are 4 and 32 (respectively) */ while (diff >= 0) { @@ -194,9 +192,9 @@ test_live_watermark_change(void) * watermark and quota */ rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2); - rte_delay_ms(1000); + rte_delay_ms(100); rte_ring_set_water_mark(r, 32); - rte_delay_ms(1000); + rte_delay_ms(100); if (rte_eal_wait_lcore(lcore_id2) < 0) return -1; diff --git a/app/test/test_spinlock.c b/app/test/test_spinlock.c index 16ced7fb..180d6deb 100644 --- a/app/test/test_spinlock.c +++ b/app/test/test_spinlock.c @@ -129,7 +129,7 @@ test_spinlock_recursive_per_core(__attribute__((unused)) void *arg) static rte_spinlock_t lk = RTE_SPINLOCK_INITIALIZER; static uint64_t lock_count[RTE_MAX_LCORE] = {0}; -#define TIME_S 5 +#define TIME_MS 100 static int load_loop_fn(void *func_param) @@ -145,7 +145,7 @@ load_loop_fn(void *func_param) while (rte_atomic32_read(&synchro) == 0); begin = rte_get_timer_cycles(); - while (time_diff / hz < TIME_S) { + while (time_diff < hz * TIME_MS / 1000) { if (use_lock) rte_spinlock_lock(&lk); lcount++; @@ -258,7 +258,7 @@ test_spinlock(void) RTE_LCORE_FOREACH_SLAVE(i) { rte_spinlock_unlock(&sl_tab[i]); - rte_delay_ms(100); + rte_delay_ms(10); } rte_eal_mp_wait_lcore(); diff --git a/app/test/test_timer.c b/app/test/test_timer.c index 944e2adc..bc07925e 100644 --- a/app/test/test_timer.c +++ b/app/test/test_timer.c @@ -137,7 +137,7 @@ #include <rte_random.h> #include <rte_malloc.h> -#define TEST_DURATION_S 20 /* in seconds */ +#define TEST_DURATION_S 1 /* in seconds */ #define NB_TIMER 4 #define RTE_LOGTYPE_TESTTIMER RTE_LOGTYPE_USER3 @@ -305,7 +305,7 @@ timer_stress2_main_loop(__attribute__((unused)) void *arg) { static struct rte_timer *timers; int i, ret; - uint64_t delay = rte_get_timer_hz() / 4; + uint64_t delay = rte_get_timer_hz() / 20; unsigned lcore_id = rte_lcore_id(); unsigned master = rte_get_master_lcore(); int32_t my_collisions = 0; @@ -346,7 +346,7 @@ timer_stress2_main_loop(__attribute__((unused)) void *arg) rte_atomic32_add(&collisions, my_collisions); /* wait long enough for timers to expire */ - rte_delay_ms(500); + rte_delay_ms(100); /* all cores rendezvous */ if (lcore_id == master) { @@ -396,7 +396,7 @@ timer_stress2_main_loop(__attribute__((unused)) void *arg) } /* wait long enough for timers to expire */ - rte_delay_ms(500); + rte_delay_ms(100); /* now check that we get the right number of callbacks */ if (lcore_id == master) { @@ -495,13 +495,13 @@ timer_basic_main_loop(__attribute__((unused)) void *arg) /* launch all timers on core 0 */ if (lcore_id == rte_get_master_lcore()) { - mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, + mytimer_reset(&mytiminfo[0], hz/4, SINGLE, lcore_id, timer_basic_cb); - mytimer_reset(&mytiminfo[1], hz*2, SINGLE, lcore_id, + mytimer_reset(&mytiminfo[1], hz/2, SINGLE, lcore_id, timer_basic_cb); - mytimer_reset(&mytiminfo[2], hz, PERIODICAL, lcore_id, + mytimer_reset(&mytiminfo[2], hz/4, PERIODICAL, lcore_id, timer_basic_cb); - mytimer_reset(&mytiminfo[3], hz, PERIODICAL, + mytimer_reset(&mytiminfo[3], hz/4, PERIODICAL, rte_get_next_lcore(lcore_id, 0, 1), timer_basic_cb); } @@ -591,7 +591,7 @@ test_timer(void) end_time = cur_time + (hz * TEST_DURATION_S); /* start other cores */ - printf("Start timer stress tests (%d seconds)\n", TEST_DURATION_S); + printf("Start timer stress tests\n"); rte_eal_mp_remote_launch(timer_stress_main_loop, NULL, CALL_MASTER); rte_eal_mp_wait_lcore(); @@ -612,7 +612,7 @@ test_timer(void) end_time = cur_time + (hz * TEST_DURATION_S); /* start other cores */ - printf("\nStart timer basic tests (%d seconds)\n", TEST_DURATION_S); + printf("\nStart timer basic tests\n"); rte_eal_mp_remote_launch(timer_basic_main_loop, NULL, CALL_MASTER); rte_eal_mp_wait_lcore(); |